OpenGL学习笔记(九)
来源:互联网 发布:mixly软件下载 编辑:程序博客网 时间:2024/05/18 02:35
龙云尧个人博客,转载请注明出处。
CSDN地址:http://blog.csdn.net/michael753951/article/details/71750809
个人blog地址:http://yaoyl.cn/nehexue-xi-bi-ji-jiu/
前言
本次笔记为nehe课程第11课的学习内容,通过实验,我们可以利用正弦函数绘制一个舞动的旗帜。在本次课程中,我们也将学习OpenGL中glPolygonMode函数对一个模型的正面和反面进行不同模式的绘图。
glPolygonMode 函数介绍
本部分内容请先查看前人整理的博客【OpenGL学习笔记(7)多边形绘制】。请先仔细阅读该博客,理解如何区分模型中的正面反面(依然遵守右手定则,由描点的方向决定),以及3种填充方式(fill,line point)。
代码分析
好了,到这里新的基本知识就已经讲述完毕了,我们看看作者是如何实现一个舞动的旗帜的。(基本的代码我就不分析了,只挑重点)
InitGL中,在设置完纹理和透视的init之后,我们将插入glPolygonMode方法进行正反不同方式填充(以此从直观上区分正反面)。然后完成45*45个点阵的绘制。
绘制中,作者将45*45个点阵均匀分布到一个长为9个单位,宽为9个单位,并且中点放置在原点上的正方形中(通过-4.5将中点移动到原点)。Z轴上,作者绘制了一个以x为自变量的正弦函数(刚好一个周期,至于为什么需要一个周期,在看完本篇博客之后你将会有答案)。
接下来DrawGLScene开始进行图像旋转。这里我注释掉了作者的沿y轴和z轴旋转,仅仅保留沿x轴旋转,以方便观察。模型绘制和纹理绑定部分我不分析了,已经是很经典的代码了,就是利用45*45个点阵绘制44*44个正方形而已。
接下来就是本此实验的重点了。一个if判断,这个判断实现了旗帜的舞动。
if( wiggle_count == 2 ) { for( y = 0; y < 45; y++ ) { hold=points[0][y][2]; for( x = 0; x < 44; x++) { points[x][y][2] = points[x+1][y][2]; } points[44][y][2]=hold; } wiggle_count = 0; }
仔细阅读代码我们可以发现,作者通过wiggle_count计数,每两帧画面,就将45*45点阵中的z值向左移动一位,最左边的z值放到最右边,实现循环。所以整个if实现的就是将一个正弦波向左移动,这也就是为什么我们在实验中旗帜的挥动,波纹向左走的原因。
剩下的代码就不用怎么解释了,都是和以前一样的代码了。
回到一开始的问题,为什么在设置45*45点阵的z值的时候,要使用2*pi将正弦波控制在一个周期。可不可以乘以n*pi,或者2*n*pi,或者其他值。(提示,if条件中左移的时候,左端点会被移动到右端,此时这个端点有可能是一个突变点造成波形尖锐或者畸形)。
最后附上效果图,首先是作者源代码的运行结果。
然后是经过我注释掉y轴旋转,z轴旋转以及注释掉了整个if判断之后的图像。我们发现这个时候图像已经不能飘动了,而且上下两个边界呈现一种标准的正弦波的形式。
最后是没有注释if,单单注释掉y轴旋转和z轴旋转的图像。喜事已经能够正常的飘动了。
显示列表
nehe教程第12课显示列表。
该课程主要讲解了glGenLists的使用样例。在使用之前,我们可以了解一下使用glGenLists能给你程序性能所带来的好处。这部分只是我们可以参考【OpenGL(八) 显示列表】以及【OpenGL显示列表】
本次课程需要使用的光、材质和光照模型,就比较符合glGenLists的使用环境。
我们来看看课程代码,作者首先定义了两个二位数组,boxcol用来存放立方体除了top之外,其他所有面的5种取,topcol用来存放立方体的顶部颜色。
接下来作者定义了BuildLists方法,在这个方法中,作者使用了本次课程的核心——显示列表。使用方法大致如下。
- 首先调用glGenListst生成一个显示列表(连续地址的数组形式),本次实验中作者生成了包含2个元素的数组,返回数组的首地址给box(不过定义的时候并没有定义成指针,有些奇怪)
- 接着作者使用glNewList和glEndList定义显示列表中的每一个元素。
- 在GLNewList方法中,作者传入了box指向的第一个显示元素,同时传入了一个参数GL_COMPILE。(注意:按照【OpenGL显示列表】中所告诉我们的知识,glNewList的函数原型为
void glNewList(GLuint list,GLenum mode);
说明一个显示列表的开始,其后的OpenGL函数存入显示列表中,直至调用结束表的函数(见下面)。参数list是一个正整数,它标志唯一的显示列表。参数mode的可能值有GL_COMPILE和GL_COMPILE_AND_EXECUTE。若要使后面的函数语句只存入而不执行,则用GL_COMPILE;若要使后面的函数语句存入表中且按瞬时方式执行一次,则用GL_COMPILE_AND_EXECUTE。) - glNewList和glEndList中间定义矩阵的语句我这里就不再分析,和之前一样。
- 在GLNewList方法中,作者传入了box指向的第一个显示元素,同时传入了一个参数GL_COMPILE。(注意:按照【OpenGL显示列表】中所告诉我们的知识,glNewList的函数原型为
- 定义完显示列表中第一个元素之后,定义第二个元素时,需要将数组头指针向后移一位,所以代码中会有
top=box+1;
一行。
接着本次实验中作者修改了InitGL方法,他在Init的最后几行中,调用了3个glEnable方法,打开了GPU默认的灯光(GL_LIGHT0),自定义的灯光(GL_LIGHTING),以及颜色纹理(GL_COLOR_MATERIAL),注意,如果不激活颜色纹理的话,在我们DrawGLScene中,将只能够贴上图片纹理,但是无法再往上添加颜色纹理(即之后的glColor3fv失效)。
DrawGLScene方法中,作者或者了6层,逐渐减少的立方体。使用过程中,作者在定位完画笔,并且旋转坐标轴完成之后,使用glColor3fv将一开始宏定义的颜色作为纹理,然后调用glCallList快速构建矩形。本次实验使用显示列表之后,DrawGLScene代码量明显比以往少了很多。
其他代码就不解释了。本次课程主要掌握显示列表的原理以及使用即可。
最终的显示图像如下所示:
稍微旋转一下图片可以看到如下效果:
我们注释掉glEnable(GL_COLOR_MATERIAL);
或者DrawGLScene中的glColor3fv
方法,就发现显示的图片已经没有颜色纹理了。
- OpenGL学习笔记(九)
- OpenGL学习笔记(九)
- openGL之光照1---openGL学习笔记(九)
- OPENGL学习笔记之九
- OpenGL入门笔记(九)
- OpenGL ES3.0 《学习笔记 九》 Texturing
- OpenGL入门学习(九)
- OpenGL入门学习(九)
- OPENGL学习视频(九)
- OpenGL入门学习(九) 【转】
- OpenGL学习(九)纹理初步
- OpenGL入门学习[九]
- 学习笔记(九)
- 学习OpenGL(九)MFC与OpenGL编程
- 初识openGL---openGL学习笔记(一)
- openGL画线---openGL学习笔记(三)
- OpenGL学习九:视图简介
- opengl 入门学习 随笔九
- ES6 const
- OCP考试经验心得
- ClassUtil
- 手把手教你玩转git
- Qt之图形视图框架
- OpenGL学习笔记(九)
- spring MVC配置详解
- 对makefile和Kconfig的理解
- SDK更新后,重新打开Eclipse时提示错误Location of the Android SDK has not been setup in the preferences
- Redis底层数据结构之跳跃表
- input的type设置成number之后能输入e的解决办法
- Unity优化建议
- 关于用jav的List对象用add方法报空指针错误
- apache转发配置