diff options
Diffstat (limited to 'indra/llrender/llglslshader.cpp')
| -rw-r--r-- | indra/llrender/llglslshader.cpp | 171 |
1 files changed, 151 insertions, 20 deletions
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 16534fa9a5..4b7e639aed 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -31,6 +31,7 @@ #include "llshadermgr.h" #include "llfile.h" #include "llrender.h" +#include "llvertexbuffer.h" #if LL_DARWIN #include "OpenGL/OpenGL.h" @@ -48,15 +49,38 @@ using std::pair; using std::make_pair; using std::string; +GLhandleARB LLGLSLShader::sCurBoundShader = 0; +LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL; +S32 LLGLSLShader::sIndexedTextureChannels = 0; +bool LLGLSLShader::sNoFixedFunction = false; + +//UI shader -- declared here so llui_libtest will link properly +LLGLSLShader gUIProgram; +LLGLSLShader gSolidColorProgram; + BOOL shouldChange(const LLVector4& v1, const LLVector4& v2) { return v1 != v2; } LLShaderFeatures::LLShaderFeatures() -: calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false), -hasTransport(false), hasSkinning(false), hasAtmospherics(false), isSpecular(false), -hasGamma(false), hasLighting(false), calculatesAtmospherics(false) + : atmosphericHelpers(false) + , calculatesLighting(false) + , calculatesAtmospherics(false) + , hasLighting(false) + , isAlphaLighting(false) + , isShiny(false) + , isFullbright(false) + , isSpecular(false) + , hasWaterFog(false) + , hasTransport(false) + , hasSkinning(false) + , hasObjectSkinning(false) + , hasAtmospherics(false) + , hasGamma(false) + , mIndexedTextureChannels(0) + , disableTextureIndex(false) + , hasAlphaMask(false) { } @@ -66,6 +90,7 @@ hasGamma(false), hasLighting(false), calculatesAtmospherics(false) LLGLSLShader::LLGLSLShader() : mProgramObject(0), mActiveTextureChannels(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT), mUniformsDirty(FALSE) { + } void LLGLSLShader::unload() @@ -84,7 +109,12 @@ void LLGLSLShader::unload() glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj); for (GLsizei i = 0; i < count; i++) { - glDeleteObjectARB(obj[i]); +#if !LL_DARWIN + if (glIsProgramARB(obj[i])) +#endif + { + glDeleteObjectARB(obj[i]); + } } glDeleteObjectARB(mProgramObject); @@ -101,24 +131,26 @@ void LLGLSLShader::unload() BOOL LLGLSLShader::createShader(vector<string> * attributes, vector<string> * uniforms) { + //reloading, reset matrix hash values + for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i) + { + mMatHash[i] = 0xFFFFFFFF; + } + mLightHash = 0xFFFFFFFF; + llassert_always(!mShaderFiles.empty()); BOOL success = TRUE; // 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 (mShaderLevel > 0) + if (shaderhandle > 0) { attachObject(shaderhandle); } @@ -128,6 +160,18 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes, } } + // Attach existing objects + if (!LLShaderMgr::instance()->attachShaderFeatures(this)) + { + return FALSE; + } + + if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 3) + { //indexed texture rendering requires GLSL 1.3 or later + //attachShaderFeatures may have set the number of indexed texture channels, so set to 1 again + mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1); + } + // Map attributes and uniforms if (success) { @@ -149,6 +193,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; } @@ -192,6 +259,13 @@ void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count) BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes) { + //before linking, make sure reserved attributes always have consistent locations + for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++) + { + const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str(); + glBindAttribLocationARB(mProgramObject, i, (const GLcharARB *) name); + } + //link the program BOOL res = link(); @@ -265,7 +339,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms) for (S32 i = 0; i < (S32) LLShaderMgr::instance()->mReservedUniforms.size(); i++) { if ( (mUniform[i] == -1) - && (LLShaderMgr::instance()->mReservedUniforms[i].compare(0, length, name, LLShaderMgr::instance()->mReservedUniforms[i].length()) == 0)) + && (LLShaderMgr::instance()->mReservedUniforms[i] == name)) { //found it mUniform[i] = location; @@ -279,7 +353,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms) for (U32 i = 0; i < uniforms->size(); i++) { if ( (mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] == -1) - && ((*uniforms)[i].compare(0, length, name, (*uniforms)[i].length()) == 0)) + && ((*uniforms)[i] == name)) { //found it mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] = location; @@ -293,7 +367,8 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms) 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); LL_DEBUGS("ShaderLoading") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL; @@ -339,10 +414,13 @@ BOOL LLGLSLShader::link(BOOL suppress_errors) void LLGLSLShader::bind() { + gGL.flush(); if (gGLManager.mHasShaderObjects) { + LLVertexBuffer::unbind(); glUseProgramObjectARB(mProgramObject); - + sCurBoundShader = mProgramObject; + sCurBoundShaderPtr = this; if (mUniformsDirty) { LLShaderMgr::instance()->updateShaderUniforms(this); @@ -353,6 +431,7 @@ void LLGLSLShader::bind() void LLGLSLShader::unbind() { + gGL.flush(); if (gGLManager.mHasShaderObjects) { stop_glerror(); @@ -364,14 +443,23 @@ void LLGLSLShader::unbind() stop_glerror(); } } + LLVertexBuffer::unbind(); glUseProgramObjectARB(0); + sCurBoundShader = 0; + sCurBoundShaderPtr = NULL; stop_glerror(); } } void LLGLSLShader::bindNoShader(void) { - glUseProgramObjectARB(0); + LLVertexBuffer::unbind(); + if (gGLManager.mHasShaderObjects) + { + glUseProgramObjectARB(0); + sCurBoundShader = 0; + sCurBoundShaderPtr = NULL; + } } S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode) @@ -698,17 +786,50 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c GLint LLGLSLShader::getUniformLocation(const string& uniform) { + GLint ret = -1; if (mProgramObject > 0) { std::map<string, GLint>::iterator iter = mUniformMap.find(uniform); if (iter != mUniformMap.end()) { - llassert(iter->second == glGetUniformLocationARB(mProgramObject, uniform.c_str())); - return iter->second; + if (gDebugGL) + { + stop_glerror(); + if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.c_str())) + { + llerrs << "Uniform does not match." << llendl; + } + stop_glerror(); + } + ret = iter->second; } } - return -1; + return ret; +} + +GLint LLGLSLShader::getUniformLocation(U32 index) +{ + GLint ret = -1; + if (mProgramObject > 0) + { + llassert(index < mUniform.size()); + return mUniform[index]; + } + + return ret; +} + +GLint LLGLSLShader::getAttribLocation(U32 attrib) +{ + if (attrib < mAttribute.size()) + { + return mAttribute[attrib]; + } + else + { + return -1; + } } void LLGLSLShader::uniform1i(const string& uniform, GLint v) @@ -850,7 +971,9 @@ void LLGLSLShader::uniform4fv(const string& uniform, U32 count, const GLfloat* v std::map<GLint, LLVector4>::iterator iter = mValue.find(location); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { + stop_glerror(); glUniform4fvARB(location, count, v); + stop_glerror(); mValue[location] = vec; } } @@ -882,7 +1005,9 @@ void LLGLSLShader::uniformMatrix4fv(const string& uniform, U32 count, GLboolean if (location >= 0) { + stop_glerror(); glUniformMatrix4fvARB(location, count, transpose, v); + stop_glerror(); } } @@ -902,3 +1027,9 @@ void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v) glVertexAttrib4fvARB(mAttribute[index], v); } } + +void LLGLSLShader::setMinimumAlpha(F32 minimum) +{ + gGL.flush(); + uniform1f(LLShaderMgr::MINIMUM_ALPHA, minimum); +} |
