diff options
Diffstat (limited to 'indra/newview/lldrawpoolbump.cpp')
-rw-r--r-- | indra/newview/lldrawpoolbump.cpp | 1382 |
1 files changed, 691 insertions, 691 deletions
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index a0ce0ef6cf..99d0853ff1 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lldrawpoolbump.cpp * @brief LLDrawPoolBump class implementation * * $LicenseInfo:firstyear=2003&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$ */ @@ -54,7 +54,7 @@ //#include "../tools/imdebug/imdebug.h" // static -LLStandardBumpmap gStandardBumpmapList[TEM_BUMPMAP_COUNT]; +LLStandardBumpmap gStandardBumpmapList[TEM_BUMPMAP_COUNT]; LL::WorkQueue::weak_t LLBumpImageList::sMainQueue; LL::WorkQueue::weak_t LLBumpImageList::sTexUpdateQueue; LLRenderTarget LLBumpImageList::sRenderTarget; @@ -84,13 +84,13 @@ static BOOL shiny = FALSE; #define LL_BUMPLIST_MULTITHREADED 1 -// static +// static void LLStandardBumpmap::shutdown() { - LLStandardBumpmap::destroyGL(); + LLStandardBumpmap::destroyGL(); } -// static +// static void LLStandardBumpmap::restoreGL() { addstandard(); @@ -99,12 +99,12 @@ void LLStandardBumpmap::restoreGL() // static void LLStandardBumpmap::addstandard() { - if(!gTextureList.isInitialized()) - { - //Note: loading pre-configuration sometimes triggers this call. - //But it is safe to return here because bump images will be reloaded during initialization later. - return ; - } + if(!gTextureList.isInitialized()) + { + //Note: loading pre-configuration sometimes triggers this call. + //But it is safe to return here because bump images will be reloaded during initialization later. + return ; + } if (LLStartUp::getStartupState() < STATE_SEED_CAP_GRANTED) { @@ -112,99 +112,99 @@ void LLStandardBumpmap::addstandard() return; } - // can't assert; we destroyGL and restoreGL a lot during *first* startup, which populates this list already, THEN we explicitly init the list as part of *normal* startup. Sigh. So clear the list every time before we (re-)add the standard bumpmaps. - //llassert( LLStandardBumpmap::sStandardBumpmapCount == 0 ); - clear(); - LL_INFOS() << "Adding standard bumpmaps." << LL_ENDL; - gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("None"); // BE_NO_BUMP - gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("Brightness"); // BE_BRIGHTNESS - gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("Darkness"); // BE_DARKNESS - - std::string file_name = gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "std_bump.ini" ); - LLFILE* file = LLFile::fopen( file_name, "rt" ); /*Flawfinder: ignore*/ - if( !file ) - { - LL_WARNS() << "Could not open std_bump <" << file_name << ">" << LL_ENDL; - return; - } - - S32 file_version = 0; - - S32 fields_read = fscanf( file, "LLStandardBumpmap version %d", &file_version ); - if( fields_read != 1 ) - { - LL_WARNS() << "Bad LLStandardBumpmap header" << LL_ENDL; - return; - } - - if( file_version > STD_BUMP_LATEST_FILE_VERSION ) - { - LL_WARNS() << "LLStandardBumpmap has newer version (" << file_version << ") than viewer (" << STD_BUMP_LATEST_FILE_VERSION << ")" << LL_ENDL; - return; - } - - while( !feof(file) && (LLStandardBumpmap::sStandardBumpmapCount < (U32)TEM_BUMPMAP_COUNT) ) - { - // *NOTE: This buffer size is hard coded into scanf() below. - char label[2048] = ""; /* Flawfinder: ignore */ - char bump_image_id[2048] = ""; /* Flawfinder: ignore */ - fields_read = fscanf( /* Flawfinder: ignore */ - file, "\n%2047s %2047s", label, bump_image_id); - if( EOF == fields_read ) - { - break; - } - if( fields_read != 2 ) - { - LL_WARNS() << "Bad LLStandardBumpmap entry" << LL_ENDL; - return; - } - -// LL_INFOS() << "Loading bumpmap: " << bump_image_id << " from viewerart" << LL_ENDL; - gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label; - gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage = - LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id)); - gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLGLTexture::LOCAL) ; - gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL ); - gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->forceToSaveRawImage(0, 30.f) ; - LLStandardBumpmap::sStandardBumpmapCount++; - } - - fclose( file ); + // can't assert; we destroyGL and restoreGL a lot during *first* startup, which populates this list already, THEN we explicitly init the list as part of *normal* startup. Sigh. So clear the list every time before we (re-)add the standard bumpmaps. + //llassert( LLStandardBumpmap::sStandardBumpmapCount == 0 ); + clear(); + LL_INFOS() << "Adding standard bumpmaps." << LL_ENDL; + gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("None"); // BE_NO_BUMP + gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("Brightness"); // BE_BRIGHTNESS + gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("Darkness"); // BE_DARKNESS + + std::string file_name = gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "std_bump.ini" ); + LLFILE* file = LLFile::fopen( file_name, "rt" ); /*Flawfinder: ignore*/ + if( !file ) + { + LL_WARNS() << "Could not open std_bump <" << file_name << ">" << LL_ENDL; + return; + } + + S32 file_version = 0; + + S32 fields_read = fscanf( file, "LLStandardBumpmap version %d", &file_version ); + if( fields_read != 1 ) + { + LL_WARNS() << "Bad LLStandardBumpmap header" << LL_ENDL; + return; + } + + if( file_version > STD_BUMP_LATEST_FILE_VERSION ) + { + LL_WARNS() << "LLStandardBumpmap has newer version (" << file_version << ") than viewer (" << STD_BUMP_LATEST_FILE_VERSION << ")" << LL_ENDL; + return; + } + + while( !feof(file) && (LLStandardBumpmap::sStandardBumpmapCount < (U32)TEM_BUMPMAP_COUNT) ) + { + // *NOTE: This buffer size is hard coded into scanf() below. + char label[2048] = ""; /* Flawfinder: ignore */ + char bump_image_id[2048] = ""; /* Flawfinder: ignore */ + fields_read = fscanf( /* Flawfinder: ignore */ + file, "\n%2047s %2047s", label, bump_image_id); + if( EOF == fields_read ) + { + break; + } + if( fields_read != 2 ) + { + LL_WARNS() << "Bad LLStandardBumpmap entry" << LL_ENDL; + return; + } + +// LL_INFOS() << "Loading bumpmap: " << bump_image_id << " from viewerart" << LL_ENDL; + gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label; + gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage = + LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id)); + gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLGLTexture::LOCAL) ; + gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL ); + gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->forceToSaveRawImage(0, 30.f) ; + LLStandardBumpmap::sStandardBumpmapCount++; + } + + fclose( file ); } // static void LLStandardBumpmap::clear() { - LL_INFOS() << "Clearing standard bumpmaps." << LL_ENDL; - for( U32 i = 0; i < LLStandardBumpmap::sStandardBumpmapCount; i++ ) - { - gStandardBumpmapList[i].mLabel.assign(""); - gStandardBumpmapList[i].mImage = NULL; - } - sStandardBumpmapCount = 0; + LL_INFOS() << "Clearing standard bumpmaps." << LL_ENDL; + for( U32 i = 0; i < LLStandardBumpmap::sStandardBumpmapCount; i++ ) + { + gStandardBumpmapList[i].mLabel.assign(""); + gStandardBumpmapList[i].mImage = NULL; + } + sStandardBumpmapCount = 0; } // static void LLStandardBumpmap::destroyGL() { - clear(); + clear(); } //////////////////////////////////////////////////////////////// -LLDrawPoolBump::LLDrawPoolBump() +LLDrawPoolBump::LLDrawPoolBump() : LLRenderPass(LLDrawPool::POOL_BUMP) { - shiny = FALSE; + shiny = FALSE; } void LLDrawPoolBump::prerender() { - mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); + mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); } // static @@ -217,88 +217,88 @@ S32 LLDrawPoolBump::numBumpPasses() //static void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel) { - LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; - if( cube_map && !LLPipeline::sReflectionProbesEnabled ) - { - if (shader ) - { - LLMatrix4 mat; - mat.initRows(LLVector4(gGLModelView+0), - LLVector4(gGLModelView+4), - LLVector4(gGLModelView+8), - LLVector4(gGLModelView+12)); - LLVector3 vec = LLVector3(gShinyOrigin) * mat; - LLVector4 vec4(vec, gShinyOrigin.mV[3]); - shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV); - if (shader_level > 1) - { + LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; + if( cube_map && !LLPipeline::sReflectionProbesEnabled ) + { + if (shader ) + { + LLMatrix4 mat; + mat.initRows(LLVector4(gGLModelView+0), + LLVector4(gGLModelView+4), + LLVector4(gGLModelView+8), + LLVector4(gGLModelView+12)); + LLVector3 vec = LLVector3(gShinyOrigin) * mat; + LLVector4 vec4(vec, gShinyOrigin.mV[3]); + shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV); + if (shader_level > 1) + { cube_map->setMatrix(1); - // Make sure that texture coord generation happens for tex unit 1, as that's the one we use for - // the cube map in the one pass shiny shaders - cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); - cube_map->enableTexture(cube_channel); - diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - } - else - { + // Make sure that texture coord generation happens for tex unit 1, as that's the one we use for + // the cube map in the one pass shiny shaders + cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); + cube_map->enableTexture(cube_channel); + diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + } + else + { cube_map->setMatrix(0); - cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); - diffuse_channel = -1; - cube_map->enable(cube_channel); - } - gGL.getTexUnit(cube_channel)->bind(cube_map); - gGL.getTexUnit(0)->activate(); - } - else - { - cube_channel = 0; - diffuse_channel = -1; - gGL.getTexUnit(0)->disable(); - cube_map->enable(0); + cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); + diffuse_channel = -1; + cube_map->enable(cube_channel); + } + gGL.getTexUnit(cube_channel)->bind(cube_map); + gGL.getTexUnit(0)->activate(); + } + else + { + cube_channel = 0; + diffuse_channel = -1; + gGL.getTexUnit(0)->disable(); + cube_map->enable(0); cube_map->setMatrix(0); - gGL.getTexUnit(0)->bind(cube_map); - } - } + gGL.getTexUnit(0)->bind(cube_map); + } + } } //static void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel) { - LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; - if( cube_map && !LLPipeline::sReflectionProbesEnabled) - { - if (shader_level > 1) - { - shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); - - if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0) - { - if (diffuse_channel != 0) - { - shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - } - } - } + LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; + if( cube_map && !LLPipeline::sReflectionProbesEnabled) + { + if (shader_level > 1) + { + shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); + + if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0) + { + if (diffuse_channel != 0) + { + shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + } + } + } // Moved below shader->disableTexture call to avoid false alarms from auto-re-enable of textures on stage 0 // MAINT-755 - cube_map->disable(); + cube_map->disable(); cube_map->restoreMatrix(); - } + } } void LLDrawPoolBump::beginFullbrightShiny() { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); - - sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0; - // Second pass: environment map - shader = &gDeferredFullbrightShinyProgram; + sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0; + + // Second pass: environment map + shader = &gDeferredFullbrightShinyProgram; if (LLPipeline::sRenderingHUDs) { shader = &gHUDFullbrightShinyProgram; } - + if (mRigged) { llassert(shader->mRiggedVariant); @@ -312,32 +312,32 @@ void LLDrawPoolBump::beginFullbrightShiny() gGL.getTexUnit(channel)->bind(&gPipeline.mExposureMap); } - LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; - + LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; + if (cube_map && !LLPipeline::sReflectionProbesEnabled) { - // Make sure that texture coord generation happens for tex unit 1, as that's the one we use for - // the cube map in the one pass shiny shaders - gGL.getTexUnit(1)->disable(); - cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); - cube_map->enableTexture(cube_channel); - diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - - gGL.getTexUnit(cube_channel)->bind(cube_map); - gGL.getTexUnit(0)->activate(); + // Make sure that texture coord generation happens for tex unit 1, as that's the one we use for + // the cube map in the one pass shiny shaders + gGL.getTexUnit(1)->disable(); + cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); + cube_map->enableTexture(cube_channel); + diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + + gGL.getTexUnit(cube_channel)->bind(cube_map); + gGL.getTexUnit(0)->activate(); } - { - LLMatrix4 mat; - mat.initRows(LLVector4(gGLModelView+0), - LLVector4(gGLModelView+4), - LLVector4(gGLModelView+8), - LLVector4(gGLModelView+12)); - shader->bind(); - - LLVector3 vec = LLVector3(gShinyOrigin) * mat; - LLVector4 vec4(vec, gShinyOrigin.mV[3]); - shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV); + { + LLMatrix4 mat; + mat.initRows(LLVector4(gGLModelView+0), + LLVector4(gGLModelView+4), + LLVector4(gGLModelView+8), + LLVector4(gGLModelView+12)); + shader->bind(); + + LLVector3 vec = LLVector3(gShinyOrigin) * mat; + LLVector4 vec4(vec, gShinyOrigin.mV[3]); + shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV); if (LLPipeline::sReflectionProbesEnabled) { @@ -347,25 +347,25 @@ void LLDrawPoolBump::beginFullbrightShiny() { gPipeline.setEnvMat(*shader); } - } + } - if (mShaderLevel > 1) - { //indexed texture rendering, channel 0 is always diffuse - diffuse_channel = 0; - } + if (mShaderLevel > 1) + { //indexed texture rendering, channel 0 is always diffuse + diffuse_channel = 0; + } - shiny = TRUE; + shiny = TRUE; } void LLDrawPoolBump::renderFullbrightShiny() { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); - { - LLGLEnable blend_enable(GL_BLEND); + { + LLGLEnable blend_enable(GL_BLEND); - if (mShaderLevel > 1) - { + if (mShaderLevel > 1) + { if (mRigged) { LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED, true, true); @@ -374,9 +374,9 @@ void LLDrawPoolBump::renderFullbrightShiny() { LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, true, true); } - } - else - { + } + else + { if (mRigged) { LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED); @@ -385,125 +385,125 @@ void LLDrawPoolBump::renderFullbrightShiny() { LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY); } - } - } + } + } } void LLDrawPoolBump::endFullbrightShiny() { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); - LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; - if( cube_map && !LLPipeline::sReflectionProbesEnabled ) - { - cube_map->disable(); + LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; + if( cube_map && !LLPipeline::sReflectionProbesEnabled ) + { + cube_map->disable(); if (shader->mFeatures.hasReflectionProbes) { gPipeline.unbindReflectionProbes(*shader); } - shader->unbind(); - } - - diffuse_channel = -1; - cube_channel = 0; - shiny = FALSE; + shader->unbind(); + } + + diffuse_channel = -1; + cube_channel = 0; + shiny = FALSE; } void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, bool texture = true) -{ - LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; - - for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) - { - LLDrawInfo& params = **k; - - applyModelMatrix(params); - - params.mVertexBuffer->setBuffer(); - params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); - } +{ + LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; + + for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) + { + LLDrawInfo& params = **k; + + applyModelMatrix(params); + + params.mVertexBuffer->setBuffer(); + params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); + } } // static BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel) { - U8 bump_code = params.mBump; + U8 bump_code = params.mBump; - return bindBumpMap(bump_code, params.mTexture, channel); + return bindBumpMap(bump_code, params.mTexture, channel); } //static BOOL LLDrawPoolBump::bindBumpMap(LLFace* face, S32 channel) { - const LLTextureEntry* te = face->getTextureEntry(); - if (te) - { - U8 bump_code = te->getBumpmap(); - return bindBumpMap(bump_code, face->getTexture(), channel); - } - - return FALSE; + const LLTextureEntry* te = face->getTextureEntry(); + if (te) + { + U8 bump_code = te->getBumpmap(); + return bindBumpMap(bump_code, face->getTexture(), channel); + } + + return FALSE; } //static BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, S32 channel) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - //Note: texture atlas does not support bump texture now. - LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(texture) ; - if(!tex) - { - //if the texture is not a fetched texture - return FALSE; - } - - LLViewerTexture* bump = NULL; - - switch( bump_code ) - { - case BE_NO_BUMP: - break; - case BE_BRIGHTNESS: - case BE_DARKNESS: - bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code ); - break; - - default: - if( bump_code < LLStandardBumpmap::sStandardBumpmapCount ) - { - bump = gStandardBumpmapList[bump_code].mImage; - gBumpImageList.addTextureStats(bump_code, tex->getID(), tex->getMaxVirtualSize()); - } - break; - } - - if (bump) - { - if (channel == -2) - { - gGL.getTexUnit(1)->bindFast(bump); - gGL.getTexUnit(0)->bindFast(bump); - } - else - { + //Note: texture atlas does not support bump texture now. + LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(texture) ; + if(!tex) + { + //if the texture is not a fetched texture + return FALSE; + } + + LLViewerTexture* bump = NULL; + + switch( bump_code ) + { + case BE_NO_BUMP: + break; + case BE_BRIGHTNESS: + case BE_DARKNESS: + bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code ); + break; + + default: + if( bump_code < LLStandardBumpmap::sStandardBumpmapCount ) + { + bump = gStandardBumpmapList[bump_code].mImage; + gBumpImageList.addTextureStats(bump_code, tex->getID(), tex->getMaxVirtualSize()); + } + break; + } + + if (bump) + { + if (channel == -2) + { + gGL.getTexUnit(1)->bindFast(bump); + gGL.getTexUnit(0)->bindFast(bump); + } + else + { // NOTE: do not use bindFast here (see SL-16222) gGL.getTexUnit(channel)->bind(bump); - } + } - return TRUE; - } + return TRUE; + } - return FALSE; + return FALSE; } //static void LLDrawPoolBump::beginBump() { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); - sVertexMask = VERTEX_MASK_BUMP; - // Optional second pass: emboss bump map - stop_glerror(); + sVertexMask = VERTEX_MASK_BUMP; + // Optional second pass: emboss bump map + stop_glerror(); shader = &gObjectBumpProgram; @@ -515,21 +515,21 @@ void LLDrawPoolBump::beginBump() shader->bind(); - gGL.setSceneBlendType(LLRender::BT_MULT_X2); - stop_glerror(); + gGL.setSceneBlendType(LLRender::BT_MULT_X2); + stop_glerror(); } //static void LLDrawPoolBump::renderBump(U32 pass) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); - LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_LEQUAL); - LLGLEnable blend(GL_BLEND); - gGL.diffuseColor4f(1,1,1,1); - /// Get rid of z-fighting with non-bump pass. - LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(-1.0f, -1.0f); - pushBumpBatches(pass); + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_LEQUAL); + LLGLEnable blend(GL_BLEND); + gGL.diffuseColor4f(1,1,1,1); + /// Get rid of z-fighting with non-bump pass. + LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-1.0f, -1.0f); + pushBumpBatches(pass); } //static @@ -541,7 +541,7 @@ void LLDrawPoolBump::endBump(U32 pass) } S32 LLDrawPoolBump::getNumDeferredPasses() -{ +{ return 1; } @@ -604,7 +604,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass) void LLDrawPoolBump::renderPostDeferred(S32 pass) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - + S32 num_passes = LLPipeline::sRenderingHUDs ? 1 : 2; // skip rigged pass when rendering HUDs for (int i = 0; i < num_passes; ++i) @@ -632,126 +632,126 @@ void LLDrawPoolBump::renderPostDeferred(S32 pass) void LLBumpImageList::init() { - llassert( mBrightnessEntries.size() == 0 ); - llassert( mDarknessEntries.size() == 0 ); + llassert( mBrightnessEntries.size() == 0 ); + llassert( mDarknessEntries.size() == 0 ); - LLStandardBumpmap::restoreGL(); + LLStandardBumpmap::restoreGL(); sMainQueue = LL::WorkQueue::getInstance("mainloop"); sTexUpdateQueue = LL::WorkQueue::getInstance("LLImageGL"); // Share work queue with tex loader. } void LLBumpImageList::clear() { - LL_INFOS() << "Clearing dynamic bumpmaps." << LL_ENDL; - // these will be re-populated on-demand - mBrightnessEntries.clear(); - mDarknessEntries.clear(); + LL_INFOS() << "Clearing dynamic bumpmaps." << LL_ENDL; + // these will be re-populated on-demand + mBrightnessEntries.clear(); + mDarknessEntries.clear(); sRenderTarget.release(); - LLStandardBumpmap::clear(); + LLStandardBumpmap::clear(); } void LLBumpImageList::shutdown() { - clear(); - LLStandardBumpmap::shutdown(); + clear(); + LLStandardBumpmap::shutdown(); } void LLBumpImageList::destroyGL() { - clear(); - LLStandardBumpmap::destroyGL(); + clear(); + LLStandardBumpmap::destroyGL(); } void LLBumpImageList::restoreGL() { - if(!gTextureList.isInitialized()) - { - //safe to return here because bump images will be reloaded during initialization later. - return ; - } - - LLStandardBumpmap::restoreGL(); - // Images will be recreated as they are needed. + if(!gTextureList.isInitialized()) + { + //safe to return here because bump images will be reloaded during initialization later. + return ; + } + + LLStandardBumpmap::restoreGL(); + // Images will be recreated as they are needed. } LLBumpImageList::~LLBumpImageList() { - // Shutdown should have already been called. - llassert( mBrightnessEntries.size() == 0 ); - llassert( mDarknessEntries.size() == 0 ); + // Shutdown should have already been called. + llassert( mBrightnessEntries.size() == 0 ); + llassert( mDarknessEntries.size() == 0 ); } // Note: Does nothing for entries in gStandardBumpmapList that are not actually standard bump images (e.g. none, brightness, and darkness) void LLBumpImageList::addTextureStats(U8 bump, const LLUUID& base_image_id, F32 virtual_size) { - bump &= TEM_BUMP_MASK; - LLViewerFetchedTexture* bump_image = gStandardBumpmapList[bump].mImage; - if( bump_image ) - { - bump_image->addTextureStats(virtual_size); - } + bump &= TEM_BUMP_MASK; + LLViewerFetchedTexture* bump_image = gStandardBumpmapList[bump].mImage; + if( bump_image ) + { + bump_image->addTextureStats(virtual_size); + } } void LLBumpImageList::updateImages() -{ - for (bump_image_map_t::iterator iter = mBrightnessEntries.begin(); iter != mBrightnessEntries.end(); ) - { - bump_image_map_t::iterator curiter = iter++; - LLViewerTexture* image = curiter->second; - if( image ) - { - BOOL destroy = TRUE; - if( image->hasGLTexture()) - { - if( image->getBoundRecently() ) - { - destroy = FALSE; - } - else - { - image->destroyGLTexture(); - } - } - - if( destroy ) - { - //LL_INFOS() << "*** Destroying bright " << (void*)image << LL_ENDL; - mBrightnessEntries.erase(curiter); // deletes the image thanks to reference counting - } - } - } - - for (bump_image_map_t::iterator iter = mDarknessEntries.begin(); iter != mDarknessEntries.end(); ) - { - bump_image_map_t::iterator curiter = iter++; - LLViewerTexture* image = curiter->second; - if( image ) - { - BOOL destroy = TRUE; - if( image->hasGLTexture()) - { - if( image->getBoundRecently() ) - { - destroy = FALSE; - } - else - { - image->destroyGLTexture(); - } - } - - if( destroy ) - { - //LL_INFOS() << "*** Destroying dark " << (void*)image << LL_ENDL;; - mDarknessEntries.erase(curiter); // deletes the image thanks to reference counting - } - } - } +{ + for (bump_image_map_t::iterator iter = mBrightnessEntries.begin(); iter != mBrightnessEntries.end(); ) + { + bump_image_map_t::iterator curiter = iter++; + LLViewerTexture* image = curiter->second; + if( image ) + { + BOOL destroy = TRUE; + if( image->hasGLTexture()) + { + if( image->getBoundRecently() ) + { + destroy = FALSE; + } + else + { + image->destroyGLTexture(); + } + } + + if( destroy ) + { + //LL_INFOS() << "*** Destroying bright " << (void*)image << LL_ENDL; + mBrightnessEntries.erase(curiter); // deletes the image thanks to reference counting + } + } + } + + for (bump_image_map_t::iterator iter = mDarknessEntries.begin(); iter != mDarknessEntries.end(); ) + { + bump_image_map_t::iterator curiter = iter++; + LLViewerTexture* image = curiter->second; + if( image ) + { + BOOL destroy = TRUE; + if( image->hasGLTexture()) + { + if( image->getBoundRecently() ) + { + destroy = FALSE; + } + else + { + image->destroyGLTexture(); + } + } + + if( destroy ) + { + //LL_INFOS() << "*** Destroying dark " << (void*)image << LL_ENDL;; + mDarknessEntries.erase(curiter); // deletes the image thanks to reference counting + } + } + } } @@ -759,52 +759,52 @@ void LLBumpImageList::updateImages() LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedTexture* src_image, U8 bump_code ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - llassert( (bump_code == BE_BRIGHTNESS) || (bump_code == BE_DARKNESS) ); - - LLViewerTexture* bump = NULL; - - bump_image_map_t* entries_list = NULL; - void (*callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) = NULL; - - switch( bump_code ) - { - case BE_BRIGHTNESS: - entries_list = &mBrightnessEntries; - callback_func = LLBumpImageList::onSourceBrightnessLoaded; - break; - case BE_DARKNESS: - entries_list = &mDarknessEntries; - callback_func = LLBumpImageList::onSourceDarknessLoaded; - break; - default: - llassert(0); - return NULL; - } - - bump_image_map_t::iterator iter = entries_list->find(src_image->getID()); - if (iter != entries_list->end() && iter->second.notNull()) - { - bump = iter->second; - } - else - { - (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( TRUE ); - bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image - } - - if (!src_image->hasCallbacks()) - { //if image has no callbacks but resolutions don't match, trigger raw image loaded callback again - if (src_image->getWidth() != bump->getWidth() || - src_image->getHeight() != bump->getHeight())// || - //(LLPipeline::sRenderDeferred && bump->getComponents() != 4)) - { - src_image->setBoostLevel(LLGLTexture::BOOST_BUMP) ; - src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL ); - src_image->forceToSaveRawImage(0) ; - } - } - - return bump; + llassert( (bump_code == BE_BRIGHTNESS) || (bump_code == BE_DARKNESS) ); + + LLViewerTexture* bump = NULL; + + bump_image_map_t* entries_list = NULL; + void (*callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) = NULL; + + switch( bump_code ) + { + case BE_BRIGHTNESS: + entries_list = &mBrightnessEntries; + callback_func = LLBumpImageList::onSourceBrightnessLoaded; + break; + case BE_DARKNESS: + entries_list = &mDarknessEntries; + callback_func = LLBumpImageList::onSourceDarknessLoaded; + break; + default: + llassert(0); + return NULL; + } + + bump_image_map_t::iterator iter = entries_list->find(src_image->getID()); + if (iter != entries_list->end() && iter->second.notNull()) + { + bump = iter->second; + } + else + { + (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( TRUE ); + bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image + } + + if (!src_image->hasCallbacks()) + { //if image has no callbacks but resolutions don't match, trigger raw image loaded callback again + if (src_image->getWidth() != bump->getWidth() || + src_image->getHeight() != bump->getHeight())// || + //(LLPipeline::sRenderDeferred && bump->getComponents() != 4)) + { + src_image->setBoostLevel(LLGLTexture::BOOST_BUMP) ; + src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL ); + src_image->forceToSaveRawImage(0) ; + } + } + + return bump; } @@ -812,94 +812,94 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText void LLBumpImageList::onSourceBrightnessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - LLUUID* source_asset_id = (LLUUID*)userdata; - LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_BRIGHTNESS ); - if( final ) - { - delete source_asset_id; - } + LLUUID* source_asset_id = (LLUUID*)userdata; + LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_BRIGHTNESS ); + if( final ) + { + delete source_asset_id; + } } // static void LLBumpImageList::onSourceDarknessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) { - LLUUID* source_asset_id = (LLUUID*)userdata; - LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_DARKNESS ); - if( final ) - { - delete source_asset_id; - } + LLUUID* source_asset_id = (LLUUID*)userdata; + LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_DARKNESS ); + if( final ) + { + delete source_asset_id; + } } void LLBumpImageList::onSourceStandardLoaded( BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) { - if (success && LLPipeline::sRenderDeferred) - { + if (success && LLPipeline::sRenderDeferred) + { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - LLPointer<LLImageRaw> nrm_image = new LLImageRaw(src->getWidth(), src->getHeight(), 4); - { - generateNormalMapFromAlpha(src, nrm_image); - } - src_vi->setExplicitFormat(GL_RGBA, GL_RGBA); - { - src_vi->createGLTexture(src_vi->getDiscardLevel(), nrm_image); - } - } + LLPointer<LLImageRaw> nrm_image = new LLImageRaw(src->getWidth(), src->getHeight(), 4); + { + generateNormalMapFromAlpha(src, nrm_image); + } + src_vi->setExplicitFormat(GL_RGBA, GL_RGBA); + { + src_vi->createGLTexture(src_vi->getDiscardLevel(), nrm_image); + } + } } void LLBumpImageList::generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nrm_image) { - U8* nrm_data = nrm_image->getData(); - S32 resX = src->getWidth(); - S32 resY = src->getHeight(); - - U8* src_data = src->getData(); - - S32 src_cmp = src->getComponents(); - - F32 norm_scale = gSavedSettings.getF32("RenderNormalMapScale"); - - U32 idx = 0; - //generate normal map from pseudo-heightfield - for (S32 j = 0; j < resY; ++j) - { - for (S32 i = 0; i < resX; ++i) - { - S32 rX = (i+1)%resX; - S32 rY = (j+1)%resY; - S32 lX = (i-1)%resX; - S32 lY = (j-1)%resY; - - if (lX < 0) - { - lX += resX; - } - if (lY < 0) - { - lY += resY; - } - - F32 cH = (F32) src_data[(j*resX+i)*src_cmp+src_cmp-1]; - - LLVector3 right = LLVector3(norm_scale, 0, (F32) src_data[(j*resX+rX)*src_cmp+src_cmp-1]-cH); - LLVector3 left = LLVector3(-norm_scale, 0, (F32) src_data[(j*resX+lX)*src_cmp+src_cmp-1]-cH); - LLVector3 up = LLVector3(0, -norm_scale, (F32) src_data[(lY*resX+i)*src_cmp+src_cmp-1]-cH); - LLVector3 down = LLVector3(0, norm_scale, (F32) src_data[(rY*resX+i)*src_cmp+src_cmp-1]-cH); - - LLVector3 norm = right%down + down%left + left%up + up%right; - - norm.normVec(); - - norm *= 0.5f; - norm += LLVector3(0.5f,0.5f,0.5f); - - idx = (j*resX+i)*4; - nrm_data[idx+0]= (U8) (norm.mV[0]*255); - nrm_data[idx+1]= (U8) (norm.mV[1]*255); - nrm_data[idx+2]= (U8) (norm.mV[2]*255); - nrm_data[idx+3]= src_data[(j*resX+i)*src_cmp+src_cmp-1]; - } - } + U8* nrm_data = nrm_image->getData(); + S32 resX = src->getWidth(); + S32 resY = src->getHeight(); + + U8* src_data = src->getData(); + + S32 src_cmp = src->getComponents(); + + F32 norm_scale = gSavedSettings.getF32("RenderNormalMapScale"); + + U32 idx = 0; + //generate normal map from pseudo-heightfield + for (S32 j = 0; j < resY; ++j) + { + for (S32 i = 0; i < resX; ++i) + { + S32 rX = (i+1)%resX; + S32 rY = (j+1)%resY; + S32 lX = (i-1)%resX; + S32 lY = (j-1)%resY; + + if (lX < 0) + { + lX += resX; + } + if (lY < 0) + { + lY += resY; + } + + F32 cH = (F32) src_data[(j*resX+i)*src_cmp+src_cmp-1]; + + LLVector3 right = LLVector3(norm_scale, 0, (F32) src_data[(j*resX+rX)*src_cmp+src_cmp-1]-cH); + LLVector3 left = LLVector3(-norm_scale, 0, (F32) src_data[(j*resX+lX)*src_cmp+src_cmp-1]-cH); + LLVector3 up = LLVector3(0, -norm_scale, (F32) src_data[(lY*resX+i)*src_cmp+src_cmp-1]-cH); + LLVector3 down = LLVector3(0, norm_scale, (F32) src_data[(rY*resX+i)*src_cmp+src_cmp-1]-cH); + + LLVector3 norm = right%down + down%left + left%up + up%right; + + norm.normVec(); + + norm *= 0.5f; + norm += LLVector3(0.5f,0.5f,0.5f); + + idx = (j*resX+i)*4; + nrm_data[idx+0]= (U8) (norm.mV[0]*255); + nrm_data[idx+1]= (U8) (norm.mV[1]*255); + nrm_data[idx+2]= (U8) (norm.mV[2]*255); + nrm_data[idx+3]= src_data[(j*resX+i)*src_cmp+src_cmp-1]; + } + } } // static @@ -907,147 +907,147 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI { LL_PROFILE_ZONE_SCOPED; - if( success ) - { + if( success ) + { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - bump_image_map_t& entries_list(bump_code == BE_BRIGHTNESS ? gBumpImageList.mBrightnessEntries : gBumpImageList.mDarknessEntries ); - bump_image_map_t::iterator iter = entries_list.find(source_asset_id); - - { - if (iter == entries_list.end() || - iter->second.isNull() || - iter->second->getWidth() != src->getWidth() || - iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution - { //make sure an entry exists for this image - entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture(TRUE); - iter = entries_list.find(src_vi->getID()); - } - } - - if (iter->second->getWidth() != src->getWidth() || - iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution - { - LLPointer<LLImageRaw> dst_image = new LLImageRaw(src->getWidth(), src->getHeight(), 1); - U8* dst_data = dst_image->getData(); - S32 dst_data_size = dst_image->getDataSize(); - - U8* src_data = src->getData(); - S32 src_data_size = src->getDataSize(); - - S32 src_components = src->getComponents(); - - // Convert to luminance and then scale and bias that to get ready for - // embossed bump mapping. (0-255 maps to 127-255) - - // Convert to fixed point so we don't have to worry about precision/clamping. - const S32 FIXED_PT = 8; - const S32 R_WEIGHT = S32(0.2995f * (1<<FIXED_PT)); - const S32 G_WEIGHT = S32(0.5875f * (1<<FIXED_PT)); - const S32 B_WEIGHT = S32(0.1145f * (1<<FIXED_PT)); - - S32 minimum = 255; - S32 maximum = 0; - - switch( src_components ) - { - case 1: - case 2: - { - if( src_data_size == dst_data_size * src_components ) - { - for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components ) - { - dst_data[i] = src_data[j]; - if( dst_data[i] < minimum ) - { - minimum = dst_data[i]; - } - if( dst_data[i] > maximum ) - { - maximum = dst_data[i]; - } - } - } - else - { - llassert(0); - dst_image->clear(); - } - } - break; - case 3: - case 4: - { - if( src_data_size == dst_data_size * src_components ) - { - for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components ) - { - // RGB to luminance - dst_data[i] = (R_WEIGHT * src_data[j] + G_WEIGHT * src_data[j+1] + B_WEIGHT * src_data[j+2]) >> FIXED_PT; - //llassert( dst_data[i] <= 255 );true because it's 8bit - if( dst_data[i] < minimum ) - { - minimum = dst_data[i]; - } - if( dst_data[i] > maximum ) - { - maximum = dst_data[i]; - } - } - } - else - { - llassert(0); - dst_image->clear(); - } - } - break; - default: - llassert(0); - dst_image->clear(); - break; - } - - if( maximum > minimum ) - { - U8 bias_and_scale_lut[256]; - F32 twice_one_over_range = 2.f / (maximum - minimum); - S32 i; - - const F32 ARTIFICIAL_SCALE = 2.f; // Advantage: exaggerates the effect in midrange. Disadvantage: clamps at the extremes. - if (BE_DARKNESS == bump_code) - { - for( i = minimum; i <= maximum; i++ ) - { - F32 minus_one_to_one = F32(maximum - i) * twice_one_over_range - 1.f; - bias_and_scale_lut[i] = llclampb(ll_round(127 * minus_one_to_one * ARTIFICIAL_SCALE + 128)); - } - } - else - { - for( i = minimum; i <= maximum; i++ ) - { - F32 minus_one_to_one = F32(i - minimum) * twice_one_over_range - 1.f; - bias_and_scale_lut[i] = llclampb(ll_round(127 * minus_one_to_one * ARTIFICIAL_SCALE + 128)); - } - } - - for( i = 0; i < dst_data_size; i++ ) - { - dst_data[i] = bias_and_scale_lut[dst_data[i]]; - } - } - - //--------------------------------------------------- - // immediately assign bump to a smart pointer in case some local smart pointer - // accidentally releases it. + bump_image_map_t& entries_list(bump_code == BE_BRIGHTNESS ? gBumpImageList.mBrightnessEntries : gBumpImageList.mDarknessEntries ); + bump_image_map_t::iterator iter = entries_list.find(source_asset_id); + + { + if (iter == entries_list.end() || + iter->second.isNull() || + iter->second->getWidth() != src->getWidth() || + iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution + { //make sure an entry exists for this image + entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture(TRUE); + iter = entries_list.find(src_vi->getID()); + } + } + + if (iter->second->getWidth() != src->getWidth() || + iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution + { + LLPointer<LLImageRaw> dst_image = new LLImageRaw(src->getWidth(), src->getHeight(), 1); + U8* dst_data = dst_image->getData(); + S32 dst_data_size = dst_image->getDataSize(); + + U8* src_data = src->getData(); + S32 src_data_size = src->getDataSize(); + + S32 src_components = src->getComponents(); + + // Convert to luminance and then scale and bias that to get ready for + // embossed bump mapping. (0-255 maps to 127-255) + + // Convert to fixed point so we don't have to worry about precision/clamping. + const S32 FIXED_PT = 8; + const S32 R_WEIGHT = S32(0.2995f * (1<<FIXED_PT)); + const S32 G_WEIGHT = S32(0.5875f * (1<<FIXED_PT)); + const S32 B_WEIGHT = S32(0.1145f * (1<<FIXED_PT)); + + S32 minimum = 255; + S32 maximum = 0; + + switch( src_components ) + { + case 1: + case 2: + { + if( src_data_size == dst_data_size * src_components ) + { + for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components ) + { + dst_data[i] = src_data[j]; + if( dst_data[i] < minimum ) + { + minimum = dst_data[i]; + } + if( dst_data[i] > maximum ) + { + maximum = dst_data[i]; + } + } + } + else + { + llassert(0); + dst_image->clear(); + } + } + break; + case 3: + case 4: + { + if( src_data_size == dst_data_size * src_components ) + { + for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components ) + { + // RGB to luminance + dst_data[i] = (R_WEIGHT * src_data[j] + G_WEIGHT * src_data[j+1] + B_WEIGHT * src_data[j+2]) >> FIXED_PT; + //llassert( dst_data[i] <= 255 );true because it's 8bit + if( dst_data[i] < minimum ) + { + minimum = dst_data[i]; + } + if( dst_data[i] > maximum ) + { + maximum = dst_data[i]; + } + } + } + else + { + llassert(0); + dst_image->clear(); + } + } + break; + default: + llassert(0); + dst_image->clear(); + break; + } + + if( maximum > minimum ) + { + U8 bias_and_scale_lut[256]; + F32 twice_one_over_range = 2.f / (maximum - minimum); + S32 i; + + const F32 ARTIFICIAL_SCALE = 2.f; // Advantage: exaggerates the effect in midrange. Disadvantage: clamps at the extremes. + if (BE_DARKNESS == bump_code) + { + for( i = minimum; i <= maximum; i++ ) + { + F32 minus_one_to_one = F32(maximum - i) * twice_one_over_range - 1.f; + bias_and_scale_lut[i] = llclampb(ll_round(127 * minus_one_to_one * ARTIFICIAL_SCALE + 128)); + } + } + else + { + for( i = minimum; i <= maximum; i++ ) + { + F32 minus_one_to_one = F32(i - minimum) * twice_one_over_range - 1.f; + bias_and_scale_lut[i] = llclampb(ll_round(127 * minus_one_to_one * ARTIFICIAL_SCALE + 128)); + } + } + + for( i = 0; i < dst_data_size; i++ ) + { + dst_data[i] = bias_and_scale_lut[dst_data[i]]; + } + } + + //--------------------------------------------------- + // immediately assign bump to a smart pointer in case some local smart pointer + // accidentally releases it. LLPointer<LLViewerTexture> bump = iter->second; - if (!LLPipeline::sRenderDeferred) - { - bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA); + if (!LLPipeline::sRenderDeferred) + { + bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA); #if LL_BUMPLIST_MULTITHREADED auto tex_queue = LLImageGLThread::sEnabledTextures ? sTexUpdateQueue.lock() : nullptr; @@ -1073,9 +1073,9 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI { bump->createGLTexture(0, dst_image); } - } - else - { //convert to normal map + } + else + { //convert to normal map LL_PROFILE_ZONE_NAMED("bil - create normal map"); LLImageGL* img = bump->getGLTexture(); LLImageRaw* dst_ptr = dst_image.get(); @@ -1179,16 +1179,16 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI } - } + } - iter->second = bump; // derefs (and deletes) old image - //--------------------------------------------------- - } - } + iter->second = bump; // derefs (and deletes) old image + //--------------------------------------------------- + } + } } void LLDrawPoolBump::pushBumpBatches(U32 type) -{ +{ LLVOAvatar* avatar = nullptr; U64 skin = 0; @@ -1200,12 +1200,12 @@ void LLDrawPoolBump::pushBumpBatches(U32 type) LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); - for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) - { - LLDrawInfo& params = **i; + for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) + { + LLDrawInfo& params = **i; - if (LLDrawPoolBump::bindBumpMap(params)) - { + if (LLDrawPoolBump::bindBumpMap(params)) + { if (mRigged) { if (avatar != params.mAvatar || skin != params.mSkinInfo->mHash) @@ -1221,80 +1221,80 @@ void LLDrawPoolBump::pushBumpBatches(U32 type) } } } - pushBumpBatch(params, false); - } - } + pushBumpBatch(params, false); + } + } } void LLRenderPass::pushBumpBatch(LLDrawInfo& params, bool texture, bool batch_textures) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - applyModelMatrix(params); - - bool tex_setup = false; - - if (batch_textures && params.mTextureList.size() > 1) - { - for (U32 i = 0; i < params.mTextureList.size(); ++i) - { - if (params.mTextureList[i].notNull()) - { - gGL.getTexUnit(i)->bindFast(params.mTextureList[i]); - } - } - } - else - { //not batching textures or batch has only 1 texture -- might need a texture matrix - if (params.mTextureMatrix) - { - if (shiny) - { - gGL.getTexUnit(0)->activate(); - gGL.matrixMode(LLRender::MM_TEXTURE); - } - else - { - gGL.getTexUnit(0)->activate(); - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); - gPipeline.mTextureMatrixOps++; - } - - gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); - gPipeline.mTextureMatrixOps++; - - tex_setup = true; - } - - if (shiny && mShaderLevel > 1 && texture) - { - if (params.mTexture.notNull()) - { - gGL.getTexUnit(diffuse_channel)->bindFast(params.mTexture); - } - else - { - gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); - } - } - } - - params.mVertexBuffer->setBuffer(); - params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); + applyModelMatrix(params); + + bool tex_setup = false; + + if (batch_textures && params.mTextureList.size() > 1) + { + for (U32 i = 0; i < params.mTextureList.size(); ++i) + { + if (params.mTextureList[i].notNull()) + { + gGL.getTexUnit(i)->bindFast(params.mTextureList[i]); + } + } + } + else + { //not batching textures or batch has only 1 texture -- might need a texture matrix + if (params.mTextureMatrix) + { + if (shiny) + { + gGL.getTexUnit(0)->activate(); + gGL.matrixMode(LLRender::MM_TEXTURE); + } + else + { + gGL.getTexUnit(0)->activate(); + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; + } + + gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; + + tex_setup = true; + } + + if (shiny && mShaderLevel > 1 && texture) + { + if (params.mTexture.notNull()) + { + gGL.getTexUnit(diffuse_channel)->bindFast(params.mTexture); + } + else + { + gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); + } + } + } + + params.mVertexBuffer->setBuffer(); + params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); if (tex_setup) - { - if (shiny) - { - gGL.getTexUnit(0)->activate(); - } - else - { - gGL.getTexUnit(0)->activate(); - gGL.matrixMode(LLRender::MM_TEXTURE); - } - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - } + { + if (shiny) + { + gGL.getTexUnit(0)->activate(); + } + else + { + gGL.getTexUnit(0)->activate(); + gGL.matrixMode(LLRender::MM_TEXTURE); + } + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + } } |