diff options
Diffstat (limited to 'indra/llrender/llrender.cpp')
-rw-r--r-- | indra/llrender/llrender.cpp | 305 |
1 files changed, 272 insertions, 33 deletions
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 8eb160f4e7..edcc47aa14 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -30,6 +30,7 @@ #include "llvertexbuffer.h" #include "llcubemap.h" +#include "llglslshader.h" #include "llimagegl.h" #include "llrendertarget.h" #include "lltexture.h" @@ -45,14 +46,17 @@ S32 gGLViewport[4]; U32 LLRender::sUICalls = 0; U32 LLRender::sUIVerts = 0; +U32 LLTexUnit::sWhiteTexture = 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[] = { GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_ARB, - GL_TEXTURE_CUBE_MAP_ARB + GL_TEXTURE_CUBE_MAP_ARB, + GL_TEXTURE_2D_MULTISAMPLE }; static GLint sGLAddressMode[] = @@ -118,14 +122,30 @@ void LLTexUnit::refreshState(void) gGL.flush(); glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); + + // + // Per apple spec, don't call glEnable/glDisable when index exceeds max texture units + // http://www.mailinglistarchive.com/html/mac-opengl@lists.apple.com/2008-07/msg00653.html + // + bool enableDisable = !LLGLSLShader::sNoFixedFunction && + (mIndex < gGLManager.mNumTextureUnits) && mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE; + if (mCurrTexType != TT_NONE) { - glEnable(sGLTextureType[mCurrTexType]); + if (enableDisable) + { + glEnable(sGLTextureType[mCurrTexType]); + } + glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture); } else { - glDisable(GL_TEXTURE_2D); + if (enableDisable) + { + glDisable(GL_TEXTURE_2D); + } + glBindTexture(GL_TEXTURE_2D, 0); } @@ -166,7 +186,12 @@ void LLTexUnit::enable(eTextureType type) mCurrTexType = type; gGL.flush(); - glEnable(sGLTextureType[type]); + if (!LLGLSLShader::sNoFixedFunction && + type != LLTexUnit::TT_MULTISAMPLE_TEXTURE && + mIndex < gGLManager.mNumTextureUnits) + { + glEnable(sGLTextureType[type]); + } } } @@ -179,7 +204,13 @@ void LLTexUnit::disable(void) activate(); unbind(mCurrTexType); gGL.flush(); - glDisable(sGLTextureType[mCurrTexType]); + if (!LLGLSLShader::sNoFixedFunction && + mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE && + mIndex < gGLManager.mNumTextureUnits) + { + glDisable(sGLTextureType[mCurrTexType]); + } + mCurrTexType = TT_NONE; } } @@ -376,7 +407,15 @@ void LLTexUnit::unbind(eTextureType type) activate(); mCurrTexture = 0; - glBindTexture(sGLTextureType[type], 0); + if (LLGLSLShader::sNoFixedFunction && type == LLTexUnit::TT_TEXTURE) + { + glBindTexture(sGLTextureType[type], sWhiteTexture); + } + else + { + glBindTexture(sGLTextureType[type], 0); + } + stop_glerror(); } } @@ -398,7 +437,7 @@ void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode) void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option) { - if (mIndex < 0 || mCurrTexture == 0) return; + if (mIndex < 0 || mCurrTexture == 0 || mCurrTexType == LLTexUnit::TT_MULTISAMPLE_TEXTURE) return; gGL.flush(); @@ -446,6 +485,11 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio void LLTexUnit::setTextureBlendType(eTextureBlendType type) { + if (LLGLSLShader::sNoFixedFunction) + { //texture blend type means nothing when using shaders + return; + } + if (mIndex < 0) return; // Do nothing if it's already correctly set. @@ -566,6 +610,11 @@ GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha) void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha) { + if (LLGLSLShader::sNoFixedFunction) + { //register combiners do nothing when not using fixed function + return; + } + if (mIndex < 0) return; activate(); @@ -747,6 +796,130 @@ void LLTexUnit::debugTextureUnit(void) } } +LLLightState::LLLightState(S32 index) +: mIndex(index), + mEnabled(false), + mConstantAtten(1.f), + mLinearAtten(0.f), + mQuadraticAtten(0.f), + mSpotExponent(0.f), + mSpotCutoff(180.f) +{ + if (mIndex == 0) + { + mDiffuse.set(1,1,1,1); + mSpecular.set(1,1,1,1); + } + + mAmbient.set(0,0,0,1); + mPosition.set(0,0,1,0); + mSpotDirection.set(0,0,-1); + +} + +void LLLightState::enable() +{ + if (!mEnabled) + { + glEnable(GL_LIGHT0+mIndex); + mEnabled = true; + } +} + +void LLLightState::disable() +{ + if (mEnabled) + { + glDisable(GL_LIGHT0+mIndex); + mEnabled = false; + } +} + +void LLLightState::setDiffuse(const LLColor4& diffuse) +{ + if (mDiffuse != diffuse) + { + mDiffuse = diffuse; + glLightfv(GL_LIGHT0+mIndex, GL_DIFFUSE, mDiffuse.mV); + } +} + +void LLLightState::setAmbient(const LLColor4& ambient) +{ + if (mAmbient != ambient) + { + mAmbient = ambient; + glLightfv(GL_LIGHT0+mIndex, GL_AMBIENT, mAmbient.mV); + } +} + +void LLLightState::setSpecular(const LLColor4& specular) +{ + if (mSpecular != specular) + { + mSpecular = specular; + glLightfv(GL_LIGHT0+mIndex, GL_SPECULAR, mSpecular.mV); + } +} + +void LLLightState::setPosition(const LLVector4& position) +{ + //always set position because modelview matrix may have changed + mPosition = position; + glLightfv(GL_LIGHT0+mIndex, GL_POSITION, mPosition.mV); +} + +void LLLightState::setConstantAttenuation(const F32& atten) +{ + if (mConstantAtten != atten) + { + mConstantAtten = atten; + glLightf(GL_LIGHT0+mIndex, GL_CONSTANT_ATTENUATION, atten); + } +} + +void LLLightState::setLinearAttenuation(const F32& atten) +{ + if (mLinearAtten != atten) + { + mLinearAtten = atten; + glLightf(GL_LIGHT0+mIndex, GL_LINEAR_ATTENUATION, atten); + } +} + +void LLLightState::setQuadraticAttenuation(const F32& atten) +{ + if (mQuadraticAtten != atten) + { + mQuadraticAtten = atten; + glLightf(GL_LIGHT0+mIndex, GL_QUADRATIC_ATTENUATION, atten); + } +} + +void LLLightState::setSpotExponent(const F32& exponent) +{ + if (mSpotExponent != exponent) + { + mSpotExponent = exponent; + glLightf(GL_LIGHT0+mIndex, GL_SPOT_EXPONENT, exponent); + } +} + +void LLLightState::setSpotCutoff(const F32& cutoff) +{ + if (mSpotCutoff != cutoff) + { + mSpotCutoff = cutoff; + glLightf(GL_LIGHT0+mIndex, GL_SPOT_CUTOFF, cutoff); + } +} + +void LLLightState::setSpotDirection(const LLVector3& direction) +{ + //always set direction because modelview matrix may have changed + mSpotDirection = direction; + glLightfv(GL_LIGHT0+mIndex, GL_SPOT_DIRECTION, direction.mV); +} LLRender::LLRender() : mDirty(false), @@ -754,13 +927,7 @@ LLRender::LLRender() mMode(LLRender::TRIANGLES), mCurrTextureUnitIndex(0), mMaxAnisotropy(0.f) -{ - mBuffer = new LLVertexBuffer(immediate_mask, 0); - mBuffer->allocateBuffer(4096, 0, TRUE); - mBuffer->getVertexStrider(mVerticesp); - mBuffer->getTexCoord0Strider(mTexcoordsp); - mBuffer->getColorStrider(mColorsp); - +{ mTexUnits.reserve(LL_NUM_TEXTURE_LAYERS); for (U32 i = 0; i < LL_NUM_TEXTURE_LAYERS; i++) { @@ -768,6 +935,11 @@ LLRender::LLRender() } mDummyTexUnit = new LLTexUnit(-1); + for (U32 i = 0; i < LL_NUM_LIGHT_UNITS; ++i) + { + mLightState.push_back(new LLLightState(i)); + } + for (U32 i = 0; i < 4; i++) { mCurrColorMask[i] = true; @@ -786,6 +958,17 @@ LLRender::~LLRender() shutdown(); } +void LLRender::init() +{ + llassert_always(mBuffer.isNull()) ; + + mBuffer = new LLVertexBuffer(immediate_mask, 0); + mBuffer->allocateBuffer(4096, 0, TRUE); + mBuffer->getVertexStrider(mVerticesp); + mBuffer->getTexCoord0Strider(mTexcoordsp); + mBuffer->getColorStrider(mColorsp); +} + void LLRender::shutdown() { for (U32 i = 0; i < mTexUnits.size(); i++) @@ -795,6 +978,13 @@ void LLRender::shutdown() mTexUnits.clear(); delete mDummyTexUnit; mDummyTexUnit = NULL; + + for (U32 i = 0; i < mLightState.size(); ++i) + { + delete mLightState[i]; + } + mLightState.clear(); + mBuffer = NULL ; } void LLRender::refreshState(void) @@ -898,7 +1088,7 @@ LLVector3 LLRender::getUITranslation() { if (mUIOffset.empty()) { - return LLVector3::zero; + return LLVector3(0,0,0); } return mUIOffset.back(); } @@ -907,7 +1097,7 @@ LLVector3 LLRender::getUIScale() { if (mUIScale.empty()) { - return LLVector3(1.f, 1.f, 1.f); + return LLVector3(1,1,1); } return mUIScale.back(); } @@ -932,15 +1122,21 @@ void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB { flush(); - mCurrColorMask[0] = writeColorR; - mCurrColorMask[1] = writeColorG; - mCurrColorMask[2] = writeColorB; - mCurrColorMask[3] = writeAlpha; + if (mCurrColorMask[0] != writeColorR || + mCurrColorMask[1] != writeColorG || + mCurrColorMask[2] != writeColorB || + mCurrColorMask[3] != writeAlpha) + { + mCurrColorMask[0] = writeColorR; + mCurrColorMask[1] = writeColorG; + mCurrColorMask[2] = writeColorB; + mCurrColorMask[3] = writeAlpha; - glColorMask(writeColorR ? GL_TRUE : GL_FALSE, - writeColorG ? GL_TRUE : GL_FALSE, - writeColorB ? GL_TRUE : GL_FALSE, - writeAlpha ? GL_TRUE : GL_FALSE); + glColorMask(writeColorR ? GL_TRUE : GL_FALSE, + writeColorG ? GL_TRUE : GL_FALSE, + writeColorB ? GL_TRUE : GL_FALSE, + writeAlpha ? GL_TRUE : GL_FALSE); + } } void LLRender::setSceneBlendType(eBlendType type) @@ -978,15 +1174,48 @@ void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value) { flush(); - mCurrAlphaFunc = func; - mCurrAlphaFuncVal = value; - if (func == CF_DEFAULT) - { - glAlphaFunc(GL_GREATER, 0.01f); - } - else + if (LLGLSLShader::sNoFixedFunction) + { //glAlphaFunc is deprecated in OpenGL 3.3 + return; + } + + if (mCurrAlphaFunc != func || + mCurrAlphaFuncVal != value) { - glAlphaFunc(sGLCompareFunc[func], value); + mCurrAlphaFunc = func; + mCurrAlphaFuncVal = value; + if (func == CF_DEFAULT) + { + glAlphaFunc(GL_GREATER, 0.01f); + } + else + { + glAlphaFunc(sGLCompareFunc[func], value); + } + } + + if (gDebugGL) + { //make sure cached state is correct + GLint cur_func = 0; + glGetIntegerv(GL_ALPHA_TEST_FUNC, &cur_func); + + if (func == CF_DEFAULT) + { + func = CF_GREATER; + } + + if (cur_func != sGLCompareFunc[func]) + { + llerrs << "Alpha test function corrupted!" << llendl; + } + + F32 ref = 0.f; + glGetFloatv(GL_ALPHA_TEST_REF, &ref); + + if (ref != value) + { + llerrs << "Alpha test value corrupted!" << llendl; + } } } @@ -1045,6 +1274,16 @@ LLTexUnit* LLRender::getTexUnit(U32 index) } } +LLLightState* LLRender::getLight(U32 index) +{ + if (index < mLightState.size()) + { + return mLightState[index]; + } + + return NULL; +} + bool LLRender::verifyTexUnitActive(U32 unitToVerify) { if (mCurrTextureUnitIndex == unitToVerify) |