diff options
Diffstat (limited to 'indra/llrender/llrender.cpp')
-rw-r--r-- | indra/llrender/llrender.cpp | 235 |
1 files changed, 217 insertions, 18 deletions
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index b74d824c9e..43662fbb5c 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -49,6 +49,9 @@ F64 gGLLastProjection[16]; F64 gGLProjection[16]; S32 gGLViewport[4]; +U32 LLRender::sUICalls = 0; +U32 LLRender::sUIVerts = 0; + static const U32 LL_NUM_TEXTURE_LAYERS = 16; static GLenum sGLTextureType[] = @@ -90,7 +93,9 @@ static GLenum sGLBlendFactor[] = GL_DST_ALPHA, GL_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, - GL_ONE_MINUS_SRC_ALPHA + GL_ONE_MINUS_SRC_ALPHA, + + GL_ZERO // 'BF_UNDEF' }; LLTexUnit::LLTexUnit(S32 index) @@ -116,6 +121,8 @@ void LLTexUnit::refreshState(void) // We set dirty to true so that the tex unit knows to ignore caching // and we reset the cached tex unit state + gGL.flush(); + glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); if (mCurrTexType != TT_NONE) { @@ -145,6 +152,7 @@ void LLTexUnit::activate(void) if ((S32)gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty) { + gGL.flush(); glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); gGL.mCurrTextureUnitIndex = mIndex; } @@ -162,6 +170,8 @@ void LLTexUnit::enable(eTextureType type) disable(); // Force a disable of a previous texture type if it's enabled. } mCurrTexType = type; + + gGL.flush(); glEnable(sGLTextureType[type]); } } @@ -174,12 +184,13 @@ void LLTexUnit::disable(void) { activate(); unbind(mCurrTexType); + gGL.flush(); glDisable(sGLTextureType[mCurrTexType]); mCurrTexType = TT_NONE; } } -bool LLTexUnit::bind(LLTexture* texture, bool forceBind) +bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind) { stop_glerror(); if (mIndex < 0) return false; @@ -198,9 +209,19 @@ bool LLTexUnit::bind(LLTexture* texture, bool forceBind) //if deleted, will re-generate it immediately texture->forceImmediateUpdate() ; + gl_tex->forceUpdateBindStats() ; return texture->bindDefaultImage(mIndex); } + //in audit, replace the selected texture by the default one. + if(gAuditTexture && for_rendering && LLImageGL::sCurTexPickSize > 0) + { + if(texture->getWidth() * texture->getHeight() == LLImageGL::sCurTexPickSize) + { + gl_tex->updateBindStats(gl_tex->mTextureMemory); + return bind(LLImageGL::sHighlightTexturep.get()); + } + } if ((mCurrTexture != gl_tex->getTexName()) || forceBind) { activate(); @@ -223,7 +244,7 @@ bool LLTexUnit::bind(LLTexture* texture, bool forceBind) return true; } -bool LLTexUnit::bind(LLImageGL* texture, bool forceBind) +bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) { stop_glerror(); if (mIndex < 0) return false; @@ -243,10 +264,9 @@ bool LLTexUnit::bind(LLImageGL* texture, bool forceBind) return false ; } - gGL.flush(); - if ((mCurrTexture != texture->getTexName()) || forceBind) { + gGL.flush(); activate(); enable(texture->getTarget()); mCurrTexture = texture->getTexName(); @@ -260,6 +280,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool forceBind) setTextureFilteringOption(texture->mFilterOption); } } + return true; } @@ -369,6 +390,8 @@ void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode) { if (mIndex < 0 || mCurrTexture == 0) return; + gGL.flush(); + activate(); glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_S, sGLAddressMode[mode]); @@ -383,6 +406,8 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio { if (mIndex < 0 || mCurrTexture == 0) return; + gGL.flush(); + if (option == TFO_POINT) { glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -432,6 +457,8 @@ void LLTexUnit::setTextureBlendType(eTextureBlendType type) return; } + gGL.flush(); + activate(); mCurrBlendType = type; S32 scale_amount = 1; @@ -548,6 +575,7 @@ void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eT if (mCurrBlendType != TB_COMBINE || gGL.mDirty) { mCurrBlendType = TB_COMBINE; + gGL.flush(); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); } @@ -558,6 +586,8 @@ void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eT return; } + gGL.flush(); + // Get the gl source enums according to the eTextureBlendSrc sources passed in GLint source1 = getTextureSource(src1); GLint source2 = getTextureSource(src2); @@ -690,6 +720,7 @@ void LLTexUnit::setColorScale(S32 scale) if (mCurrColorScale != scale || gGL.mDirty) { mCurrColorScale = scale; + gGL.flush(); glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale ); } } @@ -699,6 +730,7 @@ void LLTexUnit::setAlphaScale(S32 scale) if (mCurrAlphaScale != scale || gGL.mDirty) { mCurrAlphaScale = scale; + gGL.flush(); glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale ); } } @@ -720,8 +752,11 @@ void LLTexUnit::debugTextureUnit(void) LLRender::LLRender() -: mDirty(false), mCount(0), mMode(LLRender::TRIANGLES), - mMaxAnisotropy(0.f) + : mDirty(false), + mCount(0), + mMode(LLRender::TRIANGLES), + mCurrTextureUnitIndex(0), + mMaxAnisotropy(0.f) { mBuffer = new LLVertexBuffer(immediate_mask, 0); mBuffer->allocateBuffer(4096, 0, TRUE); @@ -743,6 +778,11 @@ LLRender::LLRender() mCurrAlphaFunc = CF_DEFAULT; mCurrAlphaFuncVal = 0.01f; + + mCurrBlendColorSFactor = BF_UNDEF; + mCurrBlendAlphaSFactor = BF_UNDEF; + mCurrBlendColorDFactor = BF_UNDEF; + mCurrBlendAlphaDFactor = BF_UNDEF; } LLRender::~LLRender() @@ -805,6 +845,88 @@ void LLRender::popMatrix() glPopMatrix(); } +void LLRender::translateUI(F32 x, F32 y, F32 z) +{ + if (mUIOffset.empty()) + { + llerrs << "Need to push a UI translation frame before offsetting" << llendl; + } + + mUIOffset.front().mV[0] += x; + mUIOffset.front().mV[1] += y; + mUIOffset.front().mV[2] += z; +} + +void LLRender::scaleUI(F32 x, F32 y, F32 z) +{ + if (mUIScale.empty()) + { + llerrs << "Need to push a UI transformation frame before scaling." << llendl; + } + + mUIScale.front().scaleVec(LLVector3(x,y,z)); +} + +void LLRender::pushUIMatrix() +{ + if (mUIOffset.empty()) + { + mUIOffset.push_front(LLVector3(0,0,0)); + } + else + { + mUIOffset.push_front(mUIOffset.front()); + } + + if (mUIScale.empty()) + { + mUIScale.push_front(LLVector3(1,1,1)); + } + else + { + mUIScale.push_front(mUIScale.front()); + } +} + +void LLRender::popUIMatrix() +{ + if (mUIOffset.empty()) + { + llerrs << "UI offset stack blown." << llendl; + } + mUIOffset.pop_front(); + mUIScale.pop_front(); +} + +LLVector3 LLRender::getUITranslation() +{ + if (mUIOffset.empty()) + { + llerrs << "UI offset stack empty." << llendl; + } + return mUIOffset.front(); +} + +LLVector3 LLRender::getUIScale() +{ + if (mUIScale.empty()) + { + llerrs << "UI scale stack empty." << llendl; + } + return mUIScale.front(); +} + + +void LLRender::loadUIIdentity() +{ + if (mUIOffset.empty()) + { + llerrs << "Need to push UI translation frame before clearing offset." << llendl; + } + mUIOffset.front().setVec(0,0,0); + mUIScale.front().setVec(1,1,1); +} + void LLRender::setColorMask(bool writeColor, bool writeAlpha) { setColorMask(writeColor, writeColor, writeColor, writeAlpha); @@ -827,29 +949,28 @@ void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB void LLRender::setSceneBlendType(eBlendType type) { - flush(); switch (type) { case BT_ALPHA: - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + blendFunc(BF_SOURCE_ALPHA, BF_ONE_MINUS_SOURCE_ALPHA); break; case BT_ADD: - glBlendFunc(GL_ONE, GL_ONE); + blendFunc(BF_ONE, BF_ONE); break; case BT_ADD_WITH_ALPHA: - glBlendFunc(GL_SRC_ALPHA, GL_ONE); + blendFunc(BF_SOURCE_ALPHA, BF_ONE); break; case BT_MULT: - glBlendFunc(GL_DST_COLOR, GL_ZERO); + blendFunc(BF_DEST_COLOR, BF_ZERO); break; case BT_MULT_ALPHA: - glBlendFunc(GL_DST_ALPHA, GL_ZERO); + blendFunc(BF_DEST_ALPHA, BF_ZERO); break; case BT_MULT_X2: - glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); + blendFunc(BF_DEST_COLOR, BF_SOURCE_COLOR); break; case BT_REPLACE: - glBlendFunc(GL_ONE, GL_ZERO); + blendFunc(BF_ONE, BF_ZERO); break; default: llerrs << "Unknown Scene Blend Type: " << type << llendl; @@ -875,8 +996,44 @@ void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value) void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor) { - flush(); - glBlendFunc(sGLBlendFactor[sfactor], sGLBlendFactor[dfactor]); + llassert(sfactor < BF_UNDEF); + llassert(dfactor < BF_UNDEF); + if (mCurrBlendColorSFactor != sfactor || mCurrBlendColorDFactor != dfactor || + mCurrBlendAlphaSFactor != sfactor || mCurrBlendAlphaDFactor != dfactor) + { + mCurrBlendColorSFactor = sfactor; + mCurrBlendAlphaSFactor = sfactor; + mCurrBlendColorDFactor = dfactor; + mCurrBlendAlphaDFactor = dfactor; + flush(); + glBlendFunc(sGLBlendFactor[sfactor], sGLBlendFactor[dfactor]); + } +} + +void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor, + eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor) +{ + llassert(color_sfactor < BF_UNDEF); + llassert(color_dfactor < BF_UNDEF); + llassert(alpha_sfactor < BF_UNDEF); + llassert(alpha_dfactor < BF_UNDEF); + if (!gGLManager.mHasBlendFuncSeparate) + { + LL_WARNS_ONCE("render") << "no glBlendFuncSeparateEXT(), using color-only blend func" << llendl; + blendFunc(color_sfactor, color_dfactor); + return; + } + if (mCurrBlendColorSFactor != color_sfactor || mCurrBlendColorDFactor != color_dfactor || + mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor) + { + mCurrBlendColorSFactor = color_sfactor; + mCurrBlendAlphaSFactor = alpha_sfactor; + mCurrBlendColorDFactor = color_dfactor; + mCurrBlendAlphaDFactor = alpha_dfactor; + flush(); + glBlendFuncSeparateEXT(sGLBlendFactor[color_sfactor], sGLBlendFactor[color_dfactor], + sGLBlendFactor[alpha_sfactor], sGLBlendFactor[alpha_dfactor]); + } } LLTexUnit* LLRender::getTexUnit(U32 index) @@ -996,6 +1153,39 @@ void LLRender::flush() } #endif + if (!mUIOffset.empty()) + { + sUICalls++; + sUIVerts += mCount; + } + + if (gDebugGL) + { + if (mMode == LLRender::QUADS) + { + if (mCount%4 != 0) + { + llerrs << "Incomplete quad rendered." << llendl; + } + } + + if (mMode == LLRender::TRIANGLES) + { + if (mCount%3 != 0) + { + llerrs << "Incomplete triangle rendered." << llendl; + } + } + + if (mMode == LLRender::LINES) + { + if (mCount%2 != 0) + { + llerrs << "Incomplete line rendered." << llendl; + } + } + } + mBuffer->setBuffer(immediate_mask); mBuffer->drawArrays(mMode, 0, mCount); @@ -1015,7 +1205,16 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z) return; } - mVerticesp[mCount] = LLVector3(x,y,z); + if (mUIOffset.empty()) + { + mVerticesp[mCount] = LLVector3(x,y,z); + } + else + { + LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.front()).scaledVec(mUIScale.front()); + mVerticesp[mCount] = vert; + } + mCount++; if (mCount < 4096) { |