Files
SingularityViewer/indra/llappearance/lltexlayer.cpp

201 lines
5.9 KiB
C++

/**
* @file lltexlayer.cpp
* @brief A texture layer. Used for avatars.
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltexlayer.h"
#include "llavatarappearance.h"
#include "llcrc.h"
#include "imageids.h"
#include "llimagej2c.h"
#include "llimagetga.h"
#include "lldir.h"
#include "llvfile.h"
#include "llvfs.h"
#include "lltexlayerparams.h"
#include "lltexturemanagerbridge.h"
//#include "llrender2dutils.h"
//#include "llwearable.h"
//#include "llwearabledata.h"
#include "llvertexbuffer.h"
#include "llviewervisualparam.h"
//#include "../tools/imdebug/imdebug.h"
using namespace LLAvatarAppearanceDefines;
//-----------------------------------------------------------------------------
// LLTexLayerSet
// An ordered set of texture layers that get composited into a single texture.
//-----------------------------------------------------------------------------
BOOL LLTexLayerSet::sHasCaches = FALSE;
LLTexLayerSet::LLTexLayerSet(LLAvatarAppearance* const appearance) :
mAvatarAppearance( appearance )
{
}
//-----------------------------------------------------------------------------
// LLTexLayerStaticImageList
//-----------------------------------------------------------------------------
LLTexLayerStaticImageList::LLTexLayerStaticImageList() :
mGLBytes(0),
mTGABytes(0),
mImageNames(16384)
{
}
LLTexLayerStaticImageList::~LLTexLayerStaticImageList()
{
deleteCachedImages();
}
void LLTexLayerStaticImageList::dumpByteCount() const
{
llinfos << "Avatar Static Textures " <<
"KB GL:" << (mGLBytes / 1024) <<
"KB TGA:" << (mTGABytes / 1024) << "KB" << llendl;
}
void LLTexLayerStaticImageList::deleteCachedImages()
{
if( mGLBytes || mTGABytes )
{
llinfos << "Clearing Static Textures " <<
"KB GL:" << (mGLBytes / 1024) <<
"KB TGA:" << (mTGABytes / 1024) << "KB" << llendl;
//mStaticImageLists uses LLPointers, clear() will cause deletion
mStaticImageListTGA.clear();
mStaticImageList.clear();
mGLBytes = 0;
mTGABytes = 0;
}
}
// Note: in general, for a given image image we'll call either getImageTga() or getTexture().
// We call getImageTga() if the image is used as an alpha gradient.
// Otherwise, we call getTexture()
// Returns an LLImageTGA that contains the encoded data from a tga file named file_name.
// Caches the result to speed identical subsequent requests.
static LLFastTimer::DeclareTimer FTM_LOAD_STATIC_TGA("getImageTGA");
LLImageTGA* LLTexLayerStaticImageList::getImageTGA(const std::string& file_name)
{
LLFastTimer t(FTM_LOAD_STATIC_TGA);
const char *namekey = mImageNames.addString(file_name);
image_tga_map_t::const_iterator iter = mStaticImageListTGA.find(namekey);
if( iter != mStaticImageListTGA.end() )
{
return iter->second;
}
else
{
std::string path;
path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,file_name);
LLPointer<LLImageTGA> image_tga = new LLImageTGA( path );
if( image_tga->getDataSize() > 0 )
{
mStaticImageListTGA[ namekey ] = image_tga;
mTGABytes += image_tga->getDataSize();
return image_tga;
}
else
{
return NULL;
}
}
}
// 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.
static LLFastTimer::DeclareTimer FTM_LOAD_STATIC_TEXTURE("getTexture");
LLGLTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_name, BOOL is_mask)
{
LLFastTimer t(FTM_LOAD_STATIC_TEXTURE);
LLPointer<LLGLTexture> tex;
const char *namekey = mImageNames.addString(file_name);
texture_map_t::const_iterator iter = mStaticImageList.find(namekey);
if( iter != mStaticImageList.end() )
{
tex = iter->second;
}
else
{
llassert(gTextureManagerBridgep);
tex = gTextureManagerBridgep->getLocalTexture( FALSE );
LLPointer<LLImageRaw> image_raw = new LLImageRaw;
if( loadImageRaw( file_name, image_raw ) )
{
if( (image_raw->getComponents() == 1) && is_mask )
{
// Note: these are static, unchanging images so it's ok to assume
// that once an image is a mask it's always a mask.
tex->setExplicitFormat( GL_ALPHA8, GL_ALPHA );
}
tex->createGLTexture(0, image_raw, 0, TRUE, LLGLTexture::LOCAL);
gGL.getTexUnit(0)->bind(tex);
tex->setAddressMode(LLTexUnit::TAM_CLAMP);
mStaticImageList [ namekey ] = tex;
mGLBytes += (S32)tex->getWidth() * tex->getHeight() * tex->getComponents();
}
else
{
tex = NULL;
}
}
return tex;
}
// Reads a .tga file, decodes it, and puts the decoded data in image_raw.
// Returns TRUE if successful.
static LLFastTimer::DeclareTimer FTM_LOAD_IMAGE_RAW("loadImageRaw");
BOOL LLTexLayerStaticImageList::loadImageRaw(const std::string& file_name, LLImageRaw* image_raw)
{
LLFastTimer t(FTM_LOAD_IMAGE_RAW);
BOOL success = FALSE;
std::string path;
path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,file_name);
LLPointer<LLImageTGA> image_tga = new LLImageTGA( path );
if( image_tga->getDataSize() > 0 )
{
// Copy data from tga to raw.
success = image_tga->decode( image_raw );
}
return success;
}