2011-07-01 82 views
14

由於今天的卡片似乎保留了渲染命令列表,並且只在調用glFlushglFinish時才刷新,是否真的需要雙緩衝?我在Linux上開發的OpenGL遊戲(ATI Mobility radeon卡)與SDL/OpenGL實際上閃爍較少,當SDL_GL_swapbuffers()被替換爲glFinish()SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,0)在init代碼中時。這是我的卡片的特殊情況還是所有卡片上都有這種情況?是否需要雙緩衝

編輯:我發現原因是KWin。看起來像datenwolf說的那樣,沒有同步的合成是原因。當我關閉KWin合成時,遊戲無需任何源代碼補丁即可正常工作

回答

19

雙緩衝和glFinish是兩個非常不同的東西。

glFinish會阻止程序,直到所有繪圖操作完成。

雙緩衝用於隱藏用戶的渲染過程。如果沒有雙緩衝,假設顯示刷新頻率無限高,則每個繪圖操作都將立即可見。在實踐中,你會得到一些顯示僞像,例如場景的一部分在一種狀態下可見,其餘部分不可見或在其他某種狀態下,圖像可能不完整等。雙緩衝通過首先渲染到後臺緩衝區中避免這種情況,並且只有在渲染完成後,將其與前端緩衝區交換後纔會發送到顯示設備。

現在合成窗口管理變得流行:Windows具有Aero,MacOS X Quartz Extreme,並且在Linux上至少Unity和GNOME3 shell使用合成(如果可用)。重點是:合成在技術上創建doublebuffering:Windows繪製到屏幕外的緩衝區,其中最後的屏幕是合成的。所以,如果你在一臺合成機器上運行,那麼如果在你的程序中執行雙緩衝,那麼它就是多餘的,並且它只需要某種同步機制來告訴合成器下一幀何時準備就緒。 MacOS X有這個。 X11仍然缺乏一個適當的同步方案,看到這個帖子上的maillist:http://lists.freedesktop.org/archives/xorg/2004-May/000607.html

TL; DR:雙緩衝和glFinish是不同的東西,你需要雙緩衝(某種形式的)來使事情看起來不錯。

+0

提到的帖子已超過6歲。 X11是否還缺少同步方案?那麼Windows呢? –

+3

除了datenwolf的解釋,你應該注意到你通常不會調用'glFlush'或'glFinish',除非在一些非常非常罕見的特殊情況下。 'glFinish'什麼也不做('wgl | glx)SwapBuffers'沒有做過(假設vsync被啓用),'glFlush'只刷新排隊的命令並且告訴服務器開始處理它們,這在最好的情況(但是是無用的調用和上下文切換),並且在最壞的情況下導致更差的性能(由於GPU資源的次優調度)。 – Damon

+1

理想情況下,您會希望儘可能多地在GL上執行命令,並儘可能擴展依賴關係(例如,如果使用紋理,首先發送命令來定義紋理圖像,設置紋理狀態等,然後發送一些執行其他操作的命令,然後只繪製使用此紋理的東西)。這可以確保:a)由於依賴關係,命令流中的命令不太可能被阻止; b)如果隊列中的命令停頓,驅動程序可以安排其他一些命令來利用GPU(OpenCL或其他程序?)。 – Damon

2

我認爲它與你的渲染或硬件有關的東西比任何可能泛化爲不在你機器上的東西都要多。所以不:不要試圖做到這一點。

哦,別忘了multisampling。許多實現僅對後臺緩衝區進行多重採樣;前端緩衝區不是多重採樣的。進行交換將從多采樣緩衝區下采樣。