- 浏览: 16534 次
最新评论
3D 游戏为什么选择OpenGL
- 博客分类:
- 技术杂绘
3D 游戏为什么选择OpenGL
2011年03月28日
对于3d 图形程序员,看到了这个标题,可能想到了硝烟弥漫的API大战… 首先声明,这篇文章并不参战,当然也不希望任何人利用本文的观点作为API战争的佐证,本文是要客观的阐述OpenGL 足以实现现代游戏的3d图形表现需要,而不是要贬低其它的API,比如Direct3D,当然本文的读者也不仅限于3d 图形程序员,也可以作为项目制作人选择什么API的一个参考。
如题所言,使用OpenGL制做3D游戏,当然,这不是说一定就直接使用OpenGL API来开发游戏;采用基于OpenGL的Graphics Engine来制作游戏,也包含在这个话题的范畴之内;可以理解为使用OpenGL API制作小型3d图形应用,或者采用基于OpenGL的Graphics Engine 来制作大型的图形应用;
下面就几个方面来说明选择OpenGL 的理由
1.跨平台
这个理由充足么?MS Windows 占据了多数PC用户,但是其它平台用户不应该忽视吧?如Linux,mac; 即便从商业角度来考虑,也不应该主动放弃阵地的。或者你会说,你的游戏只运行在MS Windows 平台,但是我要说,还是要用发展的眼光来看问题,现在的断言不一定永远都成立;举一个很现实的例子来说明这个问题,Windows 6(vista,2008,windows 7 )以后的版本都自己封杀了DX10,DX11,这意味着,DX10的游戏要想运行于WinXP,必须采用DX9 另实现,其实DX10,DX11 有很多的地方无法和DX9对应起来,这必然增大开发得复杂性和成本;然而如果采用OpenGL2.0 或者OpenGL 3.0都没有这个问题;它对任何平台都是一视同仁的,没有强行的拒绝任何系统,OpenGL拒绝的只是霸权主义,强jia(n)用户;这里可以看到,即便只做Windows 程序,DirectX都会难以跨自家的平台…
2.天生支持多核心
次时代游戏,一个非常热火的字眼,多线程渲染就是次时代的重要标志之一;OpenGL诞生伊始,就是针对高性能并行图形工作站而设计的,所以它天生支持多核心系统;而Direct3D 生来就是面向PC用户.根本就没有考虑多核心问题;这里说的多核心是CPU多核,而不是GPU多核;
OpenGL 采用TLS( Thread Local Storage,线程局部存储 )技术实现渲染线程的RenderContext,TLS,对于经常做多线程性能优化的程序员来说,应该非常的熟悉,它意味着互斥访问的零开销;它用的是独立的copy来实现共享资源的访问。
#define _declspec(thread) _THREAD_LOCAL_STORAGE
struct SRenderState
struct SRenderContext
{
SRenderState rs;// render state of this render context
}
struct SRenderTSD
{
SRenderContext* rc;//current render context of this thread
SRenderContext* rc_list;//all of render context of this thread
};
_THREAD_LOCAL_STORAGE SRenderTSD * _render_tsd;
从上面伪结构来看每个渲染线程可以有一个独立的_render_tsd 的copy,虽然你只定义了一个,但是每当有一个线程运行的时候,都有一份独立的copy;意味着每个线程的rc都是没有访问冲突的;既然rc没有访问冲突,那么每个rc的state_block也是独立的;
即便在多核心cpu上并发的执行set_state,也没有任何问题,因为set_state通过上面的_render_tsd来访问自己私有的state block;
假如一个并发的多线程如下所示:
Thread1 RC1 Thread2 RC2
//操作RC1 //操作RC2
SetState() SetState()
//采用RC1.state绘制 //采用RC2.state绘制
DrawPrimitive() DrawPrimitive()
… …
从上面看到,上面两个执行序列在多核心上任何时刻被打断都不会出现问题,因为它工作在各自独立的state block上。
另外不同线程的OpenGL渲染资源(纹理,显示列表,VB)是可以全局共享的,可以保证最大的利用率.
这里是否可以说明OpenGL 架构的天生优越性呢?Direct3D11以前的版本是都不行的;如果用Device来代表RenderContext,可以保证状态独立性,但无法实现资源共享;同一个device又只能使用一个state,面临着这样的尴尬境地:共享资源,就不能状态独立;状态独立,就不能共享资源;
到了Direct3D11 终于出现了RenderContext接口,才解决了这个问题。遗憾的是,在我写这篇文章之时,DirectX11 还没有正式发布,仅仅还是Preview 版本;在我设计的引擎中试图采用一些hack手段来改造Direct3D 9 来实现Render Context,后来也放弃了,因为DirectX11 已经意识到了这个问题,并且把它实现了,我没必要费这个力气了,用Direct3D11对应就好了。
3.天生支持多流
对于VertexStream,OpenGL是天生支持多流的;glVertexPointer,glNormalPointer,glTexcoordPointer…等等一系列API就是用来设置流的;Direct3D的FVF很令人讨厌;连MS自己都讨厌它,后来演变出了VertexDeclaration接口…那一堆罗里八索的declaration还是令我欲吐不已。
多流有什么好处?实时改写很高效。比如,修改Normal array,不必把Position,Texcoord,一起unmap…
当然对于只读的vertexbuffer,单流性能最好… 单流,就是跨距顶点格式,访问具有良好的局部性,所以提高了性能;不过,OpenGL 天生支持多流,并不是说它不支持单流,
用同样的api仍然很容易很简洁的实现跨距顶点格式。
4.多视图
多视图问题对于CAD开发者应该很感兴趣;我做过一些调研,大家使用OpenGL做多视图,通常使用这样的方案:在主线程创建所有视图的RenderContext,然后再渲染每个视图之前要执行MakeCurrentContext 操作;并且抱怨MakeCurrentContext 操作的开销很大。这里要说明的是,如果这样做,说明你真的还处在没有入门的阶段;使用OpenGL一定要有线程的概念:RenderContext是属于线程的;
让每个视图都有一个独立的线程,每个渲染线程都有独立的RenderContext,并且使用wglShareLists在不同线程间共享资源,也许你会觉得很麻烦,但是这的确是最佳的办法。
通常多视图都是子窗口,如果多个视图让子窗口在不同线程创建,会导致线程必须自己来处理消息队列,因为消息队列也是线程拥有的东西,并且还要调用AttachInput来给线程获得输入。
另一种思路是让渲染管线和视图相分离,就是采用离屏渲染的方法,让每个视图的渲染流程渲染到离屏的FBO中,在把FBO blit到视图窗口的显示区域。这样离屏渲染放在独立的线程中,而所有视图仍然在同一线程中,这样就解决了消息处理的麻烦问题,同时又实现了多线程并发渲染;
还有一个问题,如何把同时Present 所有的视图?熟悉Direct3D的程序员都知道使用SwapChain,但是OpenGL中的SwapBuffers,或者wglSwapBuffer仍然是一个和RC相关的API,就说此线程的SwapBuffer不能呈现彼线程的渲染视图,即便采用了ShareList来共享fbo也不成。它的实现就是不让你跨线程执行Swap。这也是ms实现的一个蹩脚之处。这个问题困扰了我许久。。。后来我意外之中发现了wglSwapMultipleBuffer 这个API,MS 对这个API的支持非常低调,只在wingdi.h中有寥寥数行声明而已,没有任何文档和注释。。。(真的很想骂ms…)
//wingdi.h
#if (WINVER >= 0x0500)
typedef struct _WGLSWAP
{
HDC hdc;
UINT uiFlags;
} WGLSWAP, *PWGLSWAP, FAR *LPWGLSWAP;
#define WGL_SWAPMULTIPLE_MAX 16
WINGDIAPI DWORD WINAPI wglSwapMultipleBuffers(UINT, CONST WGLSWAP *);
#endif // (WINVER >= 0x0500)
网上没有任何解释,不信你google一下这个api,寥寥无几。
我也只知道uiFlags设置非0表示可以翻转呈现,其他的细节只有ms自己知道了。而且只支持WINVER >= 0x0500的系统,就是说win2k/xp以下的系统不支持这个api,比如win95/98/nt
5.可编程管线
GPU编程今年来如火如荼,和多核环境一样,这也是3d图形编程的重大变化之一。Dx9时代的N6800芯片率先完整实现SHADER MODEL 3,标志着3d 图形编程进入次时代第一阶段。
OpenGL 2.0最初由3dlabs执掌帅印,GLSL1.0的推出,3dslabs功不可没,只是不知怎么就悄悄地被knronos给取代了。看起来knronos雷厉风行,但是雷声大雨点小。。。没有什么实质性的进展。
OpenGL 2.0 中的可编程管线支持Pixel shader,Vertex shader,Geometry Shader,相当于Shader Model 4.
如果从固定功能和可编程功能,以及框架结构对高性能渲染的支持程度来看,OpenGL 是远胜于Direct3D11 以前的任何版本;注意截至本文发布之时,Directx11还是未出生得胎儿,OpenGL 4.0似乎也在酝酿之中,但是看起来有点渺茫,这让我不得不怀疑khronos的实际执行能力了,但愿我怀疑错了。
6.扩展的问题
关于OpenGL 扩展,很多人的一致观点是OpenGL ARB 太官僚,效率太低,不过这的确是个事实。但也不得不承认,慎重的加入新的功能,才能保证质量。另一个观点是OpenGL扩展在不同显卡上支持得程度的不一样,比如 N 卡支持较好,A 卡支持不好。
这里首先要说,Direct3D 的功能也不是在任意显卡上都可以硬件实现,也是依赖硬件实际能力的。另外我个人只偏好 N 卡,A卡上OpenGL效果没怎么见过。但是我坚信一点,如果你只用 ARB 扩展,我相信是相同的。非 ARB 扩展本来就是有差异的。
如果说某一显卡对 ARB 扩展支持的不好,只能说明这款显卡是不合格的,而不能归罪于OpenGL。永远都要记住,OpenGL 只是一套规范而已,某某显卡不符合规范,这不能赖OpenGL吧?
另外,很多人只会用OpenGL 标准功能,而新版本OpenGL 的标准扩展却知之甚少。
而且他总把API版本和硬件OpenGL 版本相混淆,他总会说,MS的OpenGL 只支持1 .21,我如何使用OpenGL 2.0?这两个版本号根本就不是一类,没有可比性。
要使用OpenGL 新功能,推荐大家一定要多上 www.opengl.org这个站点
www.opengl.org/registry 下面的opengl specfiction pdf和那些 opengl extensions 都要看,ARB 开头的扩展是必须要掌握的;
和DirectX8,9,10一样,OpenGL 1.5,2.0,3.0所包含的不仅仅是API中看到的标准功能,也包括A[i][/i]RB标准扩展。
7.可用资源储备量
可用资源,一个是技术资料,包括文档,代码,商业库等等,这一点Direct3D很丰富,OpenGL也不差,大概大家都是轻信了OpenGL 胜过 Direct3D的谣言了,所以Direct3D的可用资源似乎积累的要多一点。
另一种可用资源就是3d用户。和上面的原因一样,很少有人深入的研究它们之间的细微差异,简单的听别人说Direct3D比OpenGL好,就认准了Direct3D了。让我想起了小马过河的故事。。。
最后我想说的是,无论用什么api,或者更退一步说,无论研究什么,自己都要深入的研究一下,才能做出准确的判断,才是对自己负责的一种态度。
发表评论
-
2010年度十大杰出IT博客
2012-01-20 00:55 7452010年度十大杰出IT博客 ... -
Lisp的特性 (评论发不出,只好写一篇新的)
2012-01-20 00:55 625Lisp的特性 (评论发不出,只好写一篇新的) 2011年0 ... -
深入说明HDR技术
2012-01-20 00:55 514深入说明HDR技术 2011年0 ... -
Windows XP的小秘密 {10}
2012-01-19 08:45 742Windows XP的小秘密 {10} 2011年06月03 ... -
Redflag SP3 介绍
2012-01-19 08:45 910Redflag SP3 介绍 2010年07月05日 ... -
MAX三百问(珍藏版)上
2012-01-19 08:45 638MAX三百问(珍藏版)上 2011年06月13日 安装篇 ... -
linux HoN 运行不流畅解决
2012-01-19 08:44 752linux HoN 运行不流畅解决 2011年02月13日 ... -
qtopia-2.2.0移植到ARM上
2012-01-17 01:13 1265qtopia-2.2.0移植到ARM上 2011年03月24 ... -
国产手机小游戏应用
2012-01-17 01:13 1154国产手机小游戏应用 2011年03月08日 我的是金鹏, ... -
常见手机文件格式介绍,涵盖不同地域品牌不同操作系统的文件格式~(
2012-01-17 01:13 1023常见手机文件格式介绍, ... -
vista 系统问题
2012-01-17 01:13 738vista 系统问题 2010年06月04日 Vista ... -
蛾的本本,
2012-01-15 19:53 607蛾的本本, 2012年01月12日 电脑型号 戴尔 ... -
Do it
2012-01-15 19:53 693Do it 2011年12月10日 网站开发工程师 申请 ... -
汽车英语词汇 (2012了 大家抓紧学习)
2012-01-15 19:53 706汽车英语词汇 (2012了 大家抓紧学习) 2012年0 ... -
win7电脑配置
2012-01-15 19:53 681win7电脑配置 2011年12月30日 ------- ... -
答复: [译]Nginx & Comet:低延迟信息推送 | [译]Nginx & Comet:低延迟信息推送
2012-01-11 12:06 695答复: [译]Nginx & Comet:低延迟信息推 ... -
jpa级联操作详解3-级联删除(2)(cascadetype.remove)-sefcertyu-iteye技术网站
2012-01-11 12:06 1217jpa级联操作详解3-级联删除(2)(cascadetype. ... -
Spring 总结04
2012-01-11 12:06 606Spring 总结04 2011年07月01日 Ssh整 ... -
今天又有新的异常出现。。期待我的解决...-有则必不然;无则未必然!-iteye技术网站
2012-01-11 12:06 1069今天又有新的异常出现。。期待我的解决...-有则必不然;无则未 ... -
struts2 adtion 方法的校验(二)基于xml 配置-taink-iteye技术网站
2012-01-11 12:06 658struts2 adtion 方法的校验(二)基于xml 配置 ...
相关推荐
学OpenGL编3D游戏 学OpenGL编3D游戏 学OpenGL编3D游戏 学OpenGL编3D游戏 学OpenGL编3D游戏 学OpenGL编3D游戏 学OpenGL编3D游戏 学OpenGL编3D游戏 学OpenGL编3D游戏 学OpenGL编3D游戏 学OpenGL编3D游戏 学OpenGL编3D...
包括完整源程序和.exe。 A01_OpenGL的程序框架 第1 章源程序 A02_OpenGL的基本图形 第2 章源程序 ...A12_游戏进度保存 第12章源程序 A13_3D场景编辑 第13章源程序 include 公用程序 运行程序 所有运行程序
http://blog.csdn.net/good3651/article/details/53420721 ------- 由浅入深地讲解3D游戏的编制过程,针对OpenGL的程序框架、图形应用、摄像漫游、MD2动画模型、MDL动画模型等高级游戏卡法过程作出了详细地解释。
3D贪食蛇游戏(OpenGL) 3D贪食蛇游戏(OpenGL) Delphi源码
《学OpenGL编3D游戏》是编程系列丛书之一。是以一个完整的3D游戏编写过程,进行程序设计的知识、技术教学。本教程由书和光盘构成。 《学OpenGL编3D游戏》不同于传统的程序设计书籍,它重在游戏的实现方案。以一个...
Android 3D游戏开发技术宝典 OpenGL ES 2.0 android移动开发经典 很清晰完整 内容较大,分成两部分上传 费了我好大功夫的,要一分,评论后会归还的,很划算了
本资源是著名《学OpenGL编3D游戏_CAI》教程配套资源,从0开始教你作出自己的游戏。里面有很好很完善的例子和源码。
基于OpenGL的3D赛车游戏的研究与实现
如题,Android 3D游戏开发技术宝典:OpenGL ES 2.0书中的全部源代码。该书由浅入深的讲解了OpenGL ES 2.0在3D游戏开发中的各个方面,还给出了BN赛艇、火力篮球、夜鹰行动三个经典游戏的全部源代码。
一些OpenGL编写的3D小游戏源代码,供大家参考下!
3d游戏源码,基于opengl,vc++ 3d游戏源码,基于opengl,vc++ 3d游戏源码,基于opengl,vc++
3D贪食蛇游戏(OpenGL)
3D游戏引擎 游戏 3d directx opengl
3D游戏编程:OpenGL入门.pdf
Android 3D游戏开发技术宝典 OpenGL ES 2.0.part1.rar 因为上传权限原因,分两个部分。 影印版,找得不容易啊,厚脸要点积分
学opengl编3d游戏,大量实例源代码,助你早日成为游戏开发高手
每一个都是在前一个的基础上进行开发 OpenGL学习3D游戏编程,OpenGl游戏框架、基本图形、组合图形、显示文字、显示3D模型、MDL、MD2动画模型、射击爆炸、碰撞检测、游戏进度保存、摄影漫游