码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-01-24 13:03:38      阅读:611      评论:0      收藏:0      [点我收藏+]

标签:

技术分享

效果图如上:

步骤:略,构成顺序参考下图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   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 ESC: exit
 19 
 20 CAMERA movement:
 21 w : forwards
 22 s : backwards
 23 a : turn left
 24 d : turn right
 25 x : turn up
 26 y : turn down
 27 v : strafe right
 28 c : strafe left
 29 r : move up
 30 f : move down
 31 
 32 **********************************************************************/
 33 
 34    
 35 #include <GL\glut.h>        //includes gl.h and glu.h
 36 #include <math.h>            //sine and cosine functions
 37 #include "camera.h"
 38 #include <windows.h>
 39 #define PI 3.1415265359
 40 
 41 static GLfloat MatSpec[] = {1.0,1.0,1.0,1.0};
 42 static GLfloat MatShininess[] = {45.0};
 43 static GLfloat LightPos[] = {-2.0,1.5,1.0,0.0};
 44 static GLfloat ModelAmb[] = {0.5,0.5,0.5,0.0};
 45 
 46 
 47 CCamera Camera;
 48 
 49 GLint TowerListNum,WallsListNum;  //Numbers of the display lists
 50 GLint WallsList;
 51 //Tower properties:
 52 int NumOfEdges = 12; // 塔身弯曲的精细度
 53 GLfloat LowerHeight =3.0; // 塔顶圆台的最小半径
 54 GLfloat HigherHeight = 3.5; // 塔顶圆台的最大半径
 55 GLfloat HR = 1.3;  //Radius of the highest part // 塔顶的半径
 56 
 57 //Wall properties:
 58 GLfloat WallElementSize = 0.4; // 城墙的突出部分的长度
 59 GLfloat WallHeight = 2.0;  // 城墙的高度
 60 
 61 // 画出更高的墙部分--突出的墙垣
 62 void DrawHigherWallPart(int NumElements)
 63 /*Draws a wall part like this:
 64      ___    ___       ___
 65     |    |  |   |  |   |
 66     |___|  |___|  |___| 
 67   and so on
 68   such an element is squareshaped and has the height/width WallElementSize*/
 69 {
 70     glBegin(GL_QUADS);
 71     for (int i = 0; i < NumElements; i++)
 72     {
 73         glNormal3f(0.0,0.0,-1.0);
 74         glVertex3f(i*2.0 * WallElementSize, 0.0, 0.0);
 75         glVertex3f(i*2.0 * WallElementSize, WallElementSize, 0.0);
 76         glVertex3f((i*2.0+1.0) * WallElementSize, WallElementSize, 0.0);
 77         glVertex3f((i*2.0+1.0) * WallElementSize, 0.0, 0.0);
 78 
 79     }
 80 
 81     glEnd();
 82 
 83 }
 84 
 85 // 画出墙体的部分
 86 void DrawWall(GLfloat Length)
 87 {
 88     glBegin(GL_QUADS);
 89         glNormal3f(0.0,0.0,-1.0); // 设置法向量
 90         glVertex3f(0.0,0.0,0.0);
 91         glVertex3f(0.0,WallHeight,0.0);
 92         glVertex3f(Length,WallHeight,0.0);
 93         glVertex3f(Length,0.0,0.0);
 94     glEnd();
 95     // 画出城墙的突出部分。
 96     int i = (int)(Length / WallElementSize / 2);
 97     if (i * WallElementSize > Length) i--;
 98     glPushMatrix();
 99         glTranslatef(0.0,WallHeight,0.0);
100         DrawHigherWallPart(i);
101     glPopMatrix();
102 }
103         
104 
105 
106 void Init(void) //used to create the display lists
107 {
108     TowerListNum = glGenLists(1); // 会生成一组连续的空的显示列表
109     GLfloat x,z;
110     int i=0;
111     GLfloat NVectY;  //y component for the NVects of the higher part // y分量的NVects更高的一部分
112 
113     glNewList(TowerListNum, GL_COMPILE);  // 用于创建和替换一个显示列表函数原型
114         glBegin(GL_QUADS); // 四边形 
115         //Create the lower part of the tower: // 创建塔身的圆柱形部分
116         for (i = 0; i < NumOfEdges-1; i++)
117         {    
118             x = cos((float)i/(float)NumOfEdges * PI * 2.0);
119             z = sin((float)i/(float)NumOfEdges * PI * 2.0);
120             glNormal3f(x,0.0,z);
121             glVertex3f(x,LowerHeight,z);
122             //same x,z and NVect:
123             glVertex3f(x,0.0,z);
124 
125             x = cos((float)(i+1)/(float)NumOfEdges * PI * 2.0);
126             z = sin((float)(i+1)/(float)NumOfEdges * PI * 2.0);
127             glNormal3f(x,0.0,z);
128             glVertex3f(x,0.0,z);
129             //same x,z and NVect:
130             glVertex3f(x,LowerHeight,z);
131         }
132         // 塔身侧面的连接处 
133         x = cos((float)i/(float)NumOfEdges * PI * 2.0);
134         z = sin((float)i/(float)NumOfEdges * PI * 2.0);
135         glNormal3f(x,0.0,z);
136         glVertex3f(x,LowerHeight,z);
137         //same x,z and NVect:
138         glVertex3f(x,0.0,z);
139         x = cos(1.0/(float)NumOfEdges * PI * 2.0);
140         z = sin(1.0/(float)NumOfEdges * PI * 2.0);
141         glNormal3f(x,0.0,z);
142         glVertex3f(x,0.0,z);
143         //same x,z and NVect:
144         glVertex3f(x,LowerHeight,z);
145         
146         
147         //Create the higher part: // 创建塔顶的倒梯形部分。
148 
149         //The y component is the same for all NVects, so we can calculate it here:
150         // 对所有NVects y分量是一样的,所以在这里我们可以计算:
151         NVectY = (HR-1.0) / (LowerHeight - HigherHeight) * (HR-1.0); // = (1.3-1.0)/(3.5-3.0)*(1.3-1.0)
152 
153         for (i = 0; i < NumOfEdges-1; i++)
154         {    
155             x = cos((float)i/(float)NumOfEdges * PI * 2.0);
156             z = sin((float)i/(float)NumOfEdges * PI * 2.0);
157             glNormal3f(x,NVectY,z);
158             glVertex3f(x*HR,HigherHeight,z*HR);
159             //same x,z and NVect:
160             glVertex3f(x,LowerHeight,z);
161 
162             x = cos((float)(i+1)/(float)NumOfEdges * PI * 2.0);
163             z = sin((float)(i+1)/(float)NumOfEdges * PI * 2.0);
164             glNormal3f(x,NVectY,z);
165             glVertex3f(x,LowerHeight,z);
166             //same x,z and NVect:
167             glVertex3f(x*HR,HigherHeight,z*HR);
168         }
169         // 塔顶侧面的连接处
170         x = cos((float)i/(float)NumOfEdges * PI * 2.0);
171         z = sin((float)i/(float)NumOfEdges * PI * 2.0);
172         glNormal3f(x,NVectY,z);
173         glVertex3f(x*HR,HigherHeight,z*HR);
174         //same x,z and NVect:
175         glVertex3f(x,LowerHeight,z);
176         x = cos(1.0/(float)NumOfEdges * PI * 2.0);
177         z = sin(1.0/(float)NumOfEdges * PI * 2.0);
178         glNormal3f(x,NVectY,z);
179         glVertex3f(x,LowerHeight,z);
180         //same x,z and NVect:
181         glVertex3f(x*HR,HigherHeight,z*HR);
182         
183         glEnd();
184     glEndList();
185 
186     ////////////////////////////////////////////////////////////
187 
188     //WallList
189 
190     ////////////////////////////////////////////////////////////
191 
192     WallsListNum = glGenLists(1); // 创建显示列表1个
193     glNewList(WallsListNum, GL_COMPILE);
194     DrawWall(10.0); // 绘制墙面=1
195     glPushMatrix(); // 压栈1
196 
197     glTranslatef(10.0,0.0,0.0); // 移动到点2
198 
199     glPushMatrix(); // 压栈2
200         glRotatef(270.0,0.0,1.0,0.0);
201         DrawWall(10.0); // 绘制墙面=2
202     glPopMatrix(); // 出栈2
203 
204     glTranslatef(0.0,0.0,10.0); // 向前10个单位 // 移动到点3
205 
206     glPushMatrix(); // 压栈3
207         glRotatef(180.0,0.0,1.0,0.0);
208         DrawWall(5.0); // 绘制墙面=3
209         glRotatef(90.0,0.0,1.0,0.0);
210         glTranslatef(0.0,0.0,5.0);
211         DrawWall(5.0);  // 绘制墙面=4
212     glPopMatrix();// 出栈3
213 
214     glTranslatef(-5.0,0.0,5.0); // 移动到点4
215 
216     glPushMatrix(); // 压栈4
217         glRotatef(180.0,0.0,1.0,0.0);
218         DrawWall(5.0); // 绘制墙面=5
219     glPopMatrix(); // 出栈4
220 
221     //Last and longest piece:
222     glPushMatrix(); // 压栈5
223         glRotatef(90.0,0.0,1.0,0.0);
224         glTranslatef(0.0,0.0,-5.0); // // 移动到点5
225         DrawWall(6.0);  // // 绘制墙面=7
226         //the "door"
227             glTranslatef(6.0,0.0,0.0);
228              // 绘制墙面=8
229             glBegin(GL_QUADS);
230                 glNormal3f(0.0,0.0,-1.0);
231                 glVertex3f(0.0,WallHeight / 2.0,0.0);
232                 glVertex3f(0.0,WallHeight,0.0);
233                 glVertex3f(3.0,WallHeight,0.0); // 门的宽度=3.0
234                 glVertex3f(3.0,WallHeight / 2.0,0.0);                
235             glEnd();
236 
237             i = (int)(3.0 / WallElementSize / 2);
238             if (i * WallElementSize > 3.0) i--;
239 
240             glPushMatrix();// 压栈6
241                 glTranslatef(0.0,WallHeight,0.0);
242                 DrawHigherWallPart(i); // 绘制城墙的顶部
243             glPopMatrix();  // 出栈6
244         
245         glTranslatef(3.0,0.0,0.0);
246         DrawWall(6.0);// 绘制墙面=9
247     glPopMatrix(); // 出栈5
248     
249     glPopMatrix(); // 出栈1
250 
251     glEndList();
252 }
253 
254 void Display(void)
255 {
256     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
257     glLoadIdentity();    
258     Camera.Render();
259     glLightfv(GL_LIGHT0,GL_POSITION,LightPos);
260     glTranslatef(-7.0,2.0,-7.0);
261     glRotatef(90.0,0.0,1.0,0.0);
262     glBegin(GL_POLYGON);
263         glNormal3f(0.0,1.0,0.0); // 法向量= y轴
264         glVertex3f(0.0,0.0,0.0); //  编号点=1
265         glVertex3f(10.0,0.0,0.0); //  编号点=2
266         glVertex3f(10.0,0.0,10.0); //  编号点=3
267         glVertex3f(5.0,0.0,15.0); //  编号点=4
268         glVertex3f(0.0,0.0,15.0); //  编号点=5
269         glVertex3f(0.0,0.0,0.0);//  编号点=1
270     glEnd();
271 
272 
273     //Turn two sided lighting on for the walls
274     glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
275 
276     glCallList(WallsListNum); //  调用城墙的显示列表
277     
278     //Disable it again for the towers: // 关闭它,塔楼不使用
279     glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
280 
281         
282     glCallList(TowerListNum); //  目前点=1
283     
284     glTranslatef(10.0,0.0,0.0) ; // 移动到点=2
285     glCallList(TowerListNum);
286 
287     glTranslatef(0.0,0.0,10.0); // 移动到点=3
288     glCallList(TowerListNum);
289 
290     glTranslatef(-5.0,0.0,5.0); // 移动到点=4
291     glCallList(TowerListNum);
292 
293     glTranslatef(-5.0,0.0,0.0); // 移动到点=5
294     glCallList(TowerListNum);
295 
296     glFlush();            //Finish rendering
297     glutSwapBuffers();    //Swap the buffers ->make the result of rendering visible
298 }
299 void Reshape(int x, int y)
300 {
301     if (y == 0 || x == 0) return;  //Nothing is visible then, so return
302     //Set a new projection matrix
303     glMatrixMode(GL_PROJECTION);  // 投影模式
304     glLoadIdentity();
305     //Angle of view:40 degrees
306     //Near clipping plane distance: 0.5
307     //Far clipping plane distance: 20.0
308     gluPerspective(40.0,(GLdouble)x/(GLdouble)y,1.0,200.0); // 投影范围。
309     glMatrixMode(GL_MODELVIEW); // 视景模式。
310     glViewport(0,0,x,y);  
311 }
312 void KeyDown(unsigned char key, int x, int y)
313 {    
314     switch(key)
315     {
316     case 27:    //ESC
317         exit(0);
318         break;
319     case a:        
320         Camera.RotateY(5.0);
321         Display();
322         break;
323     case d:        
324         Camera.RotateY(-5.0);
325         Display();
326         break;
327     case w:        
328         Camera.MoveForwards( -0.3 ) ;
329         Display();
330         break;
331     case s:        
332         Camera.MoveForwards( 0.3 ) ;
333         Display();
334         break;
335     case x:        
336         Camera.RotateX(5.0);
337         Display();
338         break;
339     case y:        
340         Camera.RotateX(-5.0);
341         Display();
342         break;
343     case c:        
344         Camera.StrafeRight(-0.3);
345         Display();
346         break;
347     case v:        
348         Camera.StrafeRight(0.3);
349         Display();
350         break;
351     case f:
352         Camera.Move(F3dVector(0.0,-0.3,0.0));
353         Display();
354         break;
355     case r:
356         Camera.Move(F3dVector(0.0,0.3,0.0));
357         Display();
358         break;
359 
360     
361     }
362 }
363 
364 int main(int argc, char **argv)
365 {    
366     glutInit(&argc, argv);
367     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
368     glutInitWindowSize(600,600);
369     glutCreateWindow("Castle");
370     glEnable(GL_DEPTH_TEST); // 深度测试
371     glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); // 设置正反面为线形模式
372     glClearColor(0.0,0.0,0.0,0.0); // 黑色
373     glutDisplayFunc(Display);
374     glutReshapeFunc(Reshape);
375     glutKeyboardFunc(KeyDown);
376     Camera.Move(F3dVector(0.0,5.0,20.0)); // 摄像机的位置。
377     glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, MatSpec);  // 材质属性中的镜面反射光 
378     glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, MatShininess); //  //材质属性的镜面反射指数 
379     glEnable(GL_LIGHTING);
380     glEnable(GL_LIGHT0);
381     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ModelAmb); // 设置光照模式(全局环境光)
382     Init();
383     glutMainLoop();
384     return 0;
385 }

原始代码来源:http://www.codecolony.de/

 

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

标签:

原文地址:http://www.cnblogs.com/yuwl26/p/4245659.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!