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     [email protected]
 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(); // 压栈1
100         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(); // 出栈1
105
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 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/

时间: 2024-10-10 12:40:47

openGL+VS2010的例程--空间摄影机注释版(三维)的相关文章

openGL+VS2010的例程--城堡模型注释版(三维)

效果图如上: 步骤:略,构成顺序参考下图1.2. 图1 城墙构成顺序说明图: 图2  塔楼构成说明图:略 实现代码如下: main.cpp 1 /********************************************************************** 2 3 Castle - using Display Lists 4 5 June, 12th, 2000 6 7 This tutorial was written by Philipp Crocoll 8 C

openGL+VS2010的例程--旋转变色立方体(三维)

效果图如上. 步骤:首先,变换模型视角:然后,改变颜色:最后,利用顶点数组绘制立方体. 源代码如下: #include <GL/glut.h> // 绘制立方体 // 将立方体的八个顶点保存到一个数组里面 static const float vertex_list[][3] = { -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f, 0.5f, 0.5f,

openGL+VS2010的例程--太阳地球月球运动模型增强版(三维)

效果图如上: 步骤:请看注释,这里略. 实现代码如下: 1 #include "windows.h" 2 #include <gl\glut.h> 3 4 // 三者的大小比例 5 #define SunSize 0.4 6 #define EarthSize 0.06 7 #define MoonSize 0.016 8 9 GLfloat SpeedMultiplicator = 0.01;// 运行倍数 10 // 时间比例 11 GLfloat DaysPerYea

openGL+VS2010的例程--旋转贴图灯笼(三维)

效果图如上: 步骤:略. 常见问题: 1.编译提示"gl/glaux.h"不存在,多发生在VS2008版本以上. 解决办法:下载包含"glaux.h"的库文件. 下载地址:http://yunpan.cn/cKZPLCcQufqRi 访问密码 ba74 2.运行时提示”text1.bmp“打开失败. 解决办法:将2个贴图文件放在项目文件夹下,如:X:...\Textures1\textures1内. 实现代码如下: main.cpp 1 /*************

openGL+VS2010的例程--特效(三维)

效果图如上: 步骤:略. 实现代码如下: main.cpp 1 /********************************************************************** 2 3 Particle Engine / Billboarding 4 5 October, 21st, 2002 6 7 This tutorial was written by Philipp Crocoll 8 Contact: 9 [email protected] 10 www.

openGL+VS2010的例程--立体四面体(二维)

说明:通过6条线段组合,构造一个立体四面体,是最基本的二维实现. 实现代码如下: #include <GL/glut.h> void init(void) { glClearColor(1.0, 1.0, 1.0, 0.0); glMatrixMode(GL_PROJECTION); gluOrtho2D(0.0, 200.0, 0.0, 150.0); } void lineSegment(void) { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0

openGL+VS2010的例程--旋转立方体(三维)

效果图如上: 步骤:首先,设置模型视角往后退,再旋转视角:然后,用默认绘制立方体函数绘制:最后,利用空闲对模型做角度微调. 实现代码如下: 1 #include <GL\glut.h> 2 3 GLfloat xRotated, yRotated, zRotated; 4 5 void Display(void) 6 { 7 glClear(GL_COLOR_BUFFER_BIT); 8 glLoadIdentity(); 9 glTranslatef(0.0,0.0,-4.0); 10 gl

openGL+VS2010的例程--太阳地球月球运动模型(三维)

效果图如上: 步骤:略 实现代码如下: 1 #include "windows.h" 2 #include <gl\glut.h> 3 4 #define SunSize 0.4 5 #define EarthSize 0.06 6 #define MoonSize 0.016 7 8 GLfloat SpeedMultiplicator = 1.0; 9 GLfloat DaysPerYear = 50.0; //OK, ok... but it is soo slow

openGL+VS2010的例程--静态平滑变色三角形(二维)

效果图如上: 步骤:首先,绘制顶点颜色不同的三角形:然后,设置边框大小改变时,重新按固定长宽比例投影,到整个显示界面. 实现代码如下: #include <GL\glut.h> void Display(void) { glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); glBegin(GL_POLYGON); glColor3f(0.0,0.0,0.0); glVertex3f(-0.5,-0.5,-3.0); glColor3f(1.0,0.0,