Innitial commit of experimental v2 texture system port work. Compiles and runs on windows, at least. Fixing bugs as they come.
Need to test: localassetbrowser preview related floaters hgfloatertexteditor maps media textures! Currently very hacky web browser alpha masks on avatars bumpmaps Are all sky components appearing? LLViewerDynamicTexture (texture baking, browser, animated textures, anim previews, etc) Snapshot related features Customize avatar vfs floater UI textures in general Texture priority issues
This commit is contained in:
@@ -45,8 +45,8 @@
|
||||
#include "lltexlayer.h"
|
||||
#include "llui.h"
|
||||
#include "llvfile.h"
|
||||
#include "llviewerimagelist.h"
|
||||
#include "llviewerimagelist.h"
|
||||
#include "llviewertexturelist.h"
|
||||
#include "llviewertexturelist.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llviewerstats.h"
|
||||
#include "llviewerwindow.h"
|
||||
@@ -74,7 +74,7 @@ LLBakedUploadData::LLBakedUploadData( LLVOAvatar* avatar,
|
||||
LLTexLayerSetBuffer* layerset_buffer,
|
||||
const LLUUID & id ) :
|
||||
mAvatar( avatar ),
|
||||
mLayerSet( layerset ),
|
||||
mTexLayerSet( layerset ),
|
||||
mLayerSetBuffer( layerset_buffer ),
|
||||
mID(id)
|
||||
{
|
||||
@@ -96,7 +96,7 @@ LLBakedUploadData::LLBakedUploadData( LLVOAvatar* avatar,
|
||||
LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* owner, S32 width, S32 height)
|
||||
:
|
||||
// ORDER_LAST => must render these after the hints are created.
|
||||
LLDynamicTexture( width, height, 4, LLDynamicTexture::ORDER_LAST, TRUE ),
|
||||
LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ),
|
||||
mNeedsUpdate( TRUE ),
|
||||
mNeedsUpload( FALSE ),
|
||||
mUploadPending( FALSE ), // Not used for any logic here, just to sync sending of updates
|
||||
@@ -113,7 +113,7 @@ LLTexLayerSetBuffer::~LLTexLayerSetBuffer()
|
||||
destroyGLTexture();
|
||||
for (S32 order = 0; order < ORDER_COUNT; order++)
|
||||
{
|
||||
LLDynamicTexture::sInstances[order].erase(this); // will fail in all but one case.
|
||||
LLViewerDynamicTexture::sInstances[order].erase(this); // will fail in all but one case.
|
||||
}
|
||||
if (mTexLayerSet->mComposite == this)
|
||||
{
|
||||
@@ -122,16 +122,22 @@ LLTexLayerSetBuffer::~LLTexLayerSetBuffer()
|
||||
}
|
||||
}
|
||||
|
||||
//virtual
|
||||
S8 LLTexLayerSetBuffer::getType() const
|
||||
{
|
||||
return LLViewerDynamicTexture::LL_TEX_LAYER_SET_BUFFER ;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLTexLayerSetBuffer::restoreGLTexture()
|
||||
{
|
||||
LLDynamicTexture::restoreGLTexture() ;
|
||||
LLViewerDynamicTexture::restoreGLTexture() ;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLTexLayerSetBuffer::destroyGLTexture()
|
||||
{
|
||||
LLDynamicTexture::destroyGLTexture() ;
|
||||
LLViewerDynamicTexture::destroyGLTexture() ;
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -192,7 +198,7 @@ void LLTexLayerSetBuffer::pushProjection()
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
gGL.pushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f);
|
||||
glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
gGL.pushMatrix();
|
||||
@@ -238,14 +244,14 @@ void LLTexLayerSetBuffer::preRender(BOOL clear_depth)
|
||||
pushProjection();
|
||||
|
||||
// keep depth buffer, we don't need to clear it
|
||||
LLDynamicTexture::preRender(FALSE);
|
||||
LLViewerDynamicTexture::preRender(FALSE);
|
||||
}
|
||||
|
||||
void LLTexLayerSetBuffer::postRender(BOOL success)
|
||||
{
|
||||
popProjection();
|
||||
|
||||
LLDynamicTexture::postRender(success);
|
||||
LLViewerDynamicTexture::postRender(success);
|
||||
}
|
||||
|
||||
BOOL LLTexLayerSetBuffer::render()
|
||||
@@ -260,7 +266,7 @@ BOOL LLTexLayerSetBuffer::render()
|
||||
|
||||
// Composite the color data
|
||||
LLGLSUIDefault gls_ui;
|
||||
success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mWidth, mHeight );
|
||||
success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight );
|
||||
gGL.flush();
|
||||
|
||||
if( upload_now )
|
||||
@@ -295,7 +301,7 @@ BOOL LLTexLayerSetBuffer::render()
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
|
||||
// we have valid texture data now
|
||||
mTexture->setGLTextureCreated(true);
|
||||
mGLTexturep->setGLTextureCreated(true);
|
||||
mNeedsUpdate = FALSE;
|
||||
|
||||
return success;
|
||||
@@ -303,7 +309,7 @@ BOOL LLTexLayerSetBuffer::render()
|
||||
|
||||
bool LLTexLayerSetBuffer::isInitialized(void) const
|
||||
{
|
||||
return mTexture.notNull() && mTexture->isGLTextureCreated();
|
||||
return mGLTexturep.notNull() && mGLTexturep->isGLTextureCreated();
|
||||
}
|
||||
|
||||
BOOL LLTexLayerSetBuffer::updateImmediate()
|
||||
@@ -323,44 +329,35 @@ BOOL LLTexLayerSetBuffer::updateImmediate()
|
||||
|
||||
void LLTexLayerSetBuffer::readBackAndUpload()
|
||||
{
|
||||
// pointers for storing data to upload
|
||||
U8* baked_color_data = new U8[ mWidth * mHeight * 4 ];
|
||||
|
||||
glReadPixels(mOrigin.mX, mOrigin.mY, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data );
|
||||
stop_glerror();
|
||||
|
||||
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.)
|
||||
// Don't need caches since we're baked now. (note: we won't *really* be baked
|
||||
// until this image is sent to the server and the Avatar Appearance message is received.)
|
||||
mTexLayerSet->deleteCaches();
|
||||
|
||||
// Get the COLOR information from our texture
|
||||
U8* baked_color_data = new U8[ mFullWidth * mFullHeight * 4 ];
|
||||
glReadPixels(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data );
|
||||
stop_glerror();
|
||||
|
||||
// Get the MASK information from our texture
|
||||
LLGLSUIDefault gls_ui;
|
||||
|
||||
LLPointer<LLImageRaw> baked_mask_image = new LLImageRaw(mWidth, mHeight, 1 );
|
||||
LLPointer<LLImageRaw> baked_mask_image = new LLImageRaw(mFullWidth, mFullHeight, 1 );
|
||||
U8* baked_mask_data = baked_mask_image->getData();
|
||||
|
||||
mTexLayerSet->gatherAlphaMasks(baked_mask_data, mWidth, mHeight);
|
||||
mTexLayerSet->gatherAlphaMasks(baked_mask_data, mFullWidth, mFullHeight);
|
||||
// imdebug("lum b=8 w=%d h=%d %p", mWidth, mHeight, baked_mask_data);
|
||||
|
||||
|
||||
// writes into baked_color_data
|
||||
const char* comment_text = NULL;
|
||||
|
||||
S32 baked_image_components = 5; // red green blue bump clothing
|
||||
LLPointer<LLImageRaw> baked_image = new LLImageRaw( mWidth, mHeight, baked_image_components );
|
||||
LLPointer<LLImageRaw> baked_image = new LLImageRaw( mFullWidth, mFullHeight, baked_image_components );
|
||||
U8* baked_image_data = baked_image->getData();
|
||||
|
||||
comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // 5 channels: rgb, heightfield/alpha, mask
|
||||
|
||||
S32 i = 0;
|
||||
for (S32 u = 0; u < mWidth; u++)
|
||||
for (S32 u=0; u < mFullWidth; u++)
|
||||
{
|
||||
for (S32 v = 0; v < mHeight; v++)
|
||||
for (S32 v=0; v < mFullHeight; v++)
|
||||
{
|
||||
baked_image_data[5 * i + 0] = baked_color_data[4 * i + 0];
|
||||
baked_image_data[5 * i + 1] = baked_color_data[4 * i + 1];
|
||||
@@ -373,21 +370,19 @@ void LLTexLayerSetBuffer::readBackAndUpload()
|
||||
|
||||
LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C;
|
||||
compressedImage->setRate(0.f);
|
||||
LLTransactionID tid;
|
||||
LLAssetID asset_id;
|
||||
tid.generate();
|
||||
asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
|
||||
|
||||
BOOL res = false;
|
||||
if( compressedImage->encode(baked_image, comment_text))
|
||||
const char* comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // writes into baked_color_data. 5 channels (rgb, heightfield/alpha, mask)
|
||||
if (compressedImage->encode(baked_image, comment_text))
|
||||
{
|
||||
res = LLVFile::writeFile(compressedImage->getData(), compressedImage->getDataSize(),
|
||||
gVFS, asset_id, LLAssetType::AT_TEXTURE);
|
||||
if (res)
|
||||
LLTransactionID tid;
|
||||
tid.generate();
|
||||
const LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
|
||||
if (LLVFile::writeFile(compressedImage->getData(), compressedImage->getDataSize(),
|
||||
gVFS, asset_id, LLAssetType::AT_TEXTURE))
|
||||
{
|
||||
LLPointer<LLImageJ2C> integrity_test = new LLImageJ2C;
|
||||
// Read back the file and validate.
|
||||
BOOL valid = FALSE;
|
||||
S32 file_size;
|
||||
LLPointer<LLImageJ2C> integrity_test = new LLImageJ2C;
|
||||
S32 file_size = 0;
|
||||
U8* data = LLVFile::readFile(gVFS, asset_id, LLAssetType::AT_TEXTURE, &file_size);
|
||||
if (data)
|
||||
{
|
||||
@@ -405,22 +400,18 @@ void LLTexLayerSetBuffer::readBackAndUpload()
|
||||
new LLBakedUploadData( gAgent.getAvatarObject(), this->mTexLayerSet, this, asset_id );
|
||||
mUploadID = asset_id;
|
||||
|
||||
// upload the image
|
||||
std::string url = gAgent.getRegion()->getCapability("UploadBakedTexture");
|
||||
|
||||
// Upload the image
|
||||
const std::string url = gAgent.getRegion()->getCapability("UploadBakedTexture");
|
||||
if(!url.empty()
|
||||
&& !LLPipeline::sForceOldBakedUpload) // Toggle the debug setting UploadBakedTexOld to change between the new caps method and old method
|
||||
&& !LLPipeline::sForceOldBakedUpload) // toggle debug setting UploadBakedTexOld to change between the new caps method and old method
|
||||
{
|
||||
llinfos << "Baked texture upload via capability of " << mUploadID << " to " << url << llendl;
|
||||
|
||||
LLSD body = LLSD::emptyMap();
|
||||
// The responder will call LLTexLayerSetBuffer::onTextureUploadComplete()
|
||||
LLHTTPClient::post(url, body, new LLSendTexLayerResponder(body, mUploadID, LLAssetType::AT_TEXTURE, baked_upload_data));
|
||||
// Responder will call LLTexLayerSetBuffer::onTextureUploadComplete()
|
||||
llinfos << "Baked texture upload via capability of " << mUploadID << " to " << url << llendl;
|
||||
}
|
||||
else
|
||||
{
|
||||
llinfos << "Baked texture upload via Asset Store." << llendl;
|
||||
// gAssetStorage->storeAssetData(mTransactionID, LLAssetType::AT_IMAGE_JPEG, &uploadCallback, (void *)this, FALSE);
|
||||
gAssetStorage->storeAssetData(tid,
|
||||
LLAssetType::AT_TEXTURE,
|
||||
LLTexLayerSetBuffer::onTextureUploadComplete,
|
||||
@@ -428,23 +419,26 @@ void LLTexLayerSetBuffer::readBackAndUpload()
|
||||
TRUE, // temp_file
|
||||
TRUE, // is_priority
|
||||
TRUE); // store_local
|
||||
llinfos << "Baked texture upload via Asset Store." << llendl;
|
||||
}
|
||||
|
||||
mNeedsUpload = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The read back and validate operation failed. Remove the uploaded file.
|
||||
mUploadPending = FALSE;
|
||||
llinfos << "unable to create baked upload file: corrupted" << llendl;
|
||||
LLVFile file(gVFS, asset_id, LLAssetType::AT_TEXTURE, LLVFile::WRITE);
|
||||
file.remove();
|
||||
llinfos << "Unable to create baked upload file (reason: corrupted)." << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!res)
|
||||
else
|
||||
{
|
||||
// The VFS write file operation failed.
|
||||
mUploadPending = FALSE;
|
||||
llinfos << "unable to create baked upload file" << llendl;
|
||||
llinfos << "Unable to create baked upload file (reason: failed to write file)" << llendl;
|
||||
}
|
||||
|
||||
delete [] baked_color_data;
|
||||
@@ -452,17 +446,20 @@ void LLTexLayerSetBuffer::readBackAndUpload()
|
||||
|
||||
|
||||
// static
|
||||
void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid, void* userdata, S32 result, LLExtStat ext_status) // StoreAssetData callback (not fixed)
|
||||
void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid,
|
||||
void* userdata,
|
||||
S32 result,
|
||||
LLExtStat ext_status) // StoreAssetData callback (not fixed)
|
||||
{
|
||||
LLBakedUploadData* baked_upload_data = (LLBakedUploadData*)userdata;
|
||||
|
||||
LLVOAvatar* avatar = gAgent.getAvatarObject();
|
||||
|
||||
if (avatar && !avatar->isDead() && baked_upload_data &&
|
||||
baked_upload_data->mAvatar == avatar && // Sanity check: only the user's avatar should be uploading textures.
|
||||
baked_upload_data->mLayerSet->hasComposite())
|
||||
{
|
||||
LLTexLayerSetBuffer* layerset_buffer = baked_upload_data->mLayerSet->getComposite();
|
||||
if ((result == 0) &&
|
||||
isAgentAvatarValid() &&
|
||||
!gAgent.getAvatarObject()->isDead() &&
|
||||
(baked_upload_data->mAvatar == gAgent.getAvatarObject()) && // Sanity check: only the user's avatar should be uploading textures.
|
||||
(baked_upload_data->mTexLayerSet->hasComposite()))
|
||||
{
|
||||
LLTexLayerSetBuffer* layerset_buffer = baked_upload_data->mTexLayerSet->getComposite();
|
||||
S32 failures = layerset_buffer->mUploadFailCount;
|
||||
layerset_buffer->mUploadFailCount = 0;
|
||||
|
||||
@@ -485,10 +482,10 @@ void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid, void* user
|
||||
|
||||
if (result >= 0)
|
||||
{
|
||||
ETextureIndex baked_te = avatar->getBakedTE(layerset_buffer->mTexLayerSet);
|
||||
ETextureIndex baked_te = gAgent.getAvatarObject()->getBakedTE(layerset_buffer->mTexLayerSet);
|
||||
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);
|
||||
gAgent.getAvatarObject()->setNewBakedTexture(baked_te, uuid);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -513,7 +510,7 @@ void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid, void* user
|
||||
llinfos << "Received baked texture out of date, ignored." << llendl;
|
||||
}
|
||||
|
||||
avatar->dirtyMesh();
|
||||
gAgent.getAvatarObject()->dirtyMesh();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -621,7 +618,6 @@ LLTexLayerSet::~LLTexLayerSet()
|
||||
deleteCaches();
|
||||
std::for_each(mLayerList.begin(), mLayerList.end(), DeletePointer());
|
||||
std::for_each(mMaskLayerList.begin(), mMaskLayerList.end(), DeletePointer());
|
||||
delete mComposite;
|
||||
mComposite = NULL;
|
||||
}
|
||||
|
||||
@@ -726,11 +722,11 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height,
|
||||
LLGLSNoAlphaTest gls_no_alpha_test;
|
||||
gGL.flush();
|
||||
{
|
||||
LLImageGL* image_gl = gTexStaticImageList.getImageGL(info->mStaticAlphaFileName, TRUE);
|
||||
if (image_gl)
|
||||
LLViewerTexture* tex = gTexStaticImageList.getTexture(info->mStaticAlphaFileName, TRUE);
|
||||
if (tex)
|
||||
{
|
||||
LLGLSUIDefault gls_ui;
|
||||
gGL.getTexUnit(0)->bind(image_gl);
|
||||
gGL.getTexUnit(0)->bind(tex);
|
||||
gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_REPLACE);
|
||||
gl_rect_2d_simple_tex(width, height);
|
||||
}
|
||||
@@ -884,7 +880,6 @@ void LLTexLayerSet::destroyComposite()
|
||||
{
|
||||
if( mComposite )
|
||||
{
|
||||
delete mComposite;
|
||||
mComposite = NULL;
|
||||
}
|
||||
}
|
||||
@@ -1397,20 +1392,20 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
|
||||
if( (getInfo()->mLocalTexture != -1) && !getInfo()->mUseLocalTextureAlphaOnly )
|
||||
{
|
||||
{
|
||||
LLImageGL* image_gl = NULL;
|
||||
if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) )
|
||||
LLViewerTexture* tex = NULL;
|
||||
if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &tex ) )
|
||||
{
|
||||
if (mTexLayerSet->getAvatar()->getLocalTextureID((ETextureIndex)getInfo()->mLocalTexture) == IMG_DEFAULT_AVATAR)
|
||||
{
|
||||
image_gl = NULL;
|
||||
tex = NULL;
|
||||
}
|
||||
if( image_gl )
|
||||
if( tex )
|
||||
{
|
||||
LLGLDisable alpha_test(getInfo()->mWriteAllChannels ? GL_ALPHA_TEST : 0);
|
||||
|
||||
LLTexUnit::eTextureAddressMode old_mode = image_gl->getAddressMode();
|
||||
LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode();
|
||||
|
||||
gGL.getTexUnit(0)->bind(image_gl, TRUE);
|
||||
gGL.getTexUnit(0)->bind(tex, TRUE);
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
|
||||
gl_rect_2d_simple_tex( width, height );
|
||||
@@ -1425,10 +1420,10 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
|
||||
if( !getInfo()->mStaticImageFileName.empty() )
|
||||
{
|
||||
{
|
||||
LLImageGL* image_gl = gTexStaticImageList.getImageGL( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask );
|
||||
if( image_gl )
|
||||
LLViewerTexture* tex = gTexStaticImageList.getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
|
||||
if( tex )
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(image_gl, TRUE);
|
||||
gGL.getTexUnit(0)->bind(tex, TRUE);
|
||||
gl_rect_2d_simple_tex( width, height );
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
}
|
||||
@@ -1479,11 +1474,11 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)
|
||||
|
||||
if (!getInfo()->mStaticImageFileName.empty())
|
||||
{
|
||||
LLImageGL* image_gl = gTexStaticImageList.getImageGL(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
|
||||
if (image_gl)
|
||||
LLViewerTexture* tex = gTexStaticImageList.getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
|
||||
if (tex)
|
||||
{
|
||||
LLGLSNoAlphaTest gls_no_alpha_test;
|
||||
gGL.getTexUnit(0)->bind(image_gl, TRUE);
|
||||
gGL.getTexUnit(0)->bind(tex, TRUE);
|
||||
gl_rect_2d_simple_tex(width, height);
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
}
|
||||
@@ -1496,13 +1491,13 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)
|
||||
{
|
||||
if (getInfo()->mLocalTexture >=0 && getInfo()->mLocalTexture < TEX_NUM_INDICES)
|
||||
{
|
||||
LLImageGL* image_gl = NULL;
|
||||
if (mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl))
|
||||
LLViewerTexture* tex = NULL;
|
||||
if (mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &tex))
|
||||
{
|
||||
if (image_gl)
|
||||
if (tex)
|
||||
{
|
||||
LLGLSNoAlphaTest gls_no_alpha_test;
|
||||
gGL.getTexUnit(0)->bind(image_gl);
|
||||
gGL.getTexUnit(0)->bind(tex);
|
||||
gl_rect_2d_simple_tex(width, height);
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
success = TRUE;
|
||||
@@ -1645,16 +1640,16 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
|
||||
if( getInfo()->mLocalTexture != -1 )
|
||||
{
|
||||
{
|
||||
LLImageGL* image_gl = NULL;
|
||||
if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) )
|
||||
LLViewerTexture* tex = NULL;
|
||||
if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &tex ) )
|
||||
{
|
||||
if( image_gl && (image_gl->getComponents() == 4) )
|
||||
if( tex && (tex->getComponents() == 4) )
|
||||
{
|
||||
LLGLSNoAlphaTest gls_no_alpha_test;
|
||||
|
||||
LLTexUnit::eTextureAddressMode old_mode = image_gl->getAddressMode();
|
||||
LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode();
|
||||
|
||||
gGL.getTexUnit(0)->bind(image_gl, TRUE);
|
||||
gGL.getTexUnit(0)->bind(tex, TRUE);
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
|
||||
gl_rect_2d_simple_tex( width, height );
|
||||
@@ -1668,18 +1663,16 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
|
||||
|
||||
if( !getInfo()->mStaticImageFileName.empty() )
|
||||
{
|
||||
LLViewerTexture* tex = gTexStaticImageList.getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
|
||||
if( tex )
|
||||
{
|
||||
LLImageGL* image_gl = gTexStaticImageList.getImageGL( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask );
|
||||
if( image_gl )
|
||||
if( (tex->getComponents() == 4) ||
|
||||
( (tex->getComponents() == 1) && getInfo()->mStaticImageIsMask ) )
|
||||
{
|
||||
if( (image_gl->getComponents() == 4) ||
|
||||
( (image_gl->getComponents() == 1) && getInfo()->mStaticImageIsMask ) )
|
||||
{
|
||||
LLGLSNoAlphaTest gls_no_alpha_test;
|
||||
gGL.getTexUnit(0)->bind(image_gl, TRUE);
|
||||
gl_rect_2d_simple_tex( width, height );
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1937,12 +1930,12 @@ void LLTexLayerParamAlpha::getCacheByteCount( S32* gl_bytes )
|
||||
iter != sInstances.end(); iter++ )
|
||||
{
|
||||
LLTexLayerParamAlpha* instance = *iter;
|
||||
LLImageGL* image_gl = instance->mCachedProcessedImageGL;
|
||||
if( image_gl )
|
||||
LLViewerTexture* tex = instance->mCachedProcessedTexture;
|
||||
if( tex )
|
||||
{
|
||||
S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents();
|
||||
S32 bytes = (S32)tex->getWidth() * tex->getHeight() * tex->getComponents();
|
||||
|
||||
if( image_gl->getHasGLTexture() )
|
||||
if( tex->hasGLTexture() )
|
||||
{
|
||||
*gl_bytes += bytes;
|
||||
}
|
||||
@@ -1952,7 +1945,7 @@ void LLTexLayerParamAlpha::getCacheByteCount( S32* gl_bytes )
|
||||
|
||||
LLTexLayerParamAlpha::LLTexLayerParamAlpha( LLTexLayer* layer )
|
||||
:
|
||||
mCachedProcessedImageGL( NULL ),
|
||||
mCachedProcessedTexture( NULL ),
|
||||
mTexLayer( layer ),
|
||||
mNeedsCreateTexture( FALSE ),
|
||||
mStaticImageInvalid( FALSE ),
|
||||
@@ -1990,7 +1983,7 @@ BOOL LLTexLayerParamAlpha::setInfo(LLTexLayerParamAlphaInfo *info)
|
||||
void LLTexLayerParamAlpha::deleteCaches()
|
||||
{
|
||||
mStaticImageTGA = NULL; // deletes image
|
||||
mCachedProcessedImageGL = NULL;
|
||||
mCachedProcessedTexture = NULL;
|
||||
mStaticImageRaw = NULL;
|
||||
mNeedsCreateTexture = FALSE;
|
||||
}
|
||||
@@ -2106,22 +2099,22 @@ BOOL LLTexLayerParamAlpha::render( S32 x, S32 y, S32 width, S32 height )
|
||||
|
||||
const S32 image_tga_width = mStaticImageTGA->getWidth();
|
||||
const S32 image_tga_height = mStaticImageTGA->getHeight();
|
||||
if( !mCachedProcessedImageGL ||
|
||||
(mCachedProcessedImageGL->getWidth() != image_tga_width) ||
|
||||
(mCachedProcessedImageGL->getHeight() != image_tga_height) ||
|
||||
if( !mCachedProcessedTexture ||
|
||||
(mCachedProcessedTexture->getWidth() != image_tga_width) ||
|
||||
(mCachedProcessedTexture->getHeight() != image_tga_height) ||
|
||||
(weight_changed) )
|
||||
{
|
||||
// llinfos << "Building Cached Alpha: " << mName << ": (" << mStaticImageRaw->getWidth() << ", " << mStaticImageRaw->getHeight() << ") " << effective_weight << llendl;
|
||||
mCachedEffectiveWeight = effective_weight;
|
||||
|
||||
if( !mCachedProcessedImageGL )
|
||||
if( !mCachedProcessedTexture )
|
||||
{
|
||||
mCachedProcessedImageGL = new LLImageGL( image_tga_width, image_tga_height, 1, FALSE);
|
||||
mCachedProcessedTexture = LLViewerTextureManager::getLocalTexture( image_tga_width, image_tga_height, 1, FALSE );
|
||||
|
||||
// We now have something in one of our caches
|
||||
LLTexLayerSet::sHasCaches |= mCachedProcessedImageGL ? TRUE : FALSE;
|
||||
LLTexLayerSet::sHasCaches |= mCachedProcessedTexture ? TRUE : FALSE;
|
||||
|
||||
mCachedProcessedImageGL->setExplicitFormat( GL_ALPHA8, GL_ALPHA );
|
||||
mCachedProcessedTexture->setExplicitFormat( GL_ALPHA8, GL_ALPHA );
|
||||
}
|
||||
|
||||
// Applies domain and effective weight to data as it is decoded. Also resizes the raw image if needed.
|
||||
@@ -2131,20 +2124,20 @@ BOOL LLTexLayerParamAlpha::render( S32 x, S32 y, S32 width, S32 height )
|
||||
mNeedsCreateTexture = TRUE;
|
||||
}
|
||||
|
||||
if( mCachedProcessedImageGL )
|
||||
if( mCachedProcessedTexture )
|
||||
{
|
||||
{
|
||||
// Create the GL texture, and then hang onto it for future use.
|
||||
if( mNeedsCreateTexture )
|
||||
{
|
||||
mCachedProcessedImageGL->createGLTexture(0, mStaticImageRaw, 0, TRUE, LLViewerImageBoostLevel::TEXLAYER_CACHE);
|
||||
mCachedProcessedTexture->createGLTexture(0, mStaticImageRaw, 0, TRUE, LLViewerTexture::BOOST_AVATAR_SELF);
|
||||
mNeedsCreateTexture = FALSE;
|
||||
gGL.getTexUnit(0)->bind(mCachedProcessedImageGL);
|
||||
mCachedProcessedImageGL->setAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
gGL.getTexUnit(0)->bind(mCachedProcessedTexture);
|
||||
mCachedProcessedTexture->setAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
}
|
||||
|
||||
LLGLSNoAlphaTest gls_no_alpha_test;
|
||||
gGL.getTexUnit(0)->bind(mCachedProcessedImageGL, TRUE);
|
||||
gGL.getTexUnit(0)->bind(mCachedProcessedTexture, TRUE);
|
||||
gl_rect_2d_simple_tex( width, height );
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
stop_glerror();
|
||||
@@ -2155,7 +2148,7 @@ BOOL LLTexLayerParamAlpha::render( S32 x, S32 y, S32 width, S32 height )
|
||||
// (It's not really a "cache" in that case, but the logic is the same)
|
||||
if( !mTexLayer->getTexLayerSet()->getAvatar()->isSelf() )
|
||||
{
|
||||
mCachedProcessedImageGL = NULL;
|
||||
mCachedProcessedTexture = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2509,7 +2502,7 @@ LLTexStaticImageList::~LLTexStaticImageList()
|
||||
deleteCachedImages();
|
||||
}
|
||||
|
||||
void LLTexStaticImageList::dumpByteCount()
|
||||
void LLTexStaticImageList::dumpByteCount() const
|
||||
{
|
||||
llinfos << "Avatar Static Textures " <<
|
||||
"KB GL:" << (mGLBytes / 1024) <<
|
||||
@@ -2527,7 +2520,7 @@ void LLTexStaticImageList::deleteCachedImages()
|
||||
//mStaticImageLists uses LLPointers, clear() will cause deletion
|
||||
|
||||
mStaticImageListTGA.clear();
|
||||
mStaticImageListGL.clear();
|
||||
mStaticImageList.clear();
|
||||
|
||||
mGLBytes = 0;
|
||||
mTGABytes = 0;
|
||||
@@ -2570,19 +2563,19 @@ LLImageTGA* LLTexStaticImageList::getImageTGA(const std::string& file_name)
|
||||
|
||||
// Returns a GL Image (without a backing ImageRaw) that contains the decoded data from a tga file named file_name.
|
||||
// Caches the result to speed identical subsequent requests.
|
||||
LLImageGL* LLTexStaticImageList::getImageGL(const std::string& file_name, BOOL is_mask )
|
||||
LLViewerTexture* LLTexStaticImageList::getTexture(const std::string& file_name, BOOL is_mask)
|
||||
{
|
||||
LLPointer<LLImageGL> image_gl;
|
||||
LLPointer<LLViewerTexture> tex;
|
||||
const char *namekey = sImageNames.addString(file_name);
|
||||
|
||||
image_gl_map_t::iterator iter = mStaticImageListGL.find(namekey);
|
||||
if( iter != mStaticImageListGL.end() )
|
||||
texture_map_t::const_iterator iter = mStaticImageList.find(namekey);
|
||||
if( iter != mStaticImageList.end() )
|
||||
{
|
||||
image_gl = iter->second;
|
||||
tex = iter->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
image_gl = new LLImageGL( FALSE );
|
||||
tex = LLViewerTextureManager::getLocalTexture( FALSE );
|
||||
LLPointer<LLImageRaw> image_raw = new LLImageRaw;
|
||||
if( loadImageRaw( file_name, image_raw ) )
|
||||
{
|
||||
@@ -2590,23 +2583,23 @@ LLImageGL* LLTexStaticImageList::getImageGL(const std::string& file_name, BOOL i
|
||||
{
|
||||
// Note: these are static, unchanging images so it's ok to assume
|
||||
// that once an image is a mask it's always a mask.
|
||||
image_gl->setExplicitFormat( GL_ALPHA8, GL_ALPHA );
|
||||
tex->setExplicitFormat( GL_ALPHA8, GL_ALPHA );
|
||||
}
|
||||
image_gl->createGLTexture(0, image_raw, 0, TRUE, LLViewerImageBoostLevel::OTHER);
|
||||
tex->createGLTexture(0, image_raw, 0, TRUE, LLViewerTexture::LOCAL);
|
||||
|
||||
gGL.getTexUnit(0)->bind(image_gl);
|
||||
image_gl->setAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
gGL.getTexUnit(0)->bind(tex);
|
||||
tex->setAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
|
||||
mStaticImageListGL [ namekey ] = image_gl;
|
||||
mGLBytes += (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents();
|
||||
mStaticImageList [ namekey ] = tex;
|
||||
mGLBytes += (S32)tex->getWidth() * tex->getHeight() * tex->getComponents();
|
||||
}
|
||||
else
|
||||
{
|
||||
image_gl = NULL;
|
||||
tex = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return image_gl;
|
||||
return tex;
|
||||
}
|
||||
|
||||
// Reads a .tga file, decodes it, and puts the decoded data in image_raw.
|
||||
|
||||
Reference in New Issue
Block a user