圖像使用2次方是很討厭的問題,不在技術難度上,而在技術妥協上.實際上要求美工作出2次方紋理,并且整張圖的空間利用率要高,是很難的.
當有些策劃丟過來奇奇怪怪的尺寸的圖像,我都要吐血,當知道2n次方限制后,他們把圖像尺寸擴大一下,再丟給我空余大量空白的2n次方紋理,再吐血.
玻璃渣資源里標準的2n次方人物紋理,圖像擠的滿滿的,每個身體部位紋理還是一個矩形,利用率之高不得不令人佩服,然而這對美工要求是極高的.
1024*768的圖像是要拆成4*3的256*256圖像的,而不是一整大張紋理,因為768不是2的n次方,更不要擴大為1024*1024,加大25%的內存.
還有Wow里Loading界面的圖像都壓成512*512,因為Loading圖像模糊一點不要緊,很簡單卻都是很重要的細節.
所以當Wow運行在我Geforce2的顯卡上時,我覺的很cool.
Nvidia的驅動程序也很討厭,實際Geforce6顯卡才支持non power of two texture,Geforce 5200級的顯卡,在硬件能力上不足以支持NPOT,但是最新的驅動程序使用了軟件模式進行模擬支持,而軟件模擬根本毫無實用價值,渲染變得超級緩慢,因為驅動程序每次紋理渲染都會很聰明地把非2次方尺寸圖像自動Scale到2次方尺寸,對于一個800*600的圖像,驅動程序在這個步驟就吃光了CPU.
所以總有些人喊著為什么OpenGL沒有軟件渲染支持,DX很體貼都有(實際上DX也沒有,比如那個所謂的8層紋理),而我認為如果軟件渲染能解決問題,那要硬件作什么!不能解決問題的方案我們支持它作什么!
// OpenGL動態執行2n次方圖像限制
inline int next_p2(int a)
{
?int rval=1;
?while(rval<a) rval<<=1;
?return rval;
}
int nWidthPowerOfTwo = next_p2(tex.nWidth);
int nHeightPowerOfTwo = next_p2(tex.nHeight);
if(tex.nWidth == nWidthPowerOfTwo? &&? tex.nHeight == nHeightPowerOfTwo)
{?
?glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, nWidthPowerOfTwo, nHeightPowerOfTwo, 0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData());
?tex.fScaleX = tex.fScaleY = 1.0f;
}?
else
{?
?glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, nWidthPowerOfTwo, nHeightPowerOfTwo, 0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, NULL);
?glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tex.nWidth, tex.nHeight, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData());
?tex.fScaleX = (float)tex.nWidth / (float)nWidthPowerOfTwo;
?tex.fScaleY = (float)tex.nHeight/ (float)nHeightPowerOfTwo;
}
然而對這個問題,正確的解決方案是事先規劃,強制執行,be clever.