可能有一些庫已經存在用於創建紋理地圖集(最佳包裝是一個非平凡的問題)並將舊的紋理座標轉換爲新的紋理圖集。
但是,如果你想自己做,你可能會做這樣的事情:
- 從磁盤加載所有紋理(你的「源PNG」),以及獲取原始像素數據緩衝區,
- 如果有必要,所有源紋理轉換成相同的像素格式,
- 創建一個新的紋理大到足以容納所有現有的紋理,具有相應的緩衝沿着容納像素數據
- 「位圖傳送」的像素從數據將源圖像放入新的緩衝區中n偏移量(請參見下文)
- 使用新緩衝區的數據照常創建紋理。
- 這樣做時,確定從「舊」紋理座標到「新」紋理座標的映射(應該是爲紋理圖集的每個元素記錄偏移量並進行快速轉換)。在像素着色器中執行它可能也很容易,但是需要進行一些分析以查看傳遞額外參數的開銷是否值得。
顯然,你還需要檢查,以確保你是不是做一些愚蠢像加載相同的紋理成冊的兩倍,但是這是一個關注,就是這個過程之外。
要「位圖傳送」從原始圖像(複印件)你會做這樣的事情的目標圖像(假設你拷貝一個128×128的紋理成512x512的圖冊的質感,從(128,0 )目標):
unsigned char* source = new unsigned char[ 128 * 128 * 4 ]; // in reality, comes from your texture loader
unsigned char* target = new unsigned char[ 512 * 512 * 4 ];
int targetX = 128;
int targetY = 0;
for(int sourceY = 0; sourceY < 128; ++sourceY) {
for(int sourceX = 0; sourceX < 128; ++sourceX) {
int from = (sourceY * 128 * 4) + (sourceX * 4); // 4 bytes per pixel (assuming RGBA)
int to = ((targetY + sourceY) * 512 * 4) + ((targetX + sourceX) * 4); // same format as source
for(int channel = 0; channel < 4; ++channel) {
target[to + channel] = source[from + channel];
}
}
}
這是一個非常簡單的蠻力實現:有更快,更簡潔,更巧妙的方法來複制一個數組,但這個想法是,你基本上是複製的內容在給定的X和Y偏移量處將源紋理轉換爲目標紋理。最後,您將創建一個包含其中的舊紋理的新紋理。
如果索引數學對您沒有意義,請考慮how a 2D array is actually indexed inside a 1D space(如計算機內存)。
請原諒任何錯誤。這不是生產代碼,而是我編寫而不檢查其編譯或運行的東西。
由於您使用SDL,我應該指出,它有一個很好的功能,可能是能夠幫助你:SDL_BlitSurface
。您可以在SDL中完全創建SDL_Surface
,並簡單地使用SDL_BlitSurface
將源表面複製到它,然後convert the atlas surface into a GL texture。
它會照顧所有的數學,並且還可以爲你動態地進行格式轉換。
_many_有多少?我更擔心重用現有紋理 - 引擎是否處理這個問題? – 2012-03-28 04:07:13
我認爲最多我會有100個不同的紋理在任何時候,所以這將是100綁定操作。另外,當你說重複使用現有的紋理,你的意思是,如果我有一個使用12次的特定瓦片,引擎應該繪製它12次,而只綁定一次,而不是重新綁定?這將是一個好主意..任何方式來檢查哪些紋理當前綁定,所以我不重新綁定它?或者我必須建立一個系統來繪製相同的紋理,所以我減少了綁定......但是如果我想按照特定的順序繪製它們以進行深度排序呢? – 2012-03-28 04:35:17
是的,對 - 保存綁定。第二個評論更多的是針對具有相同數據的紋理,忘記了這一點。 – 2012-03-28 05:17:59