OpenGL驱动的陷阱:ATI篇
在下一版的KlayGE中,D3D9插件光榮退休,OpenGL插件將要取代它在WinXP下 的位置。眾所周知,ATI的OpenGL驅動一直毛病眾多。因此解決OpenGL插件在ATI卡上出現的錯誤成了當務之急。本文就討論一下在增強 OpenGL插件的過程中遇到的陷阱及其解決方法。測試的顯卡為HD5870,所有問題在9.12-10.10的驅動中都會出現。
glBlitFramebufferEXT
在以前的版本里,OpenGL插件在ATI顯卡上的文字顯示總是亂碼。一開始懷疑是vbo或者shader造成的,最后定位在texture本身。在texture的局部拷貝過程中,OpenGL插件用的是GL_EXT_framebuffer_blit擴展的glBlitFramebufferEXT。ATI驅動對GL_EXT_framebuffer_blit的支持似乎并不完善,結果是雖然什么錯誤都沒發生,但拿目標texture來使用的時候總是一團亂麻,如下圖所示:
如果這個時候用glGetTexImage獲取texture數據,卻又是正確的。繞開這個問題的方法就是用pbo把源texture和目標 texture都map出來,然后memcopy;或者更傳統的gluScaleImage。此問題修好之后,所有例子的文字顯示在ATI卡上恢復了正 常:
glClearBufferfi/glClearBufferfv/glClearBufferiv
在一些例子,比如Parallax中,出現了畫面空白的現象。clear color buffer能起作用,但depth/stencil buffer卻沒有被正確地清除。在支持OpenGL3及以上的情況下,OpenGL插件會默認調用glClearBuffer*的函數來直接清除 buffer,而不用傳統的方法:先調用glClearColor,glClearDepth,glClearStencil設置清除的值,然后調用 glClear來完成清除的工作。在ATI卡上,似乎glClearBufferfi/glClearBufferfv/glClearBufferiv 這些用來清除depth/stencil的函數并沒有起作用。解決方法只能是退回到傳統的Clear方法。
這么做之后,絕大部分例子都能正常渲染了:
glBeginConditionalRender
Deferred shading的例子用query conditional來判斷一個光源是否可見。原先的版本在ATI卡上一執行就發生系統死鎖,必須強制冷啟動才能解決,破壞性極大,而且完全沒有機會調試。(難道是因為query conditional是NV提出來的緣故?)一次湊巧看了http://www.g-truc.net/post-0318.html,確定就是因為query conditional造成了死鎖。
把相關語句繞開之后Deferred shading恢復正常了。
GLSL
GLSL的問題其實不能算是陷阱,但值得關注。ATI驅動的GLSL編譯器可謂中規中矩,符合GLSL標準的shader一般沒啥問題,但不符合標 準的會死得很難看。NVIDIA的GLSL編譯器則大不相同,兼容很多NV自己的“擴展”,比如支持數組的varying。所以其實在ATI卡上能工作的 GLSL基本也能在NV的卡上工作。如果你希望你的GLSL可以在ATI平臺上跑,我的推薦是用AMD GPU ShaderAnalyzer測試一下(GPU ShaderAnalyzer是個純軟件的分析器,在NV的平臺上也能運行)。如果GLSL有問題,就會立刻顯現出來。
經過一系列的嘗試,Cg到GLSL的轉化終于可以在ATI平臺上順利執行,包括Geometry shader:
以上就是我在KlayGE中遇到的ATI OpenGL驅動陷阱。希望對大家以后遇到的問題有所幫助。
轉自http://www.klayge.org
KlayGE游戲引擎
總結
以上是生活随笔為你收集整理的OpenGL驱动的陷阱:ATI篇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 特种兵归来之绝地营救(电视剧绝地营救完整
- 下一篇: 奶油胶手机壳多久能干