forked from Mirrors/openclonk
Use power-of-two depth for material 3D texture
Otherwise the addressing using floats will not be entirely exact, maybe leading to some bad implementations trying to interpolate between 3D texture layers. That would be a very hard-to-spot performance hog, therefore let's play it safe in exchange for having to allocate a bit more texture memory.
parent
ffc1463b69
commit
d672211ef5
|
@ -61,23 +61,6 @@ bool C4LandscapeRenderGL::Init(int32_t iWidth, int32_t iHeight, C4TextureMap *pT
|
|||
while(pTexs->GetTexture(iTexCount))
|
||||
iTexCount++;
|
||||
|
||||
// Build material-texture map (depth parameter where to find appropriate texture)
|
||||
for(int pix = 0; pix < 256; pix++)
|
||||
{
|
||||
// Look up indexed entry
|
||||
const C4TexMapEntry *pEntry = pTexs->GetEntry(PixCol2Tex(BYTE(pix)));
|
||||
if(!pEntry->GetTextureName())
|
||||
{
|
||||
// Texture zero is transparent
|
||||
MatTexMap[pix] = 0.5 / iTexCount;
|
||||
continue;
|
||||
}
|
||||
// Assign texture
|
||||
int32_t iTexIndex = pTexs->GetTextureIndex(pEntry->GetTextureName());
|
||||
if(iTexIndex < 0) iTexIndex = 0;
|
||||
MatTexMap[pix] = (float(iTexIndex) + 1.5) / iTexCount;
|
||||
}
|
||||
|
||||
// Build texture, er, texture
|
||||
if (!InitMaterialTexture(pTexs))
|
||||
{
|
||||
|
@ -99,6 +82,23 @@ bool C4LandscapeRenderGL::Init(int32_t iWidth, int32_t iHeight, C4TextureMap *pT
|
|||
return false;
|
||||
}
|
||||
|
||||
// Build material-texture map (depth parameter where to find appropriate texture)
|
||||
for(int pix = 0; pix < 256; pix++)
|
||||
{
|
||||
// Look up indexed entry
|
||||
const C4TexMapEntry *pEntry = pTexs->GetEntry(PixCol2Tex(BYTE(pix)));
|
||||
if(!pEntry->GetTextureName())
|
||||
{
|
||||
// Textures over iTexCount are transparent
|
||||
MatTexMap[pix] = (float(iTexCount) + 0.5) / iMaterialTextureDepth;
|
||||
continue;
|
||||
}
|
||||
// Assign texture
|
||||
int32_t iTexIndex = pTexs->GetTextureIndex(pEntry->GetTextureName());
|
||||
if(iTexIndex < 0) iTexIndex = 0;
|
||||
MatTexMap[pix] = (float(iTexIndex) + 0.5) / iMaterialTextureDepth;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -127,6 +127,13 @@ void C4LandscapeRenderGL::Clear()
|
|||
bool C4LandscapeRenderGL::InitMaterialTexture(C4TextureMap *pTexs)
|
||||
{
|
||||
|
||||
// Determine depth to use. Lowest power of 2 that can contain
|
||||
// all textures plus sky (= empty). Might have more complicated
|
||||
// mappings in future.
|
||||
iMaterialTextureDepth = 1;
|
||||
while(iMaterialTextureDepth < iTexCount + 1)
|
||||
iMaterialTextureDepth <<= 1;
|
||||
|
||||
// Find first (actual) texture
|
||||
int iRefTexIx = 0; C4Texture *pRefTex; CSurface *pRefSfc = NULL;
|
||||
for(; pRefTex = pTexs->GetTexture(pTexs->GetTexture(iRefTexIx)); iRefTexIx++)
|
||||
|
@ -139,13 +146,13 @@ bool C4LandscapeRenderGL::InitMaterialTexture(C4TextureMap *pTexs)
|
|||
int iTexWdt = pRefSfc->Wdt, iTexHgt = pRefSfc->Hgt;
|
||||
const int iBytesPP = pRefSfc->byBytesPP;
|
||||
const int iTexSize = iTexWdt * iTexHgt * iBytesPP;
|
||||
const int iSize = iTexSize * (iTexCount + 1);
|
||||
const int iSize = iTexSize * iMaterialTextureDepth;
|
||||
BYTE *pData = new BYTE [iSize];
|
||||
for(int i = 0; i < iTexCount; i++)
|
||||
for(int i = 0; i < iMaterialTextureDepth; i++)
|
||||
{
|
||||
BYTE *p = pData + i * iTexSize;
|
||||
C4Texture *pTex; CSurface *pSurface;
|
||||
if(!(pTex = pTexs->GetTexture(pTexs->GetTexture(i-1))))
|
||||
if(!(pTex = pTexs->GetTexture(pTexs->GetTexture(i))))
|
||||
{}
|
||||
else if(!(pSurface = pTex->Surface32))
|
||||
{}
|
||||
|
@ -221,7 +228,7 @@ bool C4LandscapeRenderGL::InitMaterialTexture(C4TextureMap *pTexs)
|
|||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
// Make it happen!
|
||||
glTexImage3D(GL_TEXTURE_3D, 0, 4, iTexWdt, iTexHgt, iTexCount + 1, 0, GL_BGRA,
|
||||
glTexImage3D(GL_TEXTURE_3D, 0, 4, iTexWdt, iTexHgt, iMaterialTextureDepth, 0, GL_BGRA,
|
||||
iBytesPP == 2 ? GL_UNSIGNED_SHORT_4_4_4_4_REV : GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
pData);
|
||||
|
||||
|
|
|
@ -76,8 +76,10 @@ private:
|
|||
|
||||
// Texture count
|
||||
int32_t iTexCount;
|
||||
// 3D material textures
|
||||
// 3D texture of material textures
|
||||
GLuint hMaterialTexture[C4LR_MipMapCount];
|
||||
// depth of material texture in layers
|
||||
int32_t iMaterialTextureDepth;
|
||||
// material map
|
||||
GLfloat MatTexMap[256];
|
||||
|
||||
|
|
Loading…
Reference in New Issue