2010-09-16 54 views
3

我正在寫一個基於OpenGL的簡單3D引擎(我知道這裏有很多,但由於某些原因我想學習如何自己做這個)。我對目前的場景圖和類似的東西很滿意,但我對紋理處理非常不滿意。所以我想知道如何正確地做到這一點。如何管理紋理

當我看到互聯網上的示例代碼時,他們從不談論如何管理紋理。他們只是在應用程序啓動時加載一些紋理,展示他們的演示內容,然後退出程序。但是如果我經常改變場景中的東西呢?如果我想要顯示具有10個紋理的場景,然後刪除場景中的節點,那麼不再需要2個紋理,然後添加具有4個新紋理的新節點。所以必須從視頻RAM中刪除2箇舊紋理,並且必須添加4個新紋理。然後,我完全替換整個場景,以便再次使用所有未使用的紋理,並且必須加載新紋理,而之前使用過的紋理以及新場景中也使用過的紋理必須重新使用。這聽起來很複雜。

紋理如何在專業3D引擎中管理?它是一個全局的單例紋理管理器,它跟蹤參考計數器的紋理使用情況並不時清理視頻內存?還是有一種更天才的方法來做到這一點?

回答

4

我認爲你需要在這裏實現的是,你正試圖解決的問題並不是紋理特有的,而是你所有的遊戲資源。我認爲最好的解決方案是一個自動化的依賴關係跟蹤方法,並結合參考計數。對於遊戲中您想要的每個「事物」,您應該有某種根文件引用該「事物」使用的所有其他資產(聲音,紋理,模型,粒子效果)。您應該有某種工具或構建腳本來打包每個項目的所有資產。在創建任何「事物」之前,請加載相應的包。你加載的每一件東西都包含了這個包,並且這個包加載了所有加載的資源。一旦引用計數變爲0,您就知道它可以安全地刪除資源或整個pacakges。

這種方法的另一個好處是您可以給自己內存預算,並在構建時檢查它們,而不是運行時間,因爲您知道每個包裝有多大。另外,軟件包可以共享資源,所以如果另一個軟件包已經加載了它,你可以確保不要加載它們一次以上。

3

如果你在C++中實現它,「最簡單」的方法只需要一個可以加載和卸載自己的Texture類。每當一個對象加載時,它也加載它需要的紋理。當該對象消失時,它會銷燬它加載的紋理,從而卸載它們。

C中的解決方案是相似的;你有一個包含足夠數據的結構,當它從vram中取出並釋放它的資源時,可以「卸載」該紋理。

這基本上就是我們在「職業遊戲」上所做的事情,儘管我目前正在對每個世界區域進行研究的系列文件都會提取所需的所有紋理,因此該區域中每個具有相同紋理的對象共享相同的紋理數據。相鄰區域可能具有相同源紋理的對象,但在這種情況下,我們只是讓內存中有兩個副本,因爲管理更容易。

你可能會因引用計數和全局經理而變得棘手,但是你還需要想出一個碎片整理內存的方案等等,這是一個有趣的學術活動,但最終也會導致項目接近完成時會遇到很多麻煩。

+0

一個全球經理參考跟蹤和內存碎片整理是我專業使用的唯一的東西,所以我肯定會說它是一個可行的解決方案。 – BigSandwich 2010-09-19 03:03:19

+0

當然,我只是覺得成本非常高,只有當你有很多人在遊戲中投入大量資產時,價值纔會變得明顯。 – 2010-09-23 18:12:43