Revert "Revert "Replace 3D texture in landscape shader by a 2D texture array""

This reverts commit 4a02d3c77b.

This was merged into master even though I only wanted it in stable-7.0.
Oh well, let's just revert it again.
objectmenu
Armin Burgmeier 2016-01-10 20:59:08 -08:00
parent 729712fa2f
commit bb8b933417
4 changed files with 41 additions and 89 deletions

View File

@ -8,7 +8,7 @@ varying vec2 lightTexCoord;
// Input textures
uniform sampler2D landscapeTex[2];
uniform sampler2D scalerTex;
uniform sampler3D materialTex;
uniform sampler2DArray materialTex;
// Resolution of the landscape texture
uniform vec2 resolution;
@ -95,30 +95,31 @@ slice(texture+4)
slice(material)
{
// Get material properties from material map
int matMapIx = f2i(landscapePx.r);
vec4 matMap = queryMatMap(2*matMapIx);
vec4 matMapX = queryMatMap(2*matMapIx+1);
float materialIx = float(f2i(matMap.a)) / 256.0 + 0.5 / materialDepth;
float materialIx = f2i(matMap.a) / 256.0 * materialDepth;
vec3 matEmit = matMap.rgb;
vec3 matSpot = matMapX.rgb * 255.9f / 16.0f;
float matAngle = matMapX.a;
// Query material texture pixels
vec4 materialPx = texture3D(materialTex, vec3(materialCoo, materialIx));
vec4 normalPx = texture3D(materialTex, vec3(materialCoo, materialIx+0.5));
vec4 materialPx = texture(materialTex, vec3(materialCoo, materialIx));
vec4 normalPx = texture(materialTex, vec3(materialCoo, materialIx+0.5 * materialDepth));
// Same for second pixel
int matMapIx2 = f2i(landscapePx2.r);
vec4 matMap2 = queryMatMap(2*matMapIx2);
vec4 matMapX2 = queryMatMap(2*matMapIx2+1);
float materialIx2 = float(f2i(matMap2.a)) / 256.0 + 0.5 / materialDepth;
float materialIx2 = f2i(matMap2.a) / 256.0 * materialDepth;
vec3 matEmit2 = matMap2.rgb;
vec3 matSpot2 = matMapX2.rgb * 255.9f / 16.0f;
float matAngle2 = matMapX2.a;
// Query material texture pixels
vec4 materialPx2 = texture3D(materialTex, vec3(materialCoo, materialIx2));
vec4 normalPx2 = texture3D(materialTex, vec3(materialCoo, materialIx2+0.5));
vec4 materialPx2 = texture(materialTex, vec3(materialCoo, materialIx2));
vec4 normalPx2 = texture(materialTex, vec3(materialCoo, materialIx2+0.5 * materialDepth));
}
slice(normal)

View File

@ -23,7 +23,7 @@
#include "C4Surface.h"
// Shader version
const int C4Shader_Version = 120; // GLSL 1.20 / OpenGL 2.1
const int C4Shader_Version = 130; // GLSL 1.30 / OpenGL 3.0
// Maximum number of texture coordinates
const int C4Shader_MaxTexCoords = 8;

View File

@ -54,7 +54,7 @@ const char *const SEPERATOR_TEXTURE = "--SEP--";
C4LandscapeRenderGL::C4LandscapeRenderGL()
{
ZeroMem(Surfaces, sizeof(Surfaces));
ZeroMem(hMaterialTexture, sizeof(hMaterialTexture));
hMaterialTexture = 0;
hVBO = 0;
}
@ -142,9 +142,8 @@ void C4LandscapeRenderGL::Clear()
delete Surfaces[i];
Surfaces[i] = NULL;
}
glDeleteTextures(C4LR_MipMapCount, hMaterialTexture);
std::fill_n(hMaterialTexture, C4LR_MipMapCount, 0);
if (hMaterialTexture) glDeleteTextures(1, &hMaterialTexture);
hMaterialTexture = 0;
glDeleteBuffers(1, &hVBO);
hVBO = 0;
@ -181,9 +180,7 @@ bool C4LandscapeRenderGL::InitMaterialTexture(C4TextureMap *pTexs)
AddTexturesFromMap(pTexs);
// Determine depth to use
iMaterialTextureDepth = 1;
while(iMaterialTextureDepth < 2*int32_t(MaterialTextureMap.size()))
iMaterialTextureDepth <<= 1;
iMaterialTextureDepth = 2*MaterialTextureMap.size();
int32_t iNormalDepth = iMaterialTextureDepth / 2;
// Find the largest texture
@ -197,15 +194,16 @@ bool C4LandscapeRenderGL::InitMaterialTexture(C4TextureMap *pTexs)
// Get size for our textures. We might be limited by hardware
int iTexWdt = pRefSfc->Wdt, iTexHgt = pRefSfc->Hgt;
GLint iMaxTexSize;
glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &iMaxTexSize);
GLint iMaxTexSize, iMaxTexLayers;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &iMaxTexSize);
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &iMaxTexLayers);
if (iTexWdt > iMaxTexSize || iTexHgt > iMaxTexSize)
{
iTexWdt = std::min(iTexWdt, iMaxTexSize);
iTexHgt = std::min(iTexHgt, iMaxTexSize);
LogF(" gl: Material textures too large, GPU only supports %dx%d! Cropping might occur!", iMaxTexSize, iMaxTexSize);
}
if(iMaterialTextureDepth >= iMaxTexSize)
if(iMaterialTextureDepth >= iMaxTexLayers)
{
LogF(" gl: Too many material textures! GPU only supports 3D texture depth of %d!", iMaxTexSize);
return false;
@ -288,70 +286,33 @@ bool C4LandscapeRenderGL::InitMaterialTexture(C4TextureMap *pTexs)
// Clear error error(s?)
while(glGetError()) {}
// Alloc 3D textures
glEnable(GL_TEXTURE_3D);
glGenTextures(C4LR_MipMapCount, hMaterialTexture);
// Generate textures (mipmaps too!)
// Alloc 2D texture array
glGenTextures(1, &hMaterialTexture);
// Generate textures
int iSizeSum = 0;
BYTE *pLastData = new BYTE [iSize / 4];
for(int iMMLevel = 0; iMMLevel < C4LR_MipMapCount; iMMLevel++)
{
// Scale the texture down for mip-mapping
if(iMMLevel) {
BYTE *pOut = pData;
BYTE *pIn[4] = {
pLastData, pLastData + iBytesPP,
pLastData + iBytesPP * iTexWdt, pLastData + iBytesPP * iTexWdt + iBytesPP
};
for (int i = 0; i < iMaterialTextureDepth; ++i)
for (int y = 0; y < iTexHgt / 2; ++y)
{
for (int x = 0; x < iTexWdt / 2; ++x)
{
for (int j = 0; j < iBytesPP; j++)
{
unsigned int s = 0;
s += *pIn[0]++; s += 3 * *pIn[1]++; s += 3 * *pIn[2]++; s += *pIn[3]++;
*pOut++ = BYTE(s / 8);
}
pIn[0] += iBytesPP; pIn[1] += iBytesPP; pIn[2] += iBytesPP; pIn[3] += iBytesPP;
}
pIn[0] += iBytesPP * iTexWdt; pIn[1] += iBytesPP * iTexWdt;
pIn[2] += iBytesPP * iTexWdt; pIn[3] += iBytesPP * iTexWdt;
}
iTexWdt /= 2; iTexHgt /= 2;
}
// Select texture
glBindTexture(GL_TEXTURE_3D, hMaterialTexture[iMMLevel]);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Select texture
glBindTexture(GL_TEXTURE_2D_ARRAY, hMaterialTexture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// We fully expect to tile these
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// We fully expect to tile these
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_GENERATE_MIPMAP, GL_TRUE);
// Make it happen!
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);
// Make it happen!
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 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);
// Exchange buffers
BYTE *tmp = pLastData;
pLastData = pData;
pData = tmp;
// Statistics
iSizeSum += iTexWdt * iTexHgt * iMaterialTextureDepth * iBytesPP;
}
// Statistics
iSizeSum += iTexWdt * iTexHgt * iMaterialTextureDepth * iBytesPP;
// Dispose of data
delete [] pData;
delete [] pLastData;
glDisable(GL_TEXTURE_3D);
// Check whether we were successful
if(int err = glGetError())
@ -361,10 +322,9 @@ bool C4LandscapeRenderGL::InitMaterialTexture(C4TextureMap *pTexs)
}
// Announce the good news
LogF(" gl: Texturing uses %d slots at %dx%d, %d levels (%d MB total)",
LogF(" gl: Texturing uses %d slots at %dx%d (%d MB total)",
static_cast<int>(MaterialTextureMap.size()),
iMaterialWidth, iMaterialHeight,
C4LR_MipMapCount,
iSizeSum / 1000000);
return true;
@ -1033,13 +993,7 @@ void C4LandscapeRenderGL::Draw(const C4TargetFacet &cgo, const C4FoWRegion *Ligh
}
if(ShaderCall.AllocTexUnit(C4LRU_MaterialTex))
{
// Decide which mip-map level to use
double z = 0.5; int iMM = 0;
while(pGL->Zoom < z * ::Game.C4S.Landscape.MaterialZoom && iMM + 1 <C4LR_MipMapCount)
{ z /= 2; iMM++; }
glBindTexture(GL_TEXTURE_3D, hMaterialTexture[iMM]);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D_ARRAY, hMaterialTexture);
}
if(ShaderCall.AllocTexUnit(C4LRU_MatMapTex))
{

View File

@ -72,9 +72,6 @@ const int C4LR_BytesPerPx = 3;
const int C4LR_BytesPerSurface = 4;
const int C4LR_SurfaceCount = (C4LR_ByteCount + C4LR_BytesPerSurface - 1) / C4LR_BytesPerSurface;
// How many mip-map levels should be used at maximum?
const int C4LR_MipMapCount = 6;
class C4Landscape; class C4TextureMap;
class C4LandscapeRender
@ -123,9 +120,9 @@ private:
// VBO for landscape vertex data
GLuint hVBO;
// 3D texture of material textures
GLuint hMaterialTexture[C4LR_MipMapCount];
// material texture positions in 3D texture
// 2D texture array of material textures
GLuint hMaterialTexture;
// material texture positions in texture array
std::vector<StdCopyStrBuf> MaterialTextureMap;
// depth of material texture in layers
int32_t iMaterialTextureDepth;