summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llgl.cpp9
-rw-r--r--indra/llrender/llgl.h2
-rw-r--r--indra/llrender/llglslshader.cpp78
-rw-r--r--indra/llrender/llglslshader.h14
-rw-r--r--indra/llrender/llrender.h8
-rw-r--r--indra/llrender/llshadermgr.cpp15
-rw-r--r--indra/llrender/llshadermgr.h9
-rw-r--r--indra/llrender/llvertexbuffer.cpp32
-rw-r--r--indra/llrender/llvertexbuffer.h1
9 files changed, 156 insertions, 12 deletions
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index c8cf3713ab..9967c23ce8 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -963,6 +963,15 @@ void LLGLManager::initExtensions()
ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts) &&
ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
#endif
+#ifdef GL_EXT_texture_sRGB
+ mHassRGBTexture = ExtensionExists("GL_EXT_texture_sRGB", gGLHExts.mSysExts);
+#endif
+
+#ifdef GL_ARB_framebuffer_sRGB
+ mHassRGBFramebuffer = ExtensionExists("GL_ARB_framebuffer_sRGB", gGLHExts.mSysExts);
+#else
+ mHassRGBFramebuffer = ExtensionExists("GL_EXT_framebuffer_sRGB", gGLHExts.mSysExts);
+#endif
mHasMipMapGeneration = mHasFramebufferObject || mGLVersion >= 1.4f;
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index d70e764769..1e921d1e97 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -115,6 +115,8 @@ public:
BOOL mHasARBEnvCombine;
BOOL mHasCubeMap;
BOOL mHasDebugOutput;
+ BOOL mHassRGBTexture;
+ BOOL mHassRGBFramebuffer;
// Vendor-specific extensions
BOOL mIsATI;
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 7cbf39096e..39ad9b9e9b 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -88,7 +88,12 @@ LLShaderFeatures::LLShaderFeatures()
// LLGLSL Shader implementation
//===============================
LLGLSLShader::LLGLSLShader()
- : mProgramObject(0), mActiveTextureChannels(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT), mUniformsDirty(FALSE)
+ : mProgramObject(0),
+ mAttributeMask(0),
+ mActiveTextureChannels(0),
+ mShaderLevel(0),
+ mShaderGroup(SG_DEFAULT),
+ mUniformsDirty(FALSE)
{
}
@@ -150,7 +155,7 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
for ( ; fileIter != mShaderFiles.end(); fileIter++ )
{
- GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, mFeatures.mIndexedTextureChannels);
+ GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, mDefines, mFeatures.mIndexedTextureChannels);
LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
if (shaderhandle > 0)
{
@@ -285,6 +290,8 @@ BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
if (res)
{ //read back channel locations
+ mAttributeMask = 0;
+
//read back reserved channels first
for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
{
@@ -293,6 +300,7 @@ BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
if (index != -1)
{
mAttribute[i] = index;
+ mAttributeMask |= 1 << i;
LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
}
}
@@ -372,11 +380,21 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
}
}
}
- }
+}
+
+void LLGLSLShader::addPermutation(std::string name, std::string value)
+{
+ mDefines[name] = value;
+}
+
+void LLGLSLShader::removePermutation(std::string name)
+{
+ mDefines[name].erase();
+}
GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
{
- if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB ||
+ if ((type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) ||
type == GL_SAMPLER_2D_MULTISAMPLE)
{ //this here is a texture
glUniform1iARB(location, mActiveTextureChannels);
@@ -471,6 +489,58 @@ void LLGLSLShader::bindNoShader(void)
}
}
+S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode)
+{
+ S32 channel = 0;
+ channel = getUniformLocation(uniform);
+
+ return bindTexture(channel, texture, mode);
+}
+
+S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode)
+{
+ if (uniform < 0 || uniform >= (S32)mTexture.size())
+ {
+ UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+ return -1;
+ }
+
+ uniform = mTexture[uniform];
+
+ if (uniform > -1)
+ {
+ gGL.getTexUnit(uniform)->bind(texture, mode);
+ }
+
+ return uniform;
+}
+
+S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureType mode)
+{
+ S32 channel = 0;
+ channel = getUniformLocation(uniform);
+
+ return unbindTexture(channel);
+}
+
+S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
+{
+ if (uniform < 0 || uniform >= (S32)mTexture.size())
+ {
+ UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+ return -1;
+ }
+
+ uniform = mTexture[uniform];
+
+ if (uniform > -1)
+ {
+ gGL.getTexUnit(uniform)->unbind(mode);
+ }
+
+ return uniform;
+}
+
S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
{
if (uniform < 0 || uniform >= (S32)mTexture.size())
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 5c68cb46eb..725a7e2573 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -123,12 +123,22 @@ public:
GLint getAttribLocation(U32 attrib);
GLint mapUniformTextureChannel(GLint location, GLenum type);
+ void addPermutation(std::string name, std::string value);
+ void removePermutation(std::string name);
+
//enable/disable texture channel for specified uniform
//if given texture uniform is active in the shader,
//the corresponding channel will be active upon return
//returns channel texture is enabled in from [0-MAX)
S32 enableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
- S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+ S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+
+ // bindTexture returns the texture unit we've bound the texture to.
+ // You can reuse the return value to unbind a texture when required.
+ S32 bindTexture(const std::string& uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+ S32 bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+ S32 unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+ S32 unbindTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
BOOL link(BOOL suppress_errors = FALSE);
void bind();
@@ -142,6 +152,7 @@ public:
GLhandleARB mProgramObject;
std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel
+ U32 mAttributeMask; //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())
std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location
std::map<std::string, GLint> mUniformMap; //lookup map of uniform name to uniform location
std::map<GLint, LLVector4> mValue; //lookup map of uniform location to last known value
@@ -153,6 +164,7 @@ public:
LLShaderFeatures mFeatures;
std::vector< std::pair< std::string, GLenum > > mShaderFiles;
std::string mName;
+ boost::unordered_map<std::string, std::string> mDefines;
};
//UI shader (declared here so llui_libtest will link properly)
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 78a310e525..98222939e7 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -262,6 +262,14 @@ class LLRender
friend class LLTexUnit;
public:
+ enum eTexIndex
+ {
+ DIFFUSE_MAP = 0,
+ NORMAL_MAP,
+ SPECULAR_MAP,
+ NUM_TEXTURE_CHANNELS,
+ };
+
typedef enum {
TRIANGLES = 0,
TRIANGLE_STRIP,
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index b6a9a6b653..d4ddc6396b 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -521,7 +521,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
}
}
-GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels)
+GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string> defines, S32 texture_index_channels)
{
GLenum error = GL_NO_ERROR;
if (gDebugGL)
@@ -650,9 +650,8 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
text[count++] = strdup("#define shadow2DRect(a,b) vec2(texture(a,b))\n");
}
}
-
- //copy preprocessor definitions into buffer
- for (std::map<std::string,std::string>::iterator iter = mDefinitions.begin(); iter != mDefinitions.end(); ++iter)
+
+ for (boost::unordered_map<std::string,std::string>::iterator iter = defines.begin(); iter != defines.end(); ++iter)
{
std::string define = "#define " + iter->first + " " + iter->second + "\n";
text[count++] = (GLcharARB *) strdup(define.c_str());
@@ -854,7 +853,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (shader_level > 1)
{
shader_level--;
- return loadShaderFile(filename,shader_level,type,texture_index_channels);
+ return loadShaderFile(filename,shader_level,type, defines, texture_index_channels);
}
LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;
}
@@ -1115,6 +1114,12 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("lightMap");
mReservedUniforms.push_back("bloomMap");
mReservedUniforms.push_back("projectionMap");
+
+ mReservedUniforms.push_back("global_gamma");
+ mReservedUniforms.push_back("texture_gamma");
+
+ mReservedUniforms.push_back("specular_color");
+ mReservedUniforms.push_back("env_intensity");
llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 7a16b7c20f..1c97ab4e60 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -164,6 +164,13 @@ public:
DEFERRED_LIGHT,
DEFERRED_BLOOM,
DEFERRED_PROJECTION,
+
+ GLOBAL_GAMMA,
+ TEXTURE_GAMMA,
+
+ SPECULAR_COLOR,
+ ENVIRONMENT_INTENSITY,
+
END_RESERVED_UNIFORMS
} eGLSLReservedUniforms;
@@ -176,7 +183,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, S32 texture_index_channels = -1);
+ GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string> defines, S32 texture_index_channels = -1);
// Implemented in the application to actually point to the shader directory.
virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index dfbd8cd4ee..29fe5400a3 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -349,6 +349,25 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes
};
+static std::string vb_type_name[] =
+{
+ "TYPE_VERTEX",
+ "TYPE_NORMAL",
+ "TYPE_TEXCOORD0",
+ "TYPE_TEXCOORD1",
+ "TYPE_TEXCOORD2",
+ "TYPE_TEXCOORD3",
+ "TYPE_COLOR",
+ "TYPE_EMISSIVE",
+ "TYPE_BINORMAL",
+ "TYPE_WEIGHT",
+ "TYPE_WEIGHT4",
+ "TYPE_CLOTHWEIGHT",
+ "TYPE_TEXTURE_INDEX",
+ "TYPE_MAX",
+ "TYPE_INDEX",
+};
+
U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
{
GL_TRIANGLES,
@@ -2027,7 +2046,10 @@ bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 inde
{
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index, count, map_range);
}
-
+bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index, S32 count, bool map_range)
+{
+ return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index, count, map_range);
+}
bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count, map_range);
@@ -2310,6 +2332,14 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
if (gDebugGL && ((data_mask & mTypeMask) != data_mask))
{
+ for (U32 i = 0; i < LLVertexBuffer::TYPE_MAX; ++i)
+ {
+ U32 mask = 1 << i;
+ if (mask & data_mask && !(mask & mTypeMask))
+ { //bit set in data_mask, but not set in mTypeMask
+ llwarns << "Missing required component " << vb_type_name[i] << llendl;
+ }
+ }
llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;
}
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index 11fa4ab6a0..1be9b79e84 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -250,6 +250,7 @@ public:
bool getIndexStrider(LLStrider<U16>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
+ bool getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);