?? running.cpp
字號:
#include <windows.h>
#include <gl/Gl.h>
#include <gl/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "define.h"
#include "running.h"
RUNNING::RUNNING(void)
{
int i;
bool b;
float aspect = (float) WIDTH/HEIGHT;
FORWARD = BACKWARD = false;
//ball
B.NumOfBall = 20;
B.bX = new int[B.NumOfBall];
B.bZ = new int[B.NumOfBall];
B.IsHited = new bool[B.NumOfBall];
B.bR = 1.0f;
//Ramdom to find all Position
i = 0;
while ( i < B.NumOfBall )
{
b = true;
B.bX[i] = -G.GetWorldWidth() / 2 + ( abs(rand()) % (G.GetWorldWidth() - 5)) + 5;
B.bZ[i] = -G.GetWorldLength() / 2 + ( abs(rand()) % (G.GetWorldLength() - 5)) + 5;
B.IsHited[i] = false;
for ( int j = 0 ; j < T.NumOfTree && b ; j++ )
if ( abs(B.bX[i] - T.x[j]) < 2 || abs(B.bZ[i] - T.z[j]) < 2 ) b = false;
for ( int j = 0 ; ( j < i ) && b ; j++ )
if ( abs(B.bX[i] - B.bX[j]) < 2 || abs(B.bZ[i] - B.bZ[j]) < 2 ) b = false;
if (b) i++;
}
//The View MODE
MODE = MODE1;
//OPEN GL
GLfloat fNoLight[] = { 0.0f, 0.0f, 0.0f, 1.0f};
GLfloat fAmbientLight[] = {0.25f , 0.25f , 0.25f , 1.0f};
GLfloat fDiffuseLight[] = {0.775f , 0.775f , 0.775f , 1.0f};
GLfloat fSpecularLight[] = {1.0f , 1.0f , 1.0f , 1.0f};
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
glMaterialfv(GL_FRONT,GL_SPECULAR,fSpecularLight);
glMateriali(GL_FRONT,GL_SHININESS,128);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, fNoLight);
glLightfv(GL_LIGHT0, GL_AMBIENT, fAmbientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, fDiffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, fSpecularLight);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
//Sphere
SphereObj = gluNewQuadric();
gluQuadricDrawStyle(SphereObj,GLU_FILL);
gluQuadricOrientation(SphereObj,GLU_OUTSIDE);
//the light
lRot = 0.0f;
//cut the back face
glFrontFace(GL_CW);
glEnable(GL_CULL_FACE);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(15.0, aspect, 10.0, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
RUNNING::~RUNNING(void)
{
if ( B.bX ) delete [] B.bX;
if ( B.bZ ) delete [] B.bZ;
if ( B.IsHited ) delete [] B.IsHited;
if ( SphereObj ) gluDeleteQuadric(SphereObj);
}
void RUNNING::KeyBoard(K_EVENT kEvent)
{
if ( kEvent.Key == '1' && kEvent.STATE == ::K_EVENT.KEY )
MODE = MODE1;
else if ( kEvent.Key == '2' && kEvent.STATE == ::K_EVENT.KEY )
MODE = MODE2;
else if ( kEvent.Key == GLUT_KEY_LEFT && kEvent.STATE == ::K_EVENT.SPECIAL ) {
xTran += 10.0f;
Display();
} else if ( kEvent.Key == GLUT_KEY_RIGHT && kEvent.STATE == ::K_EVENT.SPECIAL ) {
xTran -= 10.0f;
Display();
} else if ( kEvent.Key == GLUT_KEY_UP && kEvent.STATE == ::K_EVENT.SPECIAL ) {
zTran += 10.0f;
Display();
} else if ( kEvent.Key == GLUT_KEY_DOWN && kEvent.STATE == ::K_EVENT.SPECIAL ) {
zTran -= 10.0f;
Display();
}
}
void RUNNING::Mouse(M_EVENT mEvent)
{
if ( mEvent.MouseButton == GLUT_LEFT_BUTTON && mEvent.MouseState == GLUT_DOWN && mEvent.STATE == ::M_EVENT.MOUSE ) {
FORWARD = true;
BACKWARD = false;
} else if ( mEvent.MouseButton == GLUT_LEFT_BUTTON && mEvent.MouseState == GLUT_UP && mEvent.STATE == ::M_EVENT.MOUSE ) {
FORWARD = false;
BACKWARD = false;
} else if ( mEvent.MouseButton == GLUT_RIGHT_BUTTON && mEvent.MouseState == GLUT_DOWN && mEvent.STATE == ::M_EVENT.MOUSE ) {
FORWARD = false;
BACKWARD = true;
} else if ( mEvent.MouseButton == GLUT_RIGHT_BUTTON && mEvent.MouseState == GLUT_UP && mEvent.STATE == ::M_EVENT.MOUSE ) {
FORWARD = false;
BACKWARD = false;
}
if ( ( FORWARD || BACKWARD ) && (beforeMEvent.MouseX != mEvent.MouseX ) ) {
GLTMatrix M1,M2,PM;
GLfloat tF[3];
float Rot = (beforeMEvent.MouseX - mEvent.MouseX);
Rot = (float)((const int) Rot % 360);
float d = sqrt(C.vUp[1] * C.vUp[1] + C.vUp[2] * C.vUp[2]);
float _x = acos(C.vUp[2] / d);
float _y = acos(d);
if ( BACKWARD ) Rot *= -1.0f;
gltRotationMatrix(_x,1.0f,0.0f,0.0f,M1);
gltRotationMatrix(_y,0.0f,1.0f,0.0f,M2);
gltMultiplyMatrix(M1,M2,PM);
gltRotationMatrix(gltDegToRad(Rot),0.0f,0.0f,1.0f,M1);
gltMultiplyMatrix(PM,M1,M2);
gltRotationMatrix(-_y,0.0f,1.0f,0.0f,M1);
gltMultiplyMatrix(M2,M1,PM);
gltRotationMatrix(-_x,1.0f,0.0f,0.0f,M1);
gltMultiplyMatrix(PM,M1,M2); // the final rotation is in the M2
tF[0] = M2[0] * C.vForward[0] + M2[1] * C.vForward[1] + M2[2] * C.vForward[2];
tF[1] = M2[4] * C.vForward[0] + M2[5] * C.vForward[1] + M2[6] * C.vForward[2];
tF[2] = M2[8] * C.vForward[0] + M2[9] * C.vForward[1] + M2[10] * C.vForward[2];
C.vForward[0] = tF[0];
C.vForward[1] = tF[1];
C.vForward[2] = tF[2];
}
if ( beforeMEvent.MouseButton == GLUT_MIDDLE_BUTTON && beforeMEvent.MouseState == GLUT_DOWN && mEvent.STATE == ::M_EVENT.MOTION ) {
if ( beforeMEvent.MouseY != mEvent.MouseY || beforeMEvent.MouseX != mEvent.MouseX ) {
yTran -= (beforeMEvent.MouseY - mEvent.MouseY) / 5.0f;
zTran -= (beforeMEvent.MouseY - mEvent.MouseY) / 1.0f;
beforeMEvent = mEvent;
beforeMEvent.MouseButton = GLUT_MIDDLE_BUTTON;
beforeMEvent.MouseState = GLUT_DOWN;
Display();
}
} else beforeMEvent = mEvent;
}
void RUNNING::GameTimer(int n)
{
float fLength;
float CarMaxSize = abs(( C.CAR.GetMaxWidthVertex() - C.CAR.GetMinWidthVertex() )) > abs(( C.CAR.GetMaxLengthVertex() - C.CAR.GetMinLengthVertex() ))
? abs(( C.CAR.GetMaxWidthVertex() - C.CAR.GetMinWidthVertex() )) : abs(( C.CAR.GetMaxLengthVertex() - C.CAR.GetMinLengthVertex() ));
//the Sun
lRot += 1.0f;
if ( lRot > 360.0f ) lRot = 0.0f;
//the Car
if ( FORWARD && C.Speed <= 6.0f ) C.Speed += 0.1;
if ( BACKWARD && C.Speed >= -2.0f ) C.Speed -= 0.25;
if ( C.Speed > 0 ) C.Speed -= 0.05;
if ( C.Speed < 0 ) C.Speed += 0.05;
C.vLocation[0] -= C.Speed * C.vForward[0];
C.vLocation[2] -= C.Speed * C.vForward[2];
if ( C.vLocation[0] < -G.GetWorldWidth() / 2 + CarMaxSize - 1) { C.vLocation[0] = -G.GetWorldWidth() / 2 + CarMaxSize - 1; C.Speed = - C.Speed / 2.0f; }
if ( C.vLocation[2] < -G.GetWorldLength() / 2 + CarMaxSize - 1) { C.vLocation[2] = -G.GetWorldLength() / 2 + CarMaxSize - 1; C.Speed = - C.Speed / 2.0f; }
if ( C.vLocation[0] > G.GetWorldWidth() / 2 - CarMaxSize ) { C.vLocation[0] = G.GetWorldWidth() / 2 - CarMaxSize; C.Speed = - C.Speed / 2.0f; }
if ( C.vLocation[2] > G.GetWorldLength() / 2 - CarMaxSize ) { C.vLocation[2] = G.GetWorldLength() / 2 - CarMaxSize; C.Speed = - C.Speed / 2.0f; }
C.vLocation[1] = G.GetPositionHeight(C.vLocation[0],C.vLocation[2]) + abs(C.CAR.GetMinHeightVertex());
if ( abs(C.Speed) < 0.01 ) C.Speed = 0;
//the Normal
GLfloat vP1[3],vP2[3],vP3[3],vN[3],vX[3];
vP1[0] = C.vLocation[0];
vP1[2] = C.vLocation[2];
vP1[1] = G.GetPositionHeight(vP1[0],vP1[2]);
vP2[0] = C.vLocation[0] + 1;
vP2[2] = C.vLocation[2] ;
vP2[1] = G.GetPositionHeight(vP2[0],vP2[2]);
vP3[0] = C.vLocation[0] ;
vP3[2] = C.vLocation[2] + 1;
vP3[1] = G.GetPositionHeight(vP3[0],vP3[2]);
//Get the New Normal
G.GetNormalVector(vP2,vP1,vP3,vN);
//Find vX = vForward x vUp
vX[0] = C.vUp[1] * C.vForward[2] - C.vForward[1] * C.vUp[2];
vX[1] = -C.vUp[0] * C.vForward[2] + C.vForward[0] * C.vUp[2];
vX[2] = C.vUp[0] * C.vForward[1] - C.vForward[0] * C.vUp[1];
//Normalize vX
fLength = 1.0f / sqrt(vX[0] * vX[0] + vX[1] * vX[1] + vX[2] * vX[2]);
vX[0] *= fLength;
vX[1] *= fLength;
vX[2] *= fLength;
//New vForward = vX x New Normal
C.vForward[0] = vX[1] * vN[2] - vN[1] * vX[2];
C.vForward[1] = -vX[0] * vN[2] + vN[0] * vX[2];
C.vForward[2] = vX[0] * vN[1] - vN[0] * vX[1];
//Normailize
fLength = 1.0f / sqrt(C.vForward[0] * C.vForward[0] + C.vForward[1] * C.vForward[1] + C.vForward[2] * C.vForward[2]);
C.vForward[0] *= fLength;
C.vForward[1] *= fLength;
C.vForward[2] *= fLength;
//Update New Normal
C.vUp[0] = vN[0];
C.vUp[1] = vN[1];
C.vUp[2] = vN[2];
Display();
}
void RUNNING::Display()
{
double PI = 3.14159265358979323846;
double C_ = PI / 180.0f;
double MAX;
float ColorRate;
MAX = G.GetWorldWidth() > G.GetWorldLength() ? G.GetWorldWidth() : G.GetWorldLength();
MAX = MAX > G.GetWorldHeight() ? MAX : G.GetWorldHeight();
MAX = MAX;
GLfloat fLightPos0[4];
GLfloat CarMatrix[16];
GLfloat fSpecularLight[4];
ColorRate = 1 - abs(lRot - 180.0f) / 180.0f;
fLightPos0[0] = -cos(C_ * lRot + PI / 2.0f);
fLightPos0[1] = -sin(C_ * lRot + PI / 2.0f);
fLightPos0[2] = 0;
fLightPos0[3] = 0;
fSpecularLight[0] = ColorRate;
fSpecularLight[1] = ColorRate;
fSpecularLight[2] = ColorRate;
fSpecularLight[3] = 1;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if ( MODE == MODE1 )
gluLookAt( C.vLocation[0] + C.vLocation[1] * tan( C_ * 45 ) , 20 + C.vLocation[1] , 60 + C.vLocation[2] + C.vLocation[1] * tan( C_ * 60 ) , C.vLocation[0] , C.vLocation[1] , C.vLocation[2] , 0, 1, 0);
else {
gluLookAt( C.vLocation[0] + 8 * C.vForward[0] , C.vLocation[1] + 8 * C.vForward[1] , C.vLocation[2] + 8 * C.vForward[2] , C.vLocation[0] , C.vLocation[1] , C.vLocation[2] , C.vUp[0] , C.vUp[1] , C.vUp[2] );
glTranslatef(0.0f, -2.0f , 0.0f);
}
glLightfv(GL_LIGHT0, GL_POSITION, fLightPos0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, fSpecularLight);
glPushMatrix();
glTranslatef(xTran, 0.0f , 0.0f);
glTranslatef(0.0f, yTran , 0.0f);
glTranslatef(0.0f, 0.0f , zTran);
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
glDisable(GL_LIGHTING);
//Draw the SUN
glPushMatrix();
glTranslatef( MAX / 1.2f * cos(C_ * lRot - PI / 2.0f) , MAX / 1.2f * sin(C_ * lRot - PI / 2.0f) , 0.0f);
glColor3f(1.0, 1.0, 0.0);
gluSphere(SphereObj,2,30,10);
glPopMatrix();
//Draw the SKY
glPushMatrix();
glTranslatef(0.0, -MAX / 3.0f ,0.0);
glColor3f( ColorRate , ColorRate , ColorRate );
glFrontFace(GL_CCW);
glRotatef(180,1,0,0);
S.Draw();
glFrontFace(GL_CW);
glPopMatrix();
glEnable(GL_LIGHTING);
//Draw the Tree & Ground
glCallList(FieldList);
//Draw the Ball
for(int i = 0 ; i < B.NumOfBall ; i++) {
glPushMatrix();
glTranslatef(B.bX[i] , G.GetPositionHeight(B.bX[i] , B.bZ[i]) + B.bR + 0.1f , B.bZ[i]);
glRotatef(T.Rot[i], 0.0f, 1.0f, 0.0f);
glColor3f(1.0,0.0,0.0);
gluSphere(SphereObj,B.bR,30,10);
glPopMatrix();
}
// Draw the Car
glColor3f(1.0,1.0,1.0);
GetMatrix(&C,CarMatrix);
glMultMatrixf(CarMatrix);
if ( MODE == MODE1 ) {
glRotatef(-90, 1.0f, 0.0f, 0.0f);
C.CAR.Draw();
}
glPopMatrix();
glutSwapBuffers();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -