在下一版的klayge中,d3d9外掛程式光榮退休,opengl外掛程式將要取代它在winxp下 的位置。眾所周知,ati的opengl驅動一直毛病眾多。因此解決opengl外掛程式在ati卡上出現的錯誤成了當務之急。本文就討論一下在增強 opengl外掛程式的過程中遇到的陷阱及其解決方法。測試的顯示卡為hd5870,所有問題在9.12-10.10的驅動中都會出現。
在以前的版本裡,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卡上恢復了正 常:
在一些例子,比如parallax中,出現了畫面空白的現象。clear color buffer能起作用,但depth/stencil buffer卻沒有被正確地清除。在支援opengl3及以上的情況下,opengl外掛程式會預設呼叫glclearbuffer*的函式來直接清除 buffer,而不用傳統的方法:先呼叫glclearcolor,glcleardepth,glclearstencil設定清除的值,然後呼叫 glclear來完成清除的工作。在ati卡上,似乎glclearbufferfi/glclearbufferfv/glclearbufferiv 這些用來清除depth/stencil的函式並沒有起作用。解決方法只能是退回到傳統的clear方法。
這麼做之後,絕大部分例子都能正常渲染了:
deferred shading的例子用query conditional來判斷乙個光源是否可見。原先的版本在ati卡上一執行就發生系統死鎖,必須強制冷啟動才能解決,破壞性極大,而且完全沒有機會除錯。(難道是因為query conditional是nv提出來的緣故?)一次湊巧看了確定就是因為query conditional造成了死鎖。
把相關語句繞開之後deferred shading恢復正常了。
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驅動陷阱。希望對大家以後遇到的問題有所幫助。
**
HAL驅動的串列埠程式設計陷阱
手上有塊nucleo stm32l053x板子,用來做串列埠實驗,看了下st的最新庫hal驅動,於是想用hal驅動來做串列埠。使用過程中發現只能傳送資料不能接收資料,用邏輯分析儀檢視rx,tx引角,都有資料,但就是收不到資料。使用stm32f103傳統驅動,一點問題沒有,改到hal怎麼就不行了呢?經...
去掉ATI顯示卡驅動在桌面留下的右鍵選單
剛買筆記本時我就乾掉了ati的選單 具體怎麼弄的不記得了 最近更新了一下顯示卡驅動,結果又出來一堆東西,托盤圖示和快捷鍵可以在選項設定裡去掉,但桌面右鍵選單沒地方弄,於是上網查了下,解決辦法是執行cmd命令列 win7下可能要用管理員許可權執行 regsvr32 u atiacmxx.dll dll...
C陷阱篇之define的缺陷
define存在一些先天不足。在以下情形下要格外小心 避免巨集引數中的 與 操作。帶引數的巨集定義形式上與函式很接近,程式設計師呼叫時有時會把它們視為等價。但實際define定義的偽函式相比真正函式有一些使用限制,比如 define max a,b a b a b 看上去是想得到兩個數中較大的 vo...