write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie
讨论新闻组及文件
前段时间因为刚换工作,很多东西都没有步入正轨,因为工作原因,学习了很多其他的东西,比如irrlicht等,现在慢慢缓下来了,还是好好的将OpenGL学习完。呵呵,其实这个系列主要还是自己学习为主,但是选择了一条比较累的写博方式,其实一边学习一般完成NEHE教程的Win32代码就可以了,但是选择了跟随《OpenGL Programming Guide
》的方式,这样会比NEHE学的更详细一些,但是因为自己需要额外打很多字,所以也累了很多。闲话少说,继续学习。
显示列表
显示列表可以提高性能,事实上就像把一对的函数存入OpenGL的缓存中,然后能很快的调用一样,事实上,比普通的函数调用的优点仅在于速度更快,但是却无法更改。甚至包括参数都无法更改。。。。。。。相当于用牺牲灵活性来换取一定的性能。。。。。当然,在对图形程序的性能追求中,牺牲的又何止是灵活性啊。。。。。。可读性,可维护性,扩展性。。。。。都壮烈牺牲过
效率对比
下面具体来看看例子,为了更加具体的表现显示列表对性能的优化,一两个球的绘制是没有办法的,我决定绘制在屏幕上绘制100个球,源代码利用原来文章中的2009-11-9/LightSimple,这样还可以加大动态光照的运算,进一步加大运算量。利用普通函数完成这样的工作,用已有的知识已经没有问题了,代码如下:
void
DrawAll
()
{
glPushMatrix
();
glTranslatef
(-0.9, 0.9, 0.0);
for
(int
i
= 0; i
< 10; ++i
)
{
for
(int
j
= 0; j
< 10; ++j
)
{
glutSolidSphere
(0.1, 30, 16); // r = 1 / 20
glTranslatef
(0.2, 0.0, 0.0);
}
glTranslatef
(-2.0, -0.2, 0.0);
}
glPopMatrix
();
}
代码的含义不解释应该也很清楚,先移到屏幕左上角,每绘制一个球移动一个球的距离,绘制下一个,每10个球绘制后换一行,并且移动到开头,继续绘制。
然后放开fps的限制,加入一段计算fps的代码:
// called every frame
int
CalculateFPS
(DWORD now
)
{
static int
frameCounted
= 0;
static int
startTime
= GetTickCount
();
static int
fps
= 0;
++frameCounted
;
int
elapsed
= now
- startTime
;
if
(elapsed
>= 1500 )
{
fps
= ( 1000 * frameCounted
) / elapsed
;
startTime
= now
;
frameCounted
= 0;
}
return
fps
;
}
为了这里特别写的,假如有什么问题请指出来,含义也很简单,每1500毫秒(一秒半)算一下fps,为什么用1500毫秒,是感觉要是定在1000,好像误差会大点,事实上,这里用的时间越久,误差越小,但是计算的间隔长了,不能及时的反应变化。
对了,为了更好的展示效率,使用了离屏绘制,(双缓冲)不明白的看看第一节。
效果及大概的运行效率如下图所示:
基本上在150~200帧左右。(因为抓屏的瞬间会导致瞬间的fps下降)
我们再看看显示列表的版本:
利用一下几句生成新的显示列表:
giTorus
= glGenLists
(2);
glNewList
(giTorus
, GL_COMPILE
);
glutSolidSphere
(0.1, 30, 16); // r = 1 / 20
glEndList
();
glNewList
(giTorus
+1, GL_COMPILE
);
glPushMatrix
();
glTranslatef
(-0.9, 0.9, 0.0);
for
(int
i
= 0; i
< 10; ++i
)
{
for
(int
j
= 0; j
< 10; ++j
)
{
glCallList
(giTorus
);
glTranslatef
(0.2, 0.0, 0.0);
}
glTranslatef
(-2.0, -0.2, 0.0);
}
glPopMatrix
();
glEndList
();
然后再调用:
glCallList(giTorus+1);
基本上就好了,与一般的OpenGL特性不同的是,显示列表使用上非常简单,但是知道什么时候应该使用,却需要一定的知识和经验,在《OpenGL Programming Guide
》中,甚至有专门的一节《显示列表的设计哲学》来阐述这个。
我们看看效果:
基本上在370~450之间(同样因为抓屏的瞬间会导致瞬间的fps下降)
从fps上来看,效率成倍的增加。这就是显示列表的作用,仅仅这么一个小程序都无法掩盖其强大。。。。。。
使用
显示列表牵涉的API并不算太多,而且很好理解:
《OpenGL Reference Manual
》:
GLuint glGenLists( GLsizei range);
Parameters
range
Specifies the number of contiguous empty display lists
to be generated.
glGenLists返回一个由range指定长度的显示列表起始标记,相当于普通操作的分配内存,返回的第一个内存的指针,glGenLists返回的也是第一个显示列表的标志,但是是以整数值来表示的。
然后,再就是glNewList和glEndList函数对,指示了一个显示列表的开始及结束,具体指示的显示列表由glNewList的第一个参数决定,就像定义一个函数的“{”和“}” 一样。
再然后,就是glCallList用于调用显示列表,就像调用函数一样,用参数指定调用的是哪个显示列表。
giTorus
= glGenLists
(2);
glNewList
(giTorus
, GL_COMPILE
);
glutSolidSphere
(0.1, 30, 16); // r = 1 / 20
glEndList
();
以上的4句已经定义了一个完整的显示列表了,分配,定义,都齐了。GL_COMPILE参数表示仅仅定义,但是不执行。(就像真正的函数第一次定义时那样)
glNewList
(giTorus
+1, GL_COMPILE
);
glPushMatrix
();
glTranslatef
(-0.9, 0.9, 0.0);
for
(int
i
= 0; i
< 10; ++i
)
{
for
(int
j
= 0; j
< 10; ++j
)
{
glCallList
(giTorus
);
glTranslatef
(0.2, 0.0, 0.0);
}
glTranslatef
(-2.0, -0.2, 0.0);
}
glPopMatrix
();
glEndList
();
在上面这几句,更加完整的展示了一个显示列表的操作,不仅定义了一个完整的显示列表,(就是上面那整个屏幕的球)而且在定义显示列表的时候还用“glCallList(giTorus);”调用了刚才定义的显示列表。这也展示了显示列表的可嵌套性。
为节省篇幅仅贴出关键片段,完整源代码见我博客源代码的 2009-12-21/DisplayListTest目录,获取方式见文章最后关于获取博客完整源代码的说明。
完整程序中一个程序实现了上述两种方式,利用gbIsUseDisplayList全局变量控制,需要注意,自然,还有lightsimple中包含变换光照位置的代码。
参考资料
1. 《OpenGL Reference Manual
》,OpenGL参考手册
2. 《OpenGL
编程指南》(《OpenGL Programming Guide
》),Dave Shreiner,Mason Woo,Jackie Neider,Tom Davis
著,徐波译,机械工业出版社
3. 《Nehe OpenGL Tutorials》,Nehe著,在http://nehe.gamedev.net/
上可以找到教程及相关的代码下载,(有PDF版本教程下载)Nehe自己还做了一个面向对象的框架,作为演示程序来说,这样的框架非常合适。也有中文版
,各取所需吧。
完整源代码获取说明
由于篇幅限制,本文一般仅贴出代码的主要关心的部分,代码带工程(或者makefile)完整版(如果有的话)都能用Mercurial在Google Code中下载。文章以博文发表的日期分目录存放,请直接使用Mercurial克隆下库:
https://blog-sample-code.jtianling.googlecode.com/hg/
Mercurial使用方法见《分布式的,新一代版本控制系统Mercurial的介绍及简要入门
》
要是仅仅想浏览全部代码也可以直接到google code上去看,在下面的地址:
http://code.google.com/p/jtianling/source/browse?repo=blog-sample-code
原创文章作者保留版权 转载请注明原作者 并给出链接
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie
分享到:
相关推荐
网上有很多关于创建OPENGL窗口的代码,这里我基于win32框架编写了生成OPENGL窗口的代码,并且代码做了详细的注释,对于初学者很实用。
OpenGL编程指南(红宝书)源码,官方源码.我只是它们配置在vs2008下,直接就能编译运行了.win32下的glu,glut,glew等库都是我一个一个找齐的.弄点辛苦费吧
在win32下结合OpenGL的3D漫游编程代码
为了方便学习OpenGL的同学快速开发编程,也为了省去繁琐的库编译过程,特此将自用的最新版OpenGL依赖库分享给大家。 附件中包含4个文件夹,分别是freeglut(Freeglut 3.0.0 [Released: 7 March 2015]),glew(2.1.0...
WIN32 opengl环境搭建,very good
在Win32 OPENGL环境下采用面向对象的思想,编程实现的导入OBJ文件并显示其模型的代码。
在VC6.0中利用opengl编程绘制八卦图。准备GLUT库 1.下载glut压缩包后,解压,把glut32.dll放在Windows的system32目录下,将glut32.lib放在C:\program files\Microsoft Visual Studio\VC98\Lib目录中,将glut.h放在C:...
win32编程需要 连接基本的 opengl库
使用C++与opengl实现的简易太阳系,开发环境:win7,opengl,c++
OpenGL超级宝典,中文第二版! 本书是一本完整而详尽的关于OpenGL的参考书,全书分为四部分:第一部分“OpenGL导言”介绍3D图形学...本书内容丰富而全面、结构清晰、层次分明,适用于使用OpenGL编程的各个层次的程序员。
opengl时钟代码,vc6.0下win32编程,有定时控制闹铃功能
本书是一本完整而详尽的关于OpenGL的参考书,全书分为四部分:第一部分“OpenGL导言”介绍3D图形学的基本原理,读者将在此学会... 本书内容丰富而全面、结构清晰、层次分明,适用于使用OpenGL编程的各个层次的程序员。
OpenGL编程多数都在win32下,有时候需要在MFC下,本资源给出一个小例子,包括了环境的设置。该例子在VC8下编译通过。
1、基于OpenGL编程,框架为WinGUI 2、开发环境: System: Win10 IDE: Code::Blocks 17.12 Compiler: MinGW Frame: WinGUI 3、实现功能 键盘操作:旋转、平移 鼠标操作:鼠标左键、鼠标中键 菜单操作:主菜单...
本书是OpenGL Architecture Review Board, Mason Woo、 Jackie Neider、Tom Davis 和Dave Shreinre编著的《OpenGL编程指南(第3版)》(Reading, MA: Addison-Wesley, 1999)的姊妹篇。阅读这两本书的前提是你...
win32,opengl,html,sql等的学习资料,自己总结的
C语言纯sdk编程,只使用windows.h和gl.h,便于初学者理解windows下使用opengl的基本过程。渲染场景是一个多色正方体和一个XYZ坐标轴,并包含一个简单的鼠标拖动旋转坐标轴的功能。编译环境:VC++6.0,Windows XP SP3...
最近需要在VS2019的MFC上面画3维图,记录一下配置OpenGL库的过程。下载此文件包,可以直接添加include和lib依赖。 提供所需要的GLAD、GLM、GLEW、Glut,GLFW包。Win64也可以直接使用。 此外附加详细的配置过程:...
QOpenglWindow 和QPainter混合渲染的示例代码,这个在我机器上能够运行,显卡 英伟达 9800Gt win7 64 位系统。
OpenGL核心进行中的OpenGL库旨在为您提供一个强大的沙箱,以供您学习或试验OpenGL和一般的图形编程。用法目前只有“官方”支持Windows-Mac和Linux支持即将推出。 git clone --recursive ...