From ece32418e7c1828a65c88e526a5afcb635c5453a Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 31 May 2011 14:35:59 -0500 Subject: SH-1682 Dynamically adjust the number of texture channels to use for indexed texture rendering based on available hardware. --- indra/llrender/llshadermgr.cpp | 129 +++++++++++++++++++++++++++++++++++------ 1 file changed, 111 insertions(+), 18 deletions(-) (limited to 'indra/llrender/llshadermgr.cpp') diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 6fb1e6e437..e51ef8cfe7 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -216,9 +216,13 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) return FALSE; } } - else if (!shader->attachObject("lighting/lightWaterF.glsl")) + else { - return FALSE; + if (!shader->attachObject("lighting/lightWaterF.glsl")) + { + return FALSE; + } + shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1; } } @@ -231,9 +235,13 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) return FALSE; } } - else if (!shader->attachObject("lighting/lightF.glsl")) + else { - return FALSE; + if (!shader->attachObject("lighting/lightF.glsl")) + { + return FALSE; + } + shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1; } } } @@ -251,9 +259,13 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) return FALSE; } } - else if (!shader->attachObject("lighting/lightFullbrightShinyWaterF.glsl")) + else { - return FALSE; + if (!shader->attachObject("lighting/lightFullbrightShinyWaterF.glsl")) + { + return FALSE; + } + shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1; } } else if (features->hasWaterFog) @@ -265,9 +277,13 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) return FALSE; } } - else if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl")) + else { - return FALSE; + if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl")) + { + return FALSE; + } + shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1; } } @@ -280,9 +296,13 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) return FALSE; } } - else if (!shader->attachObject("lighting/lightFullbrightShinyF.glsl")) + else { - return FALSE; + if (!shader->attachObject("lighting/lightFullbrightShinyF.glsl")) + { + return FALSE; + } + shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1; } } @@ -295,9 +315,13 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) return FALSE; } } - else if (!shader->attachObject("lighting/lightFullbrightF.glsl")) + else { - return FALSE; + if (!shader->attachObject("lighting/lightFullbrightF.glsl")) + { + return FALSE; + } + shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1; } } } @@ -315,9 +339,13 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) return FALSE; } } - else if (!shader->attachObject("lighting/lightShinyWaterF.glsl")) + else { - return FALSE; + if (!shader->attachObject("lighting/lightShinyWaterF.glsl")) + { + return FALSE; + } + shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1; } } @@ -330,9 +358,13 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) return FALSE; } } - else if (!shader->attachObject("lighting/lightShinyF.glsl")) + else { - return FALSE; + if (!shader->attachObject("lighting/lightShinyF.glsl")) + { + return FALSE; + } + shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1; } } } @@ -376,7 +408,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns) } } -GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type) +GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels) { GLenum error = GL_NO_ERROR; if (gDebugGL) @@ -430,6 +462,9 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade GLcharARB* text[1024]; GLuint count = 0; + //set version to 1.20 + text[count++] = strdup("#version 120\n"); + //copy preprocessor definitions into buffer for (std::map::iterator iter = mDefinitions.begin(); iter != mDefinitions.end(); ++iter) { @@ -437,6 +472,64 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade text[count++] = (GLcharARB *) strdup(define.c_str()); } + if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER_ARB) + { + //use specified number of texture channels for indexed texture rendering + + /* prepend shader code that looks like this: + + uniform sampler2D tex0; + uniform sampler2D tex1; + uniform sampler2D tex2; + . + . + . + uniform sampler2D texN; + + varying float vary_texture_index; + + vec4 diffuseLookup(vec2 texcoord) + { + switch (int(vary_texture_index+0.25)) + { + case 0: return texture2D(tex0, texcoord); + case 1: return texture2D(tex1, texcoord); + case 2: return texture2D(tex2, texcoord); + . + . + . + case N: return texture2D(texN, texcoord); + } + + return vec4(0,0,0,0); + } + */ + + //uniform declartion + for (S32 i = 0; i < texture_index_channels; ++i) + { + std::string decl = llformat("uniform sampler2D tex%d;\n", i); + text[count++] = strdup(decl.c_str()); + } + + text[count++] = strdup("varying float vary_texture_index;\n"); + text[count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n"); + text[count++] = strdup("{\n"); + text[count++] = strdup("\tswitch (int(vary_texture_index+0.25))\n"); + text[count++] = strdup("\t{\n"); + + //switch body + for (S32 i = 0; i < texture_index_channels; ++i) + { + std::string case_str = llformat("\t\tcase %d: return texture2D(tex%d, texcoord);\n", i, i); + text[count++] = strdup(case_str.c_str()); + } + + text[count++] = strdup("\t}\n"); + text[count++] = strdup("\treturn vec4(0,0,0,0);\n"); + text[count++] = strdup("}\n"); + } + //copy file into memory while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(buff) ) { @@ -519,7 +612,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade if (shader_level > 1) { shader_level--; - return loadShaderFile(filename,shader_level,type); + return loadShaderFile(filename,shader_level,type,texture_index_channels); } LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL; } -- cgit v1.2.3