diff options
Diffstat (limited to 'indra/newview/lltexlayer.cpp')
-rw-r--r-- | indra/newview/lltexlayer.cpp | 262 |
1 files changed, 178 insertions, 84 deletions
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index 5d9046ac90..3f4dab4fea 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); + } } } @@ -269,8 +284,6 @@ void LLTexLayerSetBuffer::readBackAndUpload() llinfos << "Baked " << mTexLayerSet->getBodyRegion() << llendl; LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES); - llassert( gAgent.getAvatarObject() == mTexLayerSet->getAvatar() ); - // We won't need our caches since we're baked now. (Techically, we won't // really be baked until this image is sent to the server and the Avatar // Appearance message is received.) @@ -337,7 +350,7 @@ void LLTexLayerSetBuffer::readBackAndUpload() { // baked_upload_data is owned by the responder and deleted after the request completes LLBakedUploadData* baked_upload_data = - new LLBakedUploadData(gAgent.getAvatarObject(), this->mTexLayerSet, asset_id); + new LLBakedUploadData(gAgentAvatarp, this->mTexLayerSet, asset_id); mUploadID = asset_id; // upload the image @@ -394,12 +407,10 @@ void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid, { LLBakedUploadData* baked_upload_data = (LLBakedUploadData*)userdata; - LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); - if (0 == result && - avatar && - !avatar->isDead() && - baked_upload_data->mAvatar == avatar && // Sanity check: only the user's avatar should be uploading textures. + isAgentAvatarValid() && + !gAgentAvatarp->isDead() && + baked_upload_data->mAvatar == gAgentAvatarp && // Sanity check: only the user's avatar should be uploading textures. baked_upload_data->mTexLayerSet->hasComposite() ) { @@ -424,11 +435,11 @@ void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid, if (result >= 0) { - LLVOAvatarDefines::ETextureIndex baked_te = avatar->getBakedTE(layerset_buffer->mTexLayerSet); + LLVOAvatarDefines::ETextureIndex baked_te = gAgentAvatarp->getBakedTE(layerset_buffer->mTexLayerSet); // Update baked texture info with the new UUID U64 now = LLFrameTimer::getTotalTime(); // Record starting time llinfos << "Baked texture upload took " << (S32)((now - baked_upload_data->mStartTime) / 1000) << " ms" << llendl; - avatar->setNewBakedTexture(baked_te, uuid); + gAgentAvatarp->setNewBakedTexture(baked_te, uuid); } else { @@ -442,7 +453,7 @@ void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid, llinfos << "Received baked texture out of date, ignored." << llendl; } - avatar->dirtyMesh(); + gAgentAvatarp->dirtyMesh(); } else { @@ -551,6 +562,8 @@ LLTexLayerSet::LLTexLayerSet(LLVOAvatarSelf* const avatar) : mComposite( NULL ), mAvatar( avatar ), mUpdatesEnabled( FALSE ), + mIsVisible( TRUE ), + mBakedTexIndex(LLVOAvatarDefines::BAKED_HEAD), mInfo( NULL ) { } @@ -665,44 +678,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 +824,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 +899,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 @@ -1065,7 +1126,8 @@ LLTexLayerInterface::LLTexLayerInterface(LLTexLayerSet* const layer_set): } LLTexLayerInterface::LLTexLayerInterface(const LLTexLayerInterface &layer, LLWearable *wearable): - mTexLayerSet( layer.mTexLayerSet ) + mTexLayerSet( layer.mTexLayerSet ), + mInfo(NULL) { // don't add visual params for cloned layers setInfo(layer.getInfo(), wearable); @@ -1075,7 +1137,12 @@ LLTexLayerInterface::LLTexLayerInterface(const LLTexLayerInterface &layer, LLWea BOOL LLTexLayerInterface::setInfo(const LLTexLayerInfo *info, LLWearable* wearable ) // This sets mInfo and calls initialization functions { - llassert(mInfo == NULL); + // setInfo should only be called once. Code is not robust enough to handle redefinition of a texlayer. + // Not a critical warning, but could be useful for debugging later issues. -Nyx + if (mInfo != NULL) + { + llwarns << "mInfo != NULL" << llendl; + } mInfo = info; //mID = info->mID; // No ID @@ -1282,7 +1349,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 +1400,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 +1438,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 +1460,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 +1573,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 +1601,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 +1645,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 +1693,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 +1733,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 +1743,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 +1759,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 +1859,7 @@ U32 LLTexLayerTemplate::updateWearableCache() } LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) { - if (mWearableCache.size() <= i || i < 0) + if (mWearableCache.size() <= i) { return NULL; } @@ -1805,8 +1877,13 @@ 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) { + if(!mInfo) + { + return FALSE ; + } + BOOL success = TRUE; updateWearableCache(); for (wearable_cache_t::const_iterator iter = mWearableCache.begin(); iter!= mWearableCache.end(); iter++) @@ -1825,9 +1902,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 +1926,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 +1934,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 +1966,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 +2128,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); |