效果图如上:
步骤:略。
实现代码如下:
1、main.cpp
1 /********************************************************************** 2 3 Camera with OpenGL 4 5 June, 11th, 2000 6 7 This tutorial was written by Philipp Crocoll 8 Contact: 9 philipp.crocoll@web.de 10 www.codecolony.de 11 12 Every comment would be appreciated. 13 14 If you want to use parts of any code of mine: 15 let me know and 16 use it! 17 18 ********************************************************************** 19 ESC: exit 20 21 CAMERA movement: 22 w : forwards 23 s : backwards 24 a : turn left 25 d : turn right 26 x : turn up 27 y : turn down 28 v : strafe right 29 c : strafe left 30 r : move up 31 f : move down 32 33 ***********************************************************************/ 34 35 #include <GL\glut.h> 36 #include <windows.h> 37 #include "camera.h" 38 39 40 CCamera Camera; 41 42 43 void DrawNet(GLfloat size, GLint LinesX, GLint LinesZ) 44 { 45 glBegin(GL_LINES); 46 for (int xc = 0; xc < LinesX; xc++) 47 { 48 glVertex3f( -size / 2.0 + xc / (GLfloat)(LinesX-1)*size, 49 0.0, 50 size / 2.0); 51 glVertex3f( -size / 2.0 + xc / (GLfloat)(LinesX-1)*size, 52 0.0, 53 size / -2.0); 54 } 55 for (int zc = 0; zc < LinesX; zc++) 56 { 57 glVertex3f( size / 2.0, 58 0.0, 59 -size / 2.0 + zc / (GLfloat)(LinesZ-1)*size); 60 glVertex3f( size / -2.0, 61 0.0, 62 -size / 2.0 + zc / (GLfloat)(LinesZ-1)*size); 63 } 64 glEnd(); 65 } 66 67 void reshape(int x, int y) 68 { 69 if (y == 0 || x == 0) return; //Nothing is visible then, so return 70 71 //Set a new projection matrix 72 glMatrixMode(GL_PROJECTION); 73 glLoadIdentity(); 74 //Angle of view:40 degrees 75 //Near clipping plane distance: 0.5 76 //Far clipping plane distance: 20.0 77 gluPerspective(40.0,(GLdouble)x/(GLdouble)y,0.5,20.0); 78 79 glMatrixMode(GL_MODELVIEW); 80 glViewport(0,0,x,y); //Use the whole window for rendering 81 } 82 83 void Display(void) 84 { 85 glClear(GL_COLOR_BUFFER_BIT); 86 glLoadIdentity(); 87 Camera.Render(); 88 glTranslatef(0.0,0.8,0.0); 89 90 glScalef(3.0,1.0,3.0); 91 92 GLfloat size = 2.0; 93 GLint LinesX = 30; 94 GLint LinesZ = 30; 95 96 GLfloat halfsize = size / 2.0; 97 glColor3f(1.0,1.0,1.0); 98 glPushMatrix(); 99 glTranslatef(0.0,-halfsize ,0.0); 100 DrawNet(size,LinesX,LinesZ); 101 glTranslatef(0.0,size,0.0); 102 DrawNet(size,LinesX,LinesZ); 103 glPopMatrix(); 104 glColor3f(0.0,0.0,1.0); 105 glPushMatrix(); 106 glTranslatef(-halfsize,0.0,0.0); 107 glRotatef(90.0,0.0,0.0,halfsize); 108 DrawNet(size,LinesX,LinesZ); 109 glTranslatef(0.0,-size,0.0); 110 DrawNet(size,LinesX,LinesZ); 111 glPopMatrix(); 112 glColor3f(1.0,0.0,0.0); 113 glPushMatrix(); 114 glTranslatef(0.0,0.0,-halfsize); 115 glRotatef(90.0,halfsize,0.0,0.0); 116 DrawNet(size,LinesX,LinesZ); 117 glTranslatef(0.0,size,0.0); 118 DrawNet(size,LinesX,LinesZ); 119 glPopMatrix(); 120 121 glFlush(); 122 glutSwapBuffers(); 123 124 } 125 void KeyDown(unsigned char key, int x, int y) 126 { 127 switch (key) 128 { 129 case 27: //ESC 130 PostQuitMessage(0); 131 break; 132 case 'a': 133 Camera.RotateY(5.0); 134 Display(); 135 break; 136 case 'd': 137 Camera.RotateY(-5.0); 138 Display(); 139 break; 140 case 'w': 141 Camera.MoveForwards( -0.1 ) ; 142 Display(); 143 break; 144 case 's': 145 Camera.MoveForwards( 0.1 ) ; 146 Display(); 147 break; 148 case 'x': 149 Camera.RotateX(5.0); 150 Display(); 151 break; 152 case 'y': 153 Camera.RotateX(-5.0); 154 Display(); 155 break; 156 case 'c': 157 Camera.StrafeRight(-0.1); 158 Display(); 159 break; 160 case 'v': 161 Camera.StrafeRight(0.1); 162 Display(); 163 break; 164 case 'f': 165 Camera.Move(F3dVector(0.0,-0.3,0.0)); 166 Display(); 167 break; 168 case 'r': 169 Camera.Move(F3dVector(0.0,0.3,0.0)); 170 Display(); 171 break; 172 173 } 174 } 175 176 int main(int argc, char **argv) 177 { 178 glutInit(&argc, argv); 179 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); 180 glutInitWindowSize(300,300); 181 glutCreateWindow("Camera"); 182 Camera.Move( F3dVector(0.0, 0.0, 3.0 )); 183 Camera.MoveForwards( 1.0 ); 184 glutDisplayFunc(Display); 185 glutReshapeFunc(reshape); 186 glutKeyboardFunc(KeyDown); 187 glutMainLoop(); 188 return 0; 189 }
2、camera.cpp
1 #include "camera.h" 2 #include "math.h" 3 #include <iostream> 4 #include "windows.h" 5 6 SF3dVector F3dVector ( GLfloat x, GLfloat y, GLfloat z ) 7 { 8 SF3dVector tmp; 9 tmp.x = x; 10 tmp.y = y; 11 tmp.z = z; 12 return tmp; 13 } 14 SF3dVector AddF3dVectors (SF3dVector* u, SF3dVector* v) 15 { 16 SF3dVector result; 17 result.x = u->x + v->x; 18 result.y = u->y + v->y; 19 result.z = u->z + v->z; 20 return result; 21 } 22 void AddF3dVectorToVector ( SF3dVector * Dst, SF3dVector * V2) 23 { 24 Dst->x += V2->x; 25 Dst->y += V2->y; 26 Dst->z += V2->z; 27 } 28 29 30 /***************************************************************************************/ 31 32 CCamera::CCamera() 33 { 34 //Init with standard OGL values: 35 Position = F3dVector ( 0.0, 36 0.0, 37 0.0); 38 ViewDir = F3dVector( 0.0, 39 0.0, 40 -1.0); 41 ViewDirChanged = false; 42 //Only to be sure: 43 RotatedX = RotatedY = RotatedZ = 0.0; 44 } 45 46 void CCamera::GetViewDir( void ) 47 { 48 SF3dVector Step1, Step2; 49 //Rotate around Y-axis: 50 Step1.x = cos( (RotatedY + 90.0) * PIdiv180); 51 Step1.z = -sin( (RotatedY + 90.0) * PIdiv180); 52 //Rotate around X-axis: 53 double cosX = cos (RotatedX * PIdiv180); 54 Step2.x = Step1.x * cosX; 55 Step2.z = Step1.z * cosX; 56 Step2.y = sin(RotatedX * PIdiv180); 57 //Rotation around Z-axis not yet implemented, so: 58 ViewDir = Step2; 59 } 60 void CCamera::Move (SF3dVector Direction) 61 { 62 AddF3dVectorToVector(&Position, &Direction ); 63 } 64 65 void CCamera::RotateY (GLfloat Angle) 66 { 67 RotatedY += Angle; 68 ViewDirChanged = true; 69 } 70 71 void CCamera::RotateX (GLfloat Angle) 72 { 73 RotatedX += Angle; 74 ViewDirChanged = true; 75 } 76 77 void CCamera::Render( void ) 78 { 79 glRotatef(-RotatedX , 1.0, 0.0, 0.0); 80 glRotatef(-RotatedY , 0.0, 1.0, 0.0); 81 glRotatef(-RotatedZ , 0.0, 0.0, 1.0); 82 glTranslatef( -Position.x, -Position.y, -Position.z ); 83 } 84 85 void CCamera::MoveForwards( GLfloat Distance ) 86 { 87 if (ViewDirChanged) GetViewDir(); 88 SF3dVector MoveVector; 89 MoveVector.x = ViewDir.x * -Distance; 90 MoveVector.y = ViewDir.y * -Distance; 91 MoveVector.z = ViewDir.z * -Distance; 92 AddF3dVectorToVector(&Position, &MoveVector ); 93 } 94 95 void CCamera::StrafeRight ( GLfloat Distance ) 96 { 97 if (ViewDirChanged) GetViewDir(); 98 SF3dVector MoveVector; 99 MoveVector.z = -ViewDir.x * -Distance; 100 MoveVector.y = 0.0; 101 MoveVector.x = ViewDir.z * -Distance; 102 AddF3dVectorToVector(&Position, &MoveVector ); 103 }
2、camera.h
1 #include <gl\glut.h> // Need to include it here because the GL* types are required 2 #define PI 3.1415265359 3 #define PIdiv180 3.1415265359/180.0 4 5 ///////////////////////////////// 6 //Note: All angles in degrees // 7 ///////////////////////////////// 8 9 struct SF3dVector //Float 3d-vect, normally used 10 { 11 GLfloat x,y,z; 12 }; 13 struct SF2dVector 14 { 15 GLfloat x,y; 16 }; 17 18 class CCamera 19 { 20 private: 21 SF3dVector Position; 22 SF3dVector ViewDir; /*Not used for rendering the camera, but for "moveforwards" 23 So it is not necessary to "actualize" it always. It is only 24 actualized when ViewDirChanged is true and moveforwards is called*/ 25 bool ViewDirChanged; 26 GLfloat RotatedX, RotatedY, RotatedZ; 27 void GetViewDir ( void ); 28 public: 29 CCamera(); //inits the values (Position: (0|0|0) Target: (0|0|-1) ) 30 void Render ( void ); //executes some glRotates and a glTranslate command 31 //Note: You should call glLoadIdentity before using Render 32 void Move ( SF3dVector Direction ); 33 void RotateX ( GLfloat Angle ); 34 void RotateY ( GLfloat Angle ); 35 void RotateZ ( GLfloat Angle ); 36 void RotateXYZ ( SF3dVector Angles ); 37 void MoveForwards ( GLfloat Distance ); 38 void StrafeRight ( GLfloat Distance ); 39 }; 40 41 42 SF3dVector F3dVector ( GLfloat x, GLfloat y, GLfloat z ); 43 SF3dVector AddF3dVectors ( SF3dVector * u, SF3dVector * v); 44 void AddF3dVectorToVector ( SF3dVector * Dst, SF3dVector * V2);
以上代码来源:http://www.codecolony.de/