summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2011-05-31 14:35:59 -0500
committerDave Parks <davep@lindenlab.com>2011-05-31 14:35:59 -0500
commitece32418e7c1828a65c88e526a5afcb635c5453a (patch)
tree3c1cb5315a354371b75d98d79f97a98d078815c4 /indra/llrender
parent522a28d12721e1cc2e7f726882baa79be97d55fa (diff)
SH-1682 Dynamically adjust the number of texture channels to use for indexed texture rendering based on available hardware.
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llgl.cpp3
-rw-r--r--indra/llrender/llglslshader.cpp40
-rw-r--r--indra/llrender/llglslshader.h1
-rw-r--r--indra/llrender/llrender.cpp2
-rw-r--r--indra/llrender/llshadermgr.cpp129
-rw-r--r--indra/llrender/llshadermgr.h2
6 files changed, 148 insertions, 29 deletions
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 96b1838158..a8d7df3bc8 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -551,7 +551,7 @@ bool LLGLManager::initGL()
{
GLint num_tex_image_units;
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
- mNumTextureImageUnits = num_tex_image_units;
+ mNumTextureImageUnits = llmin(num_tex_image_units, 32);
}
if (mHasTextureMultisample)
@@ -1516,6 +1516,7 @@ void LLGLState::checkTextureChannels(const std::string& msg)
}
}
+ stop_glerror();
gGL.getTexUnit(0)->activate();
glClientActiveTextureARB(GL_TEXTURE0_ARB);
stop_glerror();
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 71d24bcf13..2dab757828 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -56,7 +56,7 @@ BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
LLShaderFeatures::LLShaderFeatures()
: calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false),
hasTransport(false), hasSkinning(false), hasObjectSkinning(false), hasAtmospherics(false), isSpecular(false),
-hasGamma(false), hasLighting(false), calculatesAtmospherics(false), disableTextureIndex(false)
+hasGamma(false), hasLighting(false), calculatesAtmospherics(false), mIndexedTextureChannels(0), disableTextureIndex(false)
{
}
@@ -107,16 +107,11 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
// Create program
mProgramObject = glCreateProgramObjectARB();
- // Attach existing objects
- if (!LLShaderMgr::instance()->attachShaderFeatures(this))
- {
- return FALSE;
- }
-
+ //compile new source
vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
for ( ; fileIter != mShaderFiles.end(); fileIter++ )
{
- GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second);
+ GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, mFeatures.mIndexedTextureChannels);
LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
if (shaderhandle > 0)
{
@@ -128,6 +123,12 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
}
}
+ // Attach existing objects
+ if (!LLShaderMgr::instance()->attachShaderFeatures(this))
+ {
+ return FALSE;
+ }
+
// Map attributes and uniforms
if (success)
{
@@ -149,6 +150,29 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
return createShader(attributes,uniforms);
}
}
+ else if (mFeatures.mIndexedTextureChannels > 0)
+ { //override texture channels for indexed texture rendering
+ bind();
+ S32 channel_count = mFeatures.mIndexedTextureChannels;
+
+ for (S32 i = 0; i < channel_count; i++)
+ {
+ uniform1i(llformat("tex%d", i), i);
+ }
+
+ S32 cur_tex = channel_count; //adjust any texture channels that might have been overwritten
+ for (U32 i = 0; i < mTexture.size(); i++)
+ {
+ if (mTexture[i] > -1 && mTexture[i] < channel_count)
+ {
+ llassert(cur_tex < gGLManager.mNumTextureImageUnits);
+ uniform1i(i, cur_tex);
+ mTexture[i] = cur_tex++;
+ }
+ }
+ unbind();
+ }
+
return success;
}
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 392688bba3..51be56b295 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -45,6 +45,7 @@ public:
bool hasObjectSkinning;
bool hasAtmospherics;
bool hasGamma;
+ S32 mIndexedTextureChannels;
bool disableTextureIndex;
// char numLights;
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 0532510996..fdfcfe7fab 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -46,7 +46,7 @@ S32 gGLViewport[4];
U32 LLRender::sUICalls = 0;
U32 LLRender::sUIVerts = 0;
-static const U32 LL_NUM_TEXTURE_LAYERS = 16;
+static const U32 LL_NUM_TEXTURE_LAYERS = 32;
static const U32 LL_NUM_LIGHT_UNITS = 8;
static GLenum sGLTextureType[] =
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<std::string,std::string>::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;
}
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 9ee11b98c8..2f30103811 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -43,7 +43,7 @@ public:
void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE);
BOOL linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);
BOOL validateProgramObject(GLhandleARB obj);
- GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type);
+ GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels = -1);
// Implemented in the application to actually point to the shader directory.
virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual