OpenGL三维与光照

  1 #include<windows.h>
  2 #include<gl/glut.h>
  3 #include<gl/gl.h>
  4 #include<gl/glu.h>
  5
  6 //参数指定正方形的位置和大小
  7 GLfloat x1=100.0f;
  8 GLfloat y1=150.0f;
  9 GLsizei rsize=50;
 10
 11 //正方形运动变化的步长
 12 GLfloat xstep=1.0f;
 13 GLfloat ystep=1.0f;
 14
 15 //窗口的大小
 16 GLfloat windowWidth;
 17 GLfloat windowHeight;
 18
 19 //画的物体
 20 void DrawDUA();
 21 void DrawTR();
 22
 23 //属性开关
 24 void SunShine(void);//光照
 25
 26 //三维
 27 GLfloat rtri;
 28 GLfloat rquad;
 29
 30 //开关
 31 BOOL Draw3D=true;//三维动画演示开关
 32 BOOL Draw2D=false;//二维动画演示开关
 33 BOOL DrawAtoms=false;//原子动画演示开关
 34
 35
 36                     //三维属性开关
 37                     BOOL AS=true;//透视投影开关
 38                     BOOL OR=false;//正交平行投影
 39                     BOOL LIGHT=true;//光照开关
 40
 41
 42
 43 void RenderScene(void)
 44 {
 45     if(Draw3D)
 46     {
 47         glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 48         glMatrixMode(GL_MODELVIEW);
 49         glLoadIdentity();
 50         if(LIGHT)
 51             SunShine();
 52
 53         glTranslatef(-1.5f,0.0f,-6.0f);
 54         glRotatef(rtri,0.0f,1.0f,0.0f);
 55
 56         DrawTR();
 57
 58         glLoadIdentity();
 59         glTranslatef(1.5f,0.0f,-6.0f);
 60         glRotatef(rquad,1.0f,0.0f,0.0f);
 61         glColor3f(0.5f,0.5f,1.0f);
 62
 63
 64         DrawDUA();
 65
 66         rtri+=1.0f;
 67         rquad-=0.5f;
 68     }
 69
 70     if(Draw2D)
 71     {
 72         glClear(GL_COLOR_BUFFER_BIT);
 73         glColor3f(1.0f,0.0f,0.0f);
 74         glRectf(x1,y1,x1+rsize,y1+rsize);
 75     }
 76
 77     if(DrawAtoms)
 78     {
 79         //绕核旋转角度
 80         static float fElect1=0.0f;
 81
 82         glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 83
 84         //重置模型视图矩阵
 85         glMatrixMode(GL_MODELVIEW);
 86         glLoadIdentity();
 87         if(LIGHT)
 88             SunShine();
 89
 90         //将图形沿Z轴负向移动
 91         glTranslatef(0.0f,0.0f,-250.0f);
 92
 93         //绘制红色原子核
 94         glColor3f(1.0f,0.0f,0.0f);
 95         glutWireSphere(10.0f,15,15);
 96
 97         //绘制颜色变成绿色
 98         glColor3f(0.0f,1.0f,0.0f);
 99
100         //绘制第一个电子
101         //保存当前的模型视图矩阵
102         glPushMatrix();
103         glRotatef(fElect1,0.0f,1.0f,0.0f);//绕y轴旋转一定角度
104         glTranslatef(90.0f,0.0f,0.0f);//平移一段距离
105         glutSolidSphere(6.0f,15,15);//画出电子
106
107         //恢复矩阵
108         glPopMatrix();
109         glColor3f(0.0f,0.0f,1.0f);//绘制颜色变成蓝色
110         //第二个电子
111         glPushMatrix();
112         glRotatef(45.0f,0.0f,0.0f,1.0f);
113         glRotatef(fElect1,0.0f,1.0f,0.0f);
114         glTranslatef(-70.0f,0.0f,0.0f);
115         glutSolidSphere(6.0f,15,15);
116         glPopMatrix();
117
118         glColor3f(1.0f,1.0f,0.0f);//绘制颜色变成黄色
119         //第三个电子
120         glPushMatrix();
121         glRotatef(-45.0f,0.0f,0.0f,1.0f);
122         glRotatef(fElect1,0.0f,1.0f,0.0f);
123         glTranslatef(0.0f,0.0f,60.0f);
124         glutSolidSphere(6.0f,15,15);
125         glPopMatrix();
126         fElect1+=10.0f;
127         if(fElect1>360.0f)
128             fElect1=10.0f;
129     }
130     glutSwapBuffers();
131 }
132
133 void ChangeSize(GLsizei w,GLsizei h)
134 {
135     if(h==0)
136         h==1;
137
138     //设置视区尺寸
139     glViewport(0,0,w,h);
140     glMatrixMode(GL_PROJECTION);
141     glLoadIdentity();
142
143     if(Draw3D||DrawAtoms)
144     {
145         //修剪空间(透视投影)
146         if(AS)
147         {
148             GLfloat fAspect;
149             fAspect =(float)w/(float)h;
150             gluPerspective(45.0,fAspect,1.0,500.0);
151         }
152
153
154
155         //(正交平行投影)
156         if(OR)
157         {
158             if(w<=h)
159                 glOrtho(-2.25,2.25,-2.25*h/w,2.25*h/w,-10.0,10.0);
160             else
161                 glOrtho(-2.25*h/w,2.25*h/w,-2.25,2.25,-10.0,10.0);
162         }
163
164
165
166     }
167
168     if(Draw2D)
169     {
170         if(w<=h)
171         {
172             windowHeight=250.0f*h/w;
173             windowWidth=250.0f;
174         }
175         else
176         {
177             windowWidth=250.0f*w/h;
178             windowHeight=250.0f;
179         }
180
181         glOrtho(0.0f,windowWidth,0.0f,windowHeight,1.0f,-1.0f);
182     }
183
184     glMatrixMode(GL_MODELVIEW);
185     glLoadIdentity();
186 }
187
188 void TimerFunction(int value)
189 {
190     if(x1>windowWidth-rsize||x1<0)
191         xstep=-xstep;
192     if(y1>windowHeight-rsize||y1<0)
193         ystep=-ystep;
194
195     x1+=xstep;
196     y1+=ystep;
197
198     glutPostRedisplay();
199     glutTimerFunc(5,TimerFunction,1);
200 }
201
202 void SetupRC(void)
203 {
204     if(Draw3D||DrawAtoms)
205     {
206         glEnable(GL_DEPTH_TEST);//启用深度测试
207         glFrontFace(GL_CCW);
208     }
209     glClearColor(0.0f,0.0f,1.0f,1.0f);
210 }
211 void TimerFunc(int value)
212 {
213     glutPostRedisplay();
214     if(Draw3D)
215     {
216         glutTimerFunc(1,TimerFunc,1);
217     }
218     if(DrawAtoms)
219     {
220         glutTimerFunc(100,TimerFunc,1);
221     }
222
223 }
224 int main(int argc,char* argv[])
225 {
226     if(Draw2D)
227     {
228         glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
229         glutCreateWindow("Bounce");
230         glutDisplayFunc(RenderScene);
231         glutReshapeFunc(ChangeSize);
232         glutTimerFunc(5,TimerFunction,1);
233     }
234     if(Draw3D||DrawAtoms)
235     {
236         glutInit(&argc,argv);
237         glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
238         glutCreateWindow("原子示例");
239         glutReshapeFunc(ChangeSize);
240         glutDisplayFunc(RenderScene);
241         if(DrawAtoms)
242             glutTimerFunc(100,TimerFunc,1);
243         else
244             glutTimerFunc(1,TimerFunc,1);
245     }
246
247     SetupRC();
248     glutMainLoop();
249 }
250 void DrawTR()
251 {
252     glBegin(GL_TRIANGLES);
253         //
254         glColor3f(1.0f,0.0f,0.0f);
255         glVertex3f(0.0f,1.0f,0.0f);
256
257         glColor3f(0.0f,1.0f,0.0f);
258         glVertex3f(-1.0f,-1.0f,1.0f);
259
260         glColor3f(0.0f,0.0f,1.0f);
261         glVertex3f(1.0f,-1.0f,1.0f);
262
263         //
264         glColor3f(1.0f,0.0f,0.0f);
265         glVertex3f(0.0f,1.0f,0.0f);
266
267         glColor3f(0.0f,0.0f,1.0f);
268         glVertex3f(1.0f,-1.0f,1.0f);
269
270         glColor3f(0.0f,1.0f,0.0f);
271         glVertex3f(1.0f,-1.0f,-1.0f);
272
273         //
274         glColor3f(1.0f,0.0f,0.0f);
275         glVertex3f(0.0f,1.0f,0.0f);
276
277         glColor3f(0.0f,1.0f,0.0f);
278         glVertex3f(1.0f,-1.0f,-1.0f);
279
280         glColor3f(0.0f,0.0f,1.0f);
281         glVertex3f(-1.0f,-1.0f,-1.0f);
282
283         //
284         glColor3f(1.0f,0.0f,0.0f);
285         glVertex3f(0.0f,1.0f,0.0f);
286
287         glColor3f(0.0f,0.0f,1.0f);
288         glVertex3f(-1.0f,-1.0f,-1.0f);
289
290         glColor3f(0.0f,1.0f,0.0f);
291         glVertex3f(-1.0f,-1.0f,1.0f);
292
293         glEnd();
294 }
295
296 void DrawDUA()
297 {
298     glBegin(GL_QUADS);
299
300         glColor3f(0.0f,1.0f,0.0f);
301         glVertex3f(1.0f,1.0f,-1.0f);
302         glVertex3f(-1.0f,1.0f,-1.0f);
303         glVertex3f(-1.0f,1.0f,1.0f);
304         glVertex3f(1.0f,1.0f,1.0f);
305
306         glColor3f(1.0f,0.5f,0.0f);
307         glVertex3f(1.0f,-1.0f,1.0f);
308         glVertex3f(-1.0f,-1.0f,1.0f);
309         glVertex3f(-1.0f,-1.0f,-1.0f);
310         glVertex3f(1.0f,-1.0f,-1.0f);
311
312         glColor3f(1.0f,0.0f,0.0f);
313         glVertex3f(1.0f,1.0f,1.0f);
314         glVertex3f(-1.0f,1.0f,1.0f);
315         glVertex3f(-1.0f,-1.0f,1.0f);
316         glVertex3f(1.0f,-1.0f,1.0f);
317
318         glColor3f(1.0f,1.0f,0.0f);
319         glVertex3f(1.0f,-1.0f,-1.0f);
320         glVertex3f(-1.0f,-1.0f,-1.0f);
321         glVertex3f(-1.0f,1.0f,-1.0f);
322         glVertex3f(1.0f,1.0f,-1.0f);
323
324         glColor3f(0.0f,0.0f,1.0f);
325         glVertex3f(-1.0f,1.0f,1.0f);
326         glVertex3f(-1.0f,1.0f,-1.0f);
327         glVertex3f(-1.0f,-1.0f,-1.0f);
328         glVertex3f(-1.0f,-1.0f,1.0f);
329         glEnd();
330 }
331
332 void SunShine(void)
333 {
334
335     GLfloat sun_light_position[]={0.0f,0.0f,0.0f,1.0f};
336     GLfloat sun_light_ambient[]={0.0f,0.0f,0.0f,1.0f};
337     GLfloat sun_light_diffuse[]={1.0f,1.0f,1.0f,1.0f};
338     GLfloat sun_light_specular[]={1.0f,1.0f,1.0f,1.0f};
339
340     glLightfv(GL_LIGHT0,GL_POSITION,sun_light_position);
341     glLightfv(GL_LIGHT0,GL_AMBIENT,sun_light_ambient);
342     glLightfv(GL_LIGHT0,GL_DIFFUSE,sun_light_diffuse);
343     glLightfv(GL_LIGHT0,GL_SPECULAR,sun_light_specular);
344
345     glEnable(GL_LIGHT0);
346     glEnable(GL_LIGHTING);
347     glEnable(GL_DEPTH_TEST);
348 }
时间: 2024-12-08 21:05:48

OpenGL三维与光照的相关文章

OpenGL学习(五) 光照与材质

OpenGL中的光照     环境光:在环境中进行了充分的散射,无法分辨其方向的光. 散射光:来自某个方向. 镜面光:来自一个特定的方向,并且倾向于从表面某个特定的方向反射. 除了以上三种光外,材料可能具有一种发射颜色,它模拟那些源自某个物体的光. 为了实现明暗效果,必须启用光照计算,而且每种光源也必须被启用.对于单个光源,我们可以这样做: glEnable(GL_LIGHTING); glEnable(GL_LIGHT0) 注:一旦光照被启用,glColor*()指定的颜色值将不再使用. 指定

Qt OpenGL三维绘图

简介 OpenGL是为三维绘图提供的标准应用编程接口. OpenGL处理的仅仅是三维绘图方面,而很少或是根本不提供图形用户界面编程方面的支持.OpenGL*应用程序的用户界面必须由其它工具包创建,比如在X平台下的Motif,在Windows平台下的微软基本类库(MFC)——或是在这两种平台下都能使用的Qt. Qt的OpenGL模块使在Qt应用程序中使用OpenGL变的更加容易.它提供了一个OpenGL的部件类,这个部件类除了打开一个OpenGL显示缓冲,利用这个缓冲使用OpenGL应用编程接口来

OpenGL中启用光照前的准备——指定法线

我们在使用光源时,除了强度和颜色之外,还需要指定光源的位置和方向,并且这些光源的位置和方向将会极大地影响场景的外观. OpenGL至少支持8种独立的光源.当我们指定一个光源时,便要告诉OpenGL这个光源的位置以及它的照射方向.光源经常向四周照射,但也可以向一个方向照射.无论在哪种情况下,对于我们所绘制的任何物体,来自任何光源的光线(除了纯粹的环境光源之外)都将根据一个角度撞击组成这个物体的多边形的表面.为了计算围绕多边形表面的着色效果,OpenGL必须能够计算光线与多边形表面之间的角度. 设想

OpenGL中的光照与材料

在OpenGL光照模型中,除非一个物体自己会发光,否则它将受到3种不同类型的光的照射,这3种不同类型的光分别是:环境光(ambient).散射光(diffuse)和镜面光(specular).作为现实世界中光照的抽象,这3种类型的光允许我们模拟和控制光照在物体表面上所产生的效果. 环境光(ambient) 环境光并不来自任何特定的方向.由环境光所照射的物体在所有方向的表面都是均匀照亮的.在OpenGL中,这种光照类型实际上模拟了环境中源自所有光源的散光. 散射光(diffuse) OpenGL中

OPENGL学习笔记——光照

1.隐藏表面消除 隐藏表面消除就是消除实心物体被其他物体所遮挡住的部分,最简单的方法就是使用深度缓冲区. 深度缓冲区的原理是把一个距离观察平面(通常是近侧裁剪平面)的深度值与窗口中的每一个像素相关联.首先使用glClear()函数,把所有像素的深度值设置为最大可能的距离,然后在场景中以任意顺序绘制所有的物体. 深度缓冲区测试可能会影响应用程序的性能,隐藏表面消除丢弃了一些信息,而不是将它们用来绘图,因此会稍稍提高性能,但是深度缓冲区会大大影响性能,用"软件"实现的深度缓冲区(用处理器内

OpenGL中设置光照的镜面反射效果

在上一篇笔记中,我们记述了光线的方向与多边形表面的角度计算关系,除此之外,我们还有光源的位置需要指定.我们在ChangeSize函数的内部指定光源的位置: // 指定光源的位置 GLfloat lightPos[] = {-50.0f, 50.0f, 100.0f, 1.0f}; glLightfv(GL_LIGHT0, GL_POSITION, lightPos); 在此,lightPos数组包含了光源的坐标位置.这个数组的最后一个值是1.0,表示指定的坐标是光源的位置:如果这个数组的最后一个

[OpenGL] 茶壶与光照

OpenGL可以设置至少8种光源,它们的标号为GL_LIGHT0,GL_LIGHT1,GL_LIGHT2--.在这里我们使用了两种光源,一种是环境光,另一种是聚光灯. 在设置光照时,我们需要考虑这样三种光:环境反射光.镜面反射光.漫反射光.在Phong光照模型中,就是通过这三种分量的取值来模拟真实光照的.其中,环境反射光是光源多次反射后的光,可以理解为背景光,镜面反射和漫反射反映了物体表面的粗糙/光滑程度,两者的和是一定的. 在OpenGL中,如果我们想要使用光源,需要输入以下语句开启光照模式:

Linux OpenGL 实践篇-6 光照

经典光照模型 经典光照模型通过单独计算光源成分得到综合光照效果,然后添加到物体表面特定点,这些成分包括:环境光.漫反射光.镜面光. 环境光:是指不是来特定方向的光,在经典光照模型中基本是个常量. 漫反射光:是散射在各个方向上均匀的表面特定光源.物体表面通过光照照亮,即使这个表面没有将光源直接反射到你的眼睛中.漫反射与眼睛的方向没有关系,但与光源的方向有关,当表面直接面向光源的时候会表现的亮一些,而倾斜的时候则暗一些,因为在现实中倾斜的表面接受的光要少一些.在经典光照模型中,我们使用表面的法向量来

基于OpenGL三维软件开发

实验原理: OpenGL在MFC下编程原理---- Windows操作系统对OpenGL的支持 在Windows下用GDI作图必须通过设备上下文(DeviceContext简写DC)调用相应的函数:用OpenGL作图也是类似,OpenGL函数是通过"渲染上下文"(RenderingContext简写RC)完成三维图形的绘制.Windows下的窗口和设备上下文支持"位图格式"(PIXELFORMAT)属性, 和RC有着位图结构上的一致.只要在创建RC时与一个DC建立联