2009-07-26 97 views
1

任何人都可以告訴我如何使用硬件內存在OpenGL中創建紋理?目前我以窗口模式運行我的遊戲,是否需要切換到全屏才能使用硬件?如何在GPU內創建紋理

如果我可以在硬件中創建紋理,是否有限制沒有紋理(硬件內存除外)?然後如何將我的紋理緩存到硬件中?謝謝。

+0

是否要創建紋理對象或紋理數據? – 2009-07-26 15:11:13

+0

嘿,我的意思是有沒有辦法在GPU中緩存紋理數據,而不是在我們需要繪製時發送紋理的所有數據? – Morpheus 2009-07-26 17:09:58

回答

1

通常,當您談論在GPU上生成紋理時,實際上並未創建紋理圖像並將其應用爲普通紋理。更簡單和更常見的方法是使用片段着色器爲每個單幀從頭開始實時計算每個像素的顏色。
典型的例子是在一個物體的表面產生一個Mandelbrot圖案,比如一個茶壺。茶壺由應用程序渲染其多邊形和紋理座標。在渲染管線的某個階段,茶壺的每個像素都會穿過片段着色器,這是應用程序發送給GPU的一個小程序。片段着色器讀取2D紋理座標並計算2D座標的Mandelbrot設置顏色並將其應用於像素。

全屏模式與它無關。即使處於窗口模式,您也可以使用着色器並生成紋理。正如我所提到的那樣,您創建的紋理實際上並不佔用紋理內存中的空間,它們是隨時創建的。人們可能會想到一種方法來捕獲和緩存生成的紋理,但這可能有點複雜,需要多次渲染。

如果您在Google中查找「GLSL」 - 您可以瞭解更多關於它的信息 - OpenGL着色語言。
This somewhat dated tutorial顯示瞭如何創建繪製Mandelbrot集的簡單片段着色器(第4頁)。
如果您可以親手使用「OpenGL Shading Language,2nd Edition」這本書,您會發現它包含了一些關於通過外部3D Perlin噪聲紋理生成天空,火焰和木材紋理的簡單示例應用程序。

3

這應該被幾乎所有的OpenGL紋理教程所覆蓋。例如here,here和。

對於每個紋理,您首先需要紋理名稱。紋理名稱就像是單個紋理的唯一索引。每個名稱都指向一個可以有自己的參數,數據等的紋理對象。glGenTextures用於獲取新名稱。我不知道除了範圍之外是否還有任何限制(2^32)。如果有的話,你可能會得到0的所有新的紋理名稱(和gl錯誤)。

下一步是綁定您的紋理(請參閱glBindTexture)。之後,所有使用或影響紋理的操作都將使用您用作glBindTexture參數的紋理名稱指定的紋理。您現在可以設置紋理的參數(glTexParameter),並上傳紋理數據(對於2D紋理)glTexImage2D。調用glTexImage後,您還可以使用紋理數據釋放系統內存。

對於靜態紋理,所有這些只需要完成一次。如果你想使用紋理,你只需要再次綁定它並啓用紋理(glEnable(GL_TEXTURE_2D))。

單個紋理的大小(寬度/高度)受GL_MAX_TEXTURE_SIZE限制。這通常是4096,8192或16384.它也受限於可用的圖形內存,因爲它必須與幀緩衝區或頂點緩衝區等其他資源一起放入它中。所有紋理一起可以大於可用內存,但它們將被交換。

在大多數情況下,圖形驅動程序應該決定哪些紋理存儲在系統內存中,哪些紋理存儲在圖形內存中。但是,您可以使用glPrioritizeTextures或glTexParameter爲某些紋理賦予更高的優先級。

編輯: 我不會過多擔心存儲紋理的位置,因爲驅動程序通常在這方面做得非常好。經常使用的紋理也更可能存儲在圖形內存中。如果你設置了一個優先級,這對驅動程序來說只是紋理留在顯卡上的重要性。優先級也可能完全被忽略。您還可以使用glAreTexturesResident來檢查當前紋理的位置。

1

要在GPU上創建紋理,請查看「渲染到紋理」教程。有兩種常用方法:將PBuffer上下文綁定爲紋理,或者使用幀緩衝區對象。 PBuffer渲染紋理是舊方法,並有更廣泛的支持。幀緩衝區對象更易於使用。

此外,您不必切換到「全屏」模式的OpenGL硬件加速。事實上,OpenGL根本不知道Windows。全屏幕OpenGL窗口就是這樣的:所有其他窗口頂部的頂層窗口沒有裝飾和輸入焦點被抓取。一些驅動程序繞過窗口遮罩和剪切代碼,如果具有活動OpenGL上下文的窗口覆蓋整個屏幕,則採用更簡單,更快的緩衝區交換方法,從而獲得一些性能,但是與當前的硬件和軟件相比,該效果非常小以其他影響。