首页 > 代码库 > 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的例程--空间摄影机注释版(三维)