diff options
Diffstat (limited to 'indra/newview/lltexlayer.cpp')
-rw-r--r-- | indra/newview/lltexlayer.cpp | 235 |
1 files changed, 163 insertions, 72 deletions
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index 5d9046ac90..662e6dcabe 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -31,8 +31,14 @@ */ #include "llviewerprecompiledheaders.h" -#include "llagent.h" + #include "lltexlayer.h" + +#include "llagent.h" +#include "llimagej2c.h" +#include "llimagetga.h" +#include "llvfile.h" +#include "llvfs.h" #include "llviewerstats.h" #include "llviewerregion.h" #include "llvoavatar.h" @@ -161,8 +167,8 @@ void LLTexLayerSetBuffer::popProjection() const BOOL LLTexLayerSetBuffer::needsRender() { const LLVOAvatarSelf* avatar = mTexLayerSet->getAvatar(); - BOOL upload_now = mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal(); - BOOL needs_update = gAgentQueryManager.hasNoPendingQueries() && (mNeedsUpdate || upload_now) && !avatar->mAppearanceAnimating; + BOOL upload_now = mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal() && gAgentQueryManager.hasNoPendingQueries(); + BOOL needs_update = (mNeedsUpdate || upload_now) && !avatar->mAppearanceAnimating; if (needs_update) { BOOL invalid_skirt = avatar->getBakedTE(mTexLayerSet) == LLVOAvatarDefines::TEX_SKIRT_BAKED && !avatar->isWearingWearableType(WT_SKIRT); @@ -223,7 +229,16 @@ BOOL LLTexLayerSetBuffer::render() } else { - readBackAndUpload(); + if (mTexLayerSet->isVisible()) + { + readBackAndUpload(); + } + else + { + mUploadPending = FALSE; + mNeedsUpload = FALSE; + mTexLayerSet->getAvatar()->setNewBakedTexture(mTexLayerSet->getBakedTexIndex(),IMG_INVISIBLE); + } } } @@ -551,6 +566,8 @@ LLTexLayerSet::LLTexLayerSet(LLVOAvatarSelf* const avatar) : mComposite( NULL ), mAvatar( avatar ), mUpdatesEnabled( FALSE ), + mIsVisible( TRUE ), + mBakedTexIndex(LLVOAvatarDefines::BAKED_HEAD), mInfo( NULL ) { } @@ -665,44 +682,69 @@ BOOL LLTexLayerSet::isLocalTextureDataFinal() const BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) { BOOL success = TRUE; + mIsVisible = TRUE; + + if (mMaskLayerList.size() > 0) + { + for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++) + { + LLTexLayerInterface* layer = *iter; + if (layer->isInvisibleAlphaMask()) + { + mIsVisible = FALSE; + } + } + } LLGLSUIDefault gls_ui; LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE); gGL.setColorMask(true, true); - BOOL render_morph = mAvatar->morphMaskNeedsUpdate(mBakedTexIndex); - // clear buffer area to ensure we don't pick up UI elements { gGL.flush(); LLGLDisable no_alpha(GL_ALPHA_TEST); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.color4f( 0.f, 0.f, 0.f, 1.f ); - + gl_rect_2d_simple( width, height ); - + gGL.flush(); } - // composite color layers - for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) + if (mIsVisible) { - LLTexLayerInterface* layer = *iter; - if (layer->getRenderPass() == LLTexLayer::RP_COLOR) + // composite color layers + for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) { - gGL.flush(); - success &= layer->render(x, y, width, height, render_morph); - gGL.flush(); - if (layer->isMorphValid()) + LLTexLayerInterface* layer = *iter; + if (layer->getRenderPass() == LLTexLayer::RP_COLOR) { - mAvatar->setMorphMasksValid(TRUE, mBakedTexIndex); + gGL.flush(); + success &= layer->render(x, y, width, height); + gGL.flush(); } } - } + + renderAlphaMaskTextures(x, y, width, height, false); - renderAlphaMaskTextures(x, y, width, height, false); + stop_glerror(); + } + else + { + gGL.flush(); - stop_glerror(); + gGL.setSceneBlendType(LLRender::BT_REPLACE); + LLGLDisable no_alpha(GL_ALPHA_TEST); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.color4f( 0.f, 0.f, 0.f, 0.f ); + + gl_rect_2d_simple( width, height ); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + + gGL.flush(); + + } return success; } @@ -786,12 +828,10 @@ void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 width, S32 height) { memset(data, 255, width * height); - BOOL render_morph = mAvatar->morphMaskNeedsUpdate(mBakedTexIndex); - for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) { LLTexLayerInterface* layer = *iter; - layer->gatherAlphaMasks(data, mComposite->getOriginX(),mComposite->getOriginY(), width, height, render_morph); + layer->gatherAlphaMasks(data, mComposite->getOriginX(),mComposite->getOriginY(), width, height); } // Set alpha back to that of our alpha masks. @@ -863,6 +903,31 @@ void LLTexLayerSet::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_ mAvatar->applyMorphMask(tex_data, width, height, num_components, mBakedTexIndex); } +BOOL LLTexLayerSet::isMorphValid() +{ + for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) + { + LLTexLayerInterface* layer = *iter; + if (layer && !layer->isMorphValid()) + { + return FALSE; + } + } + return TRUE; +} + +void LLTexLayerSet::invalidateMorphMasks() +{ + for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) + { + LLTexLayerInterface* layer = *iter; + if (layer) + { + layer->invalidateMorphMasks(); + } + } +} + //----------------------------------------------------------------------------- // LLTexLayerInfo @@ -1075,7 +1140,11 @@ LLTexLayerInterface::LLTexLayerInterface(const LLTexLayerInterface &layer, LLWea BOOL LLTexLayerInterface::setInfo(const LLTexLayerInfo *info, LLWearable* wearable ) // This sets mInfo and calls initialization functions { - llassert(mInfo == NULL); + //llassert(mInfo == NULL); // nyx says this is probably bogus but needs investigating + if (mInfo != NULL) // above llassert(), but softened into a warning + { + llwarns << "BAD STUFF! mInfo != NULL" << llendl; + } mInfo = info; //mID = info->mID; // No ID @@ -1282,7 +1351,7 @@ void LLTexLayer::calculateTexLayerColor(const param_color_list_t ¶m_list, LL } } -BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph) +BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) { LLGLEnable color_mat(GL_COLOR_MATERIAL); gPipeline.disableLights(); @@ -1333,7 +1402,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph) } }//*/ - renderMorphMasks(x, y, width, height, net_color, render_morph); + renderMorphMasks(x, y, width, height, net_color); alpha_mask_specified = TRUE; gGL.flush(); gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ONE_MINUS_DEST_ALPHA); @@ -1371,7 +1440,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph) LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode(); - gGL.getTexUnit(0)->bind(tex); + gGL.getTexUnit(0)->bind(tex, TRUE); gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); gl_rect_2d_simple_tex( width, height ); @@ -1393,7 +1462,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph) LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); if( tex ) { - gGL.getTexUnit(0)->bind(tex); + gGL.getTexUnit(0)->bind(tex, TRUE); gl_rect_2d_simple_tex( width, height ); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } @@ -1506,7 +1575,7 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) if( tex ) { LLGLSNoAlphaTest gls_no_alpha_test; - gGL.getTexUnit(0)->bind(tex); + gGL.getTexUnit(0)->bind(tex, TRUE); gl_rect_2d_simple_tex( width, height ); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } @@ -1534,12 +1603,12 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) return success; } -/*virtual*/ void LLTexLayer::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, BOOL render_morph) +/*virtual*/ void LLTexLayer::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) { - addAlphaMask(data, originX, originY, width, height, render_morph); + addAlphaMask(data, originX, originY, width, height); } -BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, BOOL render_morph) +BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color) { BOOL success = TRUE; @@ -1578,46 +1647,38 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC // Accumulate the alpha component of the texture if( getInfo()->mLocalTexture != -1 ) { - LLViewerTexture* tex = mLocalTextureObject->getImage(); - if( tex && (tex->getComponents() == 4) ) - { - LLGLSNoAlphaTest gls_no_alpha_test; + LLViewerTexture* tex = mLocalTextureObject->getImage(); + if( tex && (tex->getComponents() == 4) ) + { + LLGLSNoAlphaTest gls_no_alpha_test; - LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode(); - - gGL.getTexUnit(0)->bind(tex); - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode(); + + gGL.getTexUnit(0)->bind(tex, TRUE); + gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - gl_rect_2d_simple_tex( width, height ); + gl_rect_2d_simple_tex( width, height ); - gGL.getTexUnit(0)->setTextureAddressMode(old_mode); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - } - else - { - success = FALSE; - } + gGL.getTexUnit(0)->setTextureAddressMode(old_mode); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } + } if( !getInfo()->mStaticImageFileName.empty() ) { - LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); - if( tex ) - { - if( (tex->getComponents() == 4) || - ( (tex->getComponents() == 1) && getInfo()->mStaticImageIsMask ) ) - { - LLGLSNoAlphaTest gls_no_alpha_test; - gGL.getTexUnit(0)->bind(tex); - gl_rect_2d_simple_tex( width, height ); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - } - } - else + LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); + if( tex ) + { + if( (tex->getComponents() == 4) || + ( (tex->getComponents() == 1) && getInfo()->mStaticImageIsMask ) ) { - success = FALSE; + LLGLSNoAlphaTest gls_no_alpha_test; + gGL.getTexUnit(0)->bind(tex, TRUE); + gl_rect_2d_simple_tex( width, height ); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } } + } // Draw a rectangle with the layer color to multiply the alpha by that color's alpha. // Note: we're still using gGL.blendFunc( GL_DST_ALPHA, GL_ZERO ); @@ -1634,7 +1695,7 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC gGL.setColorMask(true, true); - if (render_morph && mHasMorph && success) + if (hasMorph() && success) { LLCRC alpha_mask_crc; const LLUUID& uuid = getUUID(); @@ -1674,7 +1735,7 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC return success; } -void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height, BOOL render_morph) +void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height) { S32 size = width * height; U8* alphaData = getAlphaData(); @@ -1684,7 +1745,7 @@ void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 findNetColor( &net_color ); // TODO: eliminate need for layer morph mask valid flag invalidateMorphMasks(); - renderMorphMasks(originX, originY, width, height, net_color, render_morph); + renderMorphMasks(originX, originY, width, height, net_color); alphaData = getAlphaData(); } if (alphaData) @@ -1700,6 +1761,19 @@ void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 } } +/*virtual*/ BOOL LLTexLayer::isInvisibleAlphaMask() +{ + if (mLocalTextureObject) + { + if (mLocalTextureObject->getID() == IMG_INVISIBLE) + { + return TRUE; + } + } + + return FALSE; +} + // private helper function LLUUID LLTexLayer::getUUID() { @@ -1787,7 +1861,7 @@ U32 LLTexLayerTemplate::updateWearableCache() } LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) { - if (mWearableCache.size() <= i || i < 0) + if (mWearableCache.size() <= i) { return NULL; } @@ -1805,7 +1879,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) return layer; } -/*virtual*/ BOOL LLTexLayerTemplate::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph) +/*virtual*/ BOOL LLTexLayerTemplate::render(S32 x, S32 y, S32 width, S32 height) { BOOL success = TRUE; updateWearableCache(); @@ -1825,9 +1899,9 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) } if (layer) { - wearable->writeToAvatar(FALSE, FALSE); + wearable->writeToAvatar(); layer->setLTO(lto); - success &= layer->render(x,y,width,height,render_morph); + success &= layer->render(x,y,width,height); } } @@ -1849,7 +1923,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) return success; } -/*virtual*/ void LLTexLayerTemplate::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, BOOL render_morph) +/*virtual*/ void LLTexLayerTemplate::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) { U32 num_wearables = updateWearableCache(); for (U32 i = 0; i < num_wearables; i++) @@ -1857,7 +1931,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) LLTexLayer *layer = getLayer(i); if (layer) { - layer->addAlphaMask(data, originX, originY, width, height, render_morph); + layer->addAlphaMask(data, originX, originY, width, height); } } } @@ -1889,6 +1963,23 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) } } +/*virtual*/ BOOL LLTexLayerTemplate::isInvisibleAlphaMask() +{ + U32 num_wearables = updateWearableCache(); + for (U32 i = 0; i < num_wearables; i++) + { + LLTexLayer *layer = getLayer(i); + if (layer) + { + if (layer->isInvisibleAlphaMask()) + { + return TRUE; + } + } + } + + return FALSE; +} //----------------------------------------------------------------------------- @@ -2034,7 +2125,7 @@ LLViewerTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_n // that once an image is a mask it's always a mask. tex->setExplicitFormat( GL_ALPHA8, GL_ALPHA ); } - tex->createGLTexture(0, image_raw); + tex->createGLTexture(0, image_raw, 0, TRUE, LLViewerTexture::LOCAL); gGL.getTexUnit(0)->bind(tex); tex->setAddressMode(LLTexUnit::TAM_CLAMP); |