首页 > 代码库 > openGL+VS2010的例程--空间摄影机注释版(三维)
openGL+VS2010的例程--空间摄影机注释版(三维)
效果图如上:
步骤:请看注释,这里略。
实现代码,有3个文件,如下:
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 // 绘制网格-第1个参数网格的总边长,第2、3个是横纵线条的总个数。 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); // 当LinesX=30时, (-1,0,1) (-1+2/29, 0, 1)(-1+4/29, 0, 1).....(-1+2*29/29, 0, 1) 51 glVertex3f( -size / 2.0 + xc / (GLfloat)(LinesX-1)*size, 52 0.0, 53 size / -2.0);// (-1,0,-1) 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(); // 设置摄影机的空间坐标(0,0,4),相当于屏幕前的观察者往后退4个单位 88 glTranslatef(0.0,0.8,0.0); // 0.8 是该模型的Y轴上实际构造位置 89 90 glScalef(4.0,1.0,4.0); // 模型的放大比例 91 92 GLfloat size = 2.0; 93 GLint LinesX =41; // 网格面X轴边的线条个数 94 GLint LinesZ = 41; 95 96 GLfloat halfsize = size / 2.0; 97 glColor3f(1.0,1.0,1.0); // 白色 98 99 glPushMatrix(); // 压栈1100 glTranslatef(0.0,-halfsize ,0.0); // 下沉半个单位绘制底面网格101 DrawNet(size,LinesX,LinesZ); // 绘制网格 102 glTranslatef(0.0,size,0.0);// 上升一个完整的单位绘制底面网格103 DrawNet(size,LinesX,LinesZ); // 绘制网格 104 glPopMatrix(); // 出栈1105 106 glColor3f(0.0,0.0,1.0); // 蓝色107 glPushMatrix();108 glTranslatef(-halfsize,0.0,0.0); // 左移半个单位绘制底面网格109 glRotatef(90.0,0.0,0.0,halfsize); // 沿着Z轴顺时针旋转90°。110 DrawNet(size,LinesX,LinesZ);111 glTranslatef(0.0,-size,0.0); // 沿着Y轴负方向移动,即世界坐标的右移。112 DrawNet(size,LinesX,LinesZ);113 glPopMatrix();114 115 glColor3f(1.0,0.0,0.0); // 红色116 glPushMatrix();117 glTranslatef(0.0,0.0,-halfsize); // 沿着Z轴负方向移动 118 glRotatef(90.0,halfsize,0.0,0.0); // 沿着X轴顺时针旋转90°。119 DrawNet(size,LinesX,LinesZ);120 glTranslatef(0.0,size,0.0); // 沿着Y轴正方向移动,即世界坐标的往前靠。121 DrawNet(size,LinesX,LinesZ);122 glPopMatrix();123 124 glFlush(); 125 glutSwapBuffers();126 127 }128 129 void KeyDown(unsigned char key, int x, int y)130 {131 switch (key) 132 {133 case 27: //ESC 134 PostQuitMessage(0); // 关闭应用程序135 break;136 case ‘a‘: // 视角面向左137 Camera.RotateY(5.0);138 Display();139 break;140 case ‘d‘: // 视角面向右141 Camera.RotateY(-5.0); 142 Display();143 break;144 case ‘w‘: // 视角点前移 145 Camera.MoveForwards( -0.1 ) ;146 Display();147 break;148 case ‘s‘: // 视角点后退 149 Camera.MoveForwards( 0.1 ) ;150 Display();151 break;152 case ‘x‘: // 视角面向上153 Camera.RotateX(5.0);154 Display();155 break;156 case ‘y‘: // 视角面向下157 Camera.RotateX(-5.0);158 Display();159 break;160 case ‘c‘: // 视角点左移161 Camera.StrafeRight(-0.1);162 Display();163 break;164 case ‘v‘: // 视角点右移165 Camera.StrafeRight(0.1);166 Display();167 break;168 case ‘f‘: // 视角点下移169 Camera.Move(F3dVector(0.0,-0.3,0.0));170 Display();171 break;172 case ‘r‘: // 视角点上移173 Camera.Move(F3dVector(0.0,0.3,0.0));174 Display();175 break;176 177 }178 }179 180 int main(int argc, char **argv)181 {182 glutInit(&argc, argv);183 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);184 glutInitWindowSize(600,600);185 glutCreateWindow("Camera");186 Camera.Move( F3dVector(0.0, 0.0, 3.0 )); // 摄影机的空间坐标187 Camera.MoveForwards( 1.0 ); // 略188 glutDisplayFunc(Display); // 在以下几种情况下会被调用,在窗口从被遮挡中恢复时调用,动画刷新调用等。189 glutReshapeFunc(reshape); // 调整窗口大小时被调用,创建窗口相当于调整了一次窗口大小。190 glutKeyboardFunc(KeyDown); // 按键触发时执行 191 glutMainLoop();192 return 0; 193 }
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 15 SF3dVector AddF3dVectors (SF3dVector* u, SF3dVector* v) 16 { 17 SF3dVector result; 18 result.x = u->x + v->x; 19 result.y = u->y + v->y; 20 result.z = u->z + v->z; 21 return result; 22 } 23 24 void AddF3dVectorToVector ( SF3dVector * Dst, SF3dVector * V2) 25 { 26 Dst->x += V2->x; 27 Dst->y += V2->y; 28 Dst->z += V2->z; 29 } 30 31 32 /***************************************************************************************/ 33 34 CCamera::CCamera() 35 { 36 //Init with standard OGL values: 37 Position = F3dVector ( 0.0, 38 0.0, 39 0.0); // 观察点的初始值 40 ViewDir = F3dVector( 0.0, 41 0.0, 42 -1.0); // 观察面的初始值 43 ViewDirChanged = false; 44 //Only to be sure: 45 RotatedX = RotatedY = RotatedZ = 0.0; // 旋转角度的初始值 46 } 47 48 // 获取观察面 49 void CCamera::GetViewDir( void ) 50 { 51 // 假设视角面的向量是1个单位,根据各轴面的旋转角度,计算X、Y、Z的比值。 52 // 那么step1是处理无俯仰视角的过程;step2是处理存在俯仰的过程。 53 SF3dVector Step1, Step2; 54 //Rotate around Y-axis: 55 Step1.x = cos( (RotatedY + 90.0) * PIdiv180);// 视角点在世界坐标系的偏移位置 56 Step1.z = -sin( (RotatedY + 90.0) * PIdiv180); 57 //Rotate around X-axis: 58 double cosX = cos (RotatedX * PIdiv180); 59 Step2.x = Step1.x * cosX; 60 Step2.z = Step1.z * cosX; 61 Step2.y = sin(RotatedX * PIdiv180); 62 //Rotation around Z-axis not yet implemented, so: 63 ViewDir = Step2; 64 } 65 void CCamera::Move (SF3dVector Direction) 66 { 67 AddF3dVectorToVector(&Position, &Direction ); // 观察点的最终值,分多次操作值累加而成 68 } 69 70 // 以Y轴(0,1,0)为旋转轴 71 void CCamera::RotateY (GLfloat Angle) 72 { 73 RotatedY += Angle; 74 ViewDirChanged = true; 75 } 76 // 以X轴(1,0,0)为旋转轴 77 void CCamera::RotateX (GLfloat Angle) 78 { 79 RotatedX += Angle; 80 ViewDirChanged = true; 81 } 82 83 // 渲染 84 void CCamera::Render( void ) 85 { 86 // 旋转模型(观察面调整) 87 glRotatef(-RotatedX , 1.0, 0.0, 0.0); 88 glRotatef(-RotatedY , 0.0, 1.0, 0.0); 89 glRotatef(-RotatedZ , 0.0, 0.0, 1.0); 90 91 glTranslatef( -Position.x, -Position.y, -Position.z ); // 移动(观察点调整) 92 } 93 94 // 视角点前后移 95 void CCamera::MoveForwards( GLfloat Distance ) 96 { 97 if (ViewDirChanged) GetViewDir(); 98 SF3dVector MoveVector; 99 MoveVector.x = ViewDir.x * -Distance;100 MoveVector.y = ViewDir.y * -Distance; // 视角点 前后移动时,有“上浮”和“下潜”的感觉。101 MoveVector.z = ViewDir.z * -Distance;102 AddF3dVectorToVector(&Position, &MoveVector );103 }104 // 视角点左右移105 void CCamera::StrafeRight ( GLfloat Distance )106 {107 if (ViewDirChanged) GetViewDir();108 SF3dVector MoveVector;109 MoveVector.z = -ViewDir.x * -Distance;110 MoveVector.y = 0.0; // 视角点 水平移动时,Y轴保持不变。111 MoveVector.x = ViewDir.z * -Distance;112 AddF3dVectorToVector(&Position, &MoveVector );113 }
3、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 used10 {11 GLfloat x,y,z;12 };13 struct SF2dVector14 {15 GLfloat x,y;16 };17 18 class CCamera19 {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 only24 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 command31 //Note: You should call glLoadIdentity before using Render32 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/
openGL+VS2010的例程--空间摄影机注释版(三维)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。