SL-16166 Apply optimizations from pushBatch to other render call sites. Optimize out a map lookup in rigged face rendering.
parent
aa2169aa37
commit
e7227afe02
|
|
@ -1017,7 +1017,7 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextu
|
|||
|
||||
if (uniform > -1)
|
||||
{
|
||||
gGL.getTexUnit(uniform)->bind(texture, mode);
|
||||
gGL.getTexUnit(uniform)->bindFast(texture);
|
||||
gGL.getTexUnit(uniform)->setTextureColorSpace(colorspace);
|
||||
}
|
||||
|
||||
|
|
@ -1048,7 +1048,7 @@ S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
|
|||
|
||||
if (uniform > -1)
|
||||
{
|
||||
gGL.getTexUnit(uniform)->unbind(mode);
|
||||
gGL.getTexUnit(uniform)->unbindFast(mode);
|
||||
}
|
||||
|
||||
return uniform;
|
||||
|
|
|
|||
|
|
@ -169,7 +169,6 @@ void LLTexUnit::refreshState(void)
|
|||
|
||||
void LLTexUnit::activate(void)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
if (mIndex < 0) return;
|
||||
|
||||
if ((S32)gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty)
|
||||
|
|
@ -1956,9 +1955,9 @@ void LLRender::end()
|
|||
}
|
||||
void LLRender::flush()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
if (mCount > 0)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
if (!mUIOffset.empty())
|
||||
{
|
||||
sUICalls++;
|
||||
|
|
|
|||
|
|
@ -234,8 +234,6 @@ void LLDrawable::markDead()
|
|||
|
||||
LLVOVolume* LLDrawable::getVOVolume() const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED
|
||||
|
||||
LLViewerObject* objectp = mVObjp;
|
||||
if ( !isDead() && objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -55,19 +55,7 @@ static BOOL deferred_render = FALSE;
|
|||
|
||||
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SETUP("Alpha Setup");
|
||||
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_GROUP_LOOP("Alpha Group");
|
||||
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_PUSH("Alpha Push Verts");
|
||||
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED("Alpha Deferred");
|
||||
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SETBUFFER("Alpha SetBuffer");
|
||||
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DRAW("Alpha Draw");
|
||||
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_TEX_BINDS("Alpha Tex Binds");
|
||||
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MATS("Alpha Mat Tex Binds");
|
||||
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_GLOW("Alpha Glow Binds");
|
||||
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SHADER_BINDS("Alpha Shader Binds");
|
||||
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS("Alpha Def Binds");
|
||||
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS("Alpha Def Tex Binds");
|
||||
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MESH_REBUILD("Alpha Mesh Rebuild");
|
||||
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_EMISSIVE("Alpha Emissive");
|
||||
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_LIGHT_SETUP("Alpha Light Setup");
|
||||
|
||||
LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) :
|
||||
LLRenderPass(type), current_shader(NULL), target_shader(NULL),
|
||||
|
|
@ -86,6 +74,10 @@ LLDrawPoolAlpha::~LLDrawPoolAlpha()
|
|||
void LLDrawPoolAlpha::prerender()
|
||||
{
|
||||
mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
|
||||
|
||||
// TODO: is this even necessay? These are probably set to never discard
|
||||
LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(1024.f*1024.f);
|
||||
LLViewerFetchedTexture::sWhiteImagep->addTextureStats(1024.f * 1024.f);
|
||||
}
|
||||
|
||||
S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
|
||||
|
|
@ -309,7 +301,7 @@ void LLDrawPoolAlpha::render(S32 pass)
|
|||
gGL.diffuseColor4f(1,0,0,1);
|
||||
|
||||
LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f*1024.f);
|
||||
gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep, TRUE) ;
|
||||
gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sSmokeImagep);
|
||||
renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX |
|
||||
LLVertexBuffer::MAP_TEXCOORD0);
|
||||
|
||||
|
|
@ -358,9 +350,8 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
|
|||
{
|
||||
params.mGroup->rebuildMesh();
|
||||
}
|
||||
params.mVertexBuffer->setBuffer(mask);
|
||||
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
|
||||
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
|
||||
params.mVertexBuffer->setBufferFast(mask);
|
||||
params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -383,27 +374,23 @@ inline bool IsEmissive(LLDrawInfo& params)
|
|||
|
||||
inline void Draw(LLDrawInfo* draw, U32 mask)
|
||||
{
|
||||
draw->mVertexBuffer->setBuffer(mask);
|
||||
draw->mVertexBuffer->setBufferFast(mask);
|
||||
LLRenderPass::applyModelMatrix(*draw);
|
||||
draw->mVertexBuffer->drawRange(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
|
||||
gPipeline.addTrianglesDrawn(draw->mCount, draw->mDrawMode);
|
||||
draw->mVertexBuffer->drawRangeFast(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
|
||||
}
|
||||
|
||||
bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_material, LLGLSLShader* current_shader)
|
||||
bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material, LLGLSLShader* current_shader)
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_TEX_BINDS);
|
||||
|
||||
bool tex_setup = false;
|
||||
|
||||
if (deferred_render && use_material && current_shader)
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS);
|
||||
if (draw->mNormalMap)
|
||||
{
|
||||
{
|
||||
draw->mNormalMap->addTextureStats(draw->mVSize);
|
||||
current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap);
|
||||
}
|
||||
|
||||
|
||||
if (draw->mSpecularMap)
|
||||
{
|
||||
draw->mSpecularMap->addTextureStats(draw->mVSize);
|
||||
|
|
@ -412,18 +399,16 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_mate
|
|||
}
|
||||
else if (current_shader == simple_shader)
|
||||
{
|
||||
LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(draw->mVSize);
|
||||
LLViewerFetchedTexture::sWhiteImagep->addTextureStats(draw->mVSize);
|
||||
current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
|
||||
current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
|
||||
current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
|
||||
}
|
||||
if (use_shaders && draw->mTextureList.size() > 1)
|
||||
if (draw->mTextureList.size() > 1)
|
||||
{
|
||||
for (U32 i = 0; i < draw->mTextureList.size(); ++i)
|
||||
{
|
||||
if (draw->mTextureList[i].notNull())
|
||||
{
|
||||
gGL.getTexUnit(i)->bind(draw->mTextureList[i], TRUE);
|
||||
gGL.getTexUnit(i)->bindFast(draw->mTextureList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -431,16 +416,15 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_mate
|
|||
{ //not batching textures or batch has only 1 texture -- might need a texture matrix
|
||||
if (draw->mTexture.notNull())
|
||||
{
|
||||
draw->mTexture->addTextureStats(draw->mVSize);
|
||||
if (use_shaders && use_material)
|
||||
if (use_material)
|
||||
{
|
||||
current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, draw->mTexture);
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(draw->mTexture, TRUE) ;
|
||||
gGL.getTexUnit(0)->bindFast(draw->mTexture);
|
||||
}
|
||||
|
||||
|
||||
if (draw->mTextureMatrix)
|
||||
{
|
||||
tex_setup = true;
|
||||
|
|
@ -452,7 +436,7 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_mate
|
|||
}
|
||||
else
|
||||
{
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -470,37 +454,15 @@ void LLDrawPoolAlpha::RestoreTexSetup(bool tex_setup)
|
|||
}
|
||||
}
|
||||
|
||||
void LLDrawPoolAlpha::renderSimples(U32 mask, std::vector<LLDrawInfo*>& simples)
|
||||
{
|
||||
gPipeline.enableLightsDynamic();
|
||||
simple_shader->bind();
|
||||
simple_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
|
||||
simple_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
|
||||
simple_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
simple_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f);
|
||||
simple_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 0.0f);
|
||||
bool use_shaders = gPipeline.canUseVertexShaders();
|
||||
for (LLDrawInfo* draw : simples)
|
||||
{
|
||||
bool tex_setup = TexSetup(draw, use_shaders, false, simple_shader);
|
||||
LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test);
|
||||
gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
|
||||
|
||||
Draw(draw, mask);
|
||||
RestoreTexSetup(tex_setup);
|
||||
}
|
||||
simple_shader->unbind();
|
||||
}
|
||||
|
||||
void LLDrawPoolAlpha::renderFullbrights(U32 mask, std::vector<LLDrawInfo*>& fullbrights)
|
||||
{
|
||||
gPipeline.enableLightsFullbright();
|
||||
fullbright_shader->bind();
|
||||
fullbright_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.0f);
|
||||
bool use_shaders = gPipeline.canUseVertexShaders();
|
||||
|
||||
for (LLDrawInfo* draw : fullbrights)
|
||||
{
|
||||
bool tex_setup = TexSetup(draw, use_shaders, false, fullbright_shader);
|
||||
bool tex_setup = TexSetup(draw, false, fullbright_shader);
|
||||
|
||||
LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test);
|
||||
gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
|
||||
|
|
@ -511,65 +473,10 @@ void LLDrawPoolAlpha::renderFullbrights(U32 mask, std::vector<LLDrawInfo*>& full
|
|||
fullbright_shader->unbind();
|
||||
}
|
||||
|
||||
void LLDrawPoolAlpha::renderMaterials(U32 mask, std::vector<LLDrawInfo*>& materials)
|
||||
{
|
||||
LLGLSLShader::bindNoShader();
|
||||
current_shader = NULL;
|
||||
|
||||
gPipeline.enableLightsDynamic();
|
||||
bool use_shaders = gPipeline.canUseVertexShaders();
|
||||
for (LLDrawInfo* draw : materials)
|
||||
{
|
||||
U32 mask = draw->mShaderMask;
|
||||
|
||||
llassert(mask < LLMaterial::SHADER_COUNT);
|
||||
target_shader = (LLPipeline::sUnderWaterRender) ? &(gDeferredMaterialWaterProgram[mask]) : &(gDeferredMaterialProgram[mask]);
|
||||
|
||||
if (current_shader != target_shader)
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS);
|
||||
if (current_shader)
|
||||
{
|
||||
gPipeline.unbindDeferredShader(*current_shader);
|
||||
}
|
||||
gPipeline.bindDeferredShader(*target_shader);
|
||||
current_shader = target_shader;
|
||||
}
|
||||
|
||||
bool tex_setup = TexSetup(draw, use_shaders, true, current_shader);
|
||||
|
||||
current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, draw->mSpecColor.mV[0], draw->mSpecColor.mV[1], draw->mSpecColor.mV[2], draw->mSpecColor.mV[3]);
|
||||
current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, draw->mEnvIntensity);
|
||||
current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, draw->mFullbright ? 1.f : 0.f);
|
||||
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS);
|
||||
if (draw->mNormalMap)
|
||||
{
|
||||
draw->mNormalMap->addTextureStats(draw->mVSize);
|
||||
current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap);
|
||||
}
|
||||
|
||||
if (draw->mSpecularMap)
|
||||
{
|
||||
draw->mSpecularMap->addTextureStats(draw->mVSize);
|
||||
current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap);
|
||||
}
|
||||
}
|
||||
|
||||
LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test);
|
||||
gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
|
||||
|
||||
Draw(draw, mask);
|
||||
RestoreTexSetup(tex_setup);
|
||||
}
|
||||
}
|
||||
|
||||
void LLDrawPoolAlpha::drawEmissive(U32 mask, LLDrawInfo* draw)
|
||||
{
|
||||
draw->mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);
|
||||
draw->mVertexBuffer->drawRange(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
|
||||
gPipeline.addTrianglesDrawn(draw->mCount, draw->mDrawMode);
|
||||
draw->mVertexBuffer->setBufferFast((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);
|
||||
draw->mVertexBuffer->drawRangeFast(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
|
||||
}
|
||||
|
||||
void LLDrawPoolAlpha::drawEmissiveInline(U32 mask, LLDrawInfo* draw)
|
||||
|
|
@ -599,10 +506,10 @@ void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissi
|
|||
// install glow-accumulating blend mode
|
||||
// don't touch color, add to alpha (glow)
|
||||
gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE);
|
||||
bool use_shaders = gPipeline.canUseVertexShaders();
|
||||
|
||||
for (LLDrawInfo* draw : emissives)
|
||||
{
|
||||
bool tex_setup = TexSetup(draw, use_shaders, false, emissive_shader);
|
||||
bool tex_setup = TexSetup(draw, false, emissive_shader);
|
||||
drawEmissive(mask, draw);
|
||||
RestoreTexSetup(tex_setup);
|
||||
}
|
||||
|
|
@ -620,8 +527,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
|
|||
BOOL initialized_lighting = FALSE;
|
||||
BOOL light_enabled = TRUE;
|
||||
|
||||
BOOL use_shaders = gPipeline.canUseVertexShaders();
|
||||
|
||||
for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
|
||||
{
|
||||
LLSpatialGroup* group = *i;
|
||||
|
|
@ -631,8 +536,10 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
|
|||
if (group->getSpatialPartition()->mRenderByGroup &&
|
||||
!group->isDead())
|
||||
{
|
||||
std::vector<LLDrawInfo*> emissives;
|
||||
std::vector<LLDrawInfo*> fullbrights;
|
||||
static std::vector<LLDrawInfo*> emissives;
|
||||
static std::vector<LLDrawInfo*> fullbrights;
|
||||
emissives.resize(0);
|
||||
fullbrights.resize(0);
|
||||
|
||||
bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE
|
||||
|| group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE;
|
||||
|
|
@ -649,6 +556,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
|
|||
|
||||
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("ra - push batch")
|
||||
LLDrawInfo& params = **k;
|
||||
U32 have_mask = params.mVertexBuffer->getTypeMask() & mask;
|
||||
if (have_mask != mask)
|
||||
|
|
@ -696,34 +604,17 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
|
|||
// Turn off lighting if it hasn't already been so.
|
||||
if (light_enabled || !initialized_lighting)
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_LIGHT_SETUP);
|
||||
|
||||
initialized_lighting = TRUE;
|
||||
if (use_shaders)
|
||||
{
|
||||
target_shader = fullbright_shader;
|
||||
}
|
||||
else
|
||||
{
|
||||
gPipeline.enableLightsFullbright();
|
||||
}
|
||||
target_shader = fullbright_shader;
|
||||
|
||||
light_enabled = FALSE;
|
||||
}
|
||||
}
|
||||
// Turn on lighting if it isn't already.
|
||||
else if (!light_enabled || !initialized_lighting)
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_LIGHT_SETUP);
|
||||
|
||||
initialized_lighting = TRUE;
|
||||
if (use_shaders)
|
||||
{
|
||||
target_shader = simple_shader;
|
||||
}
|
||||
else
|
||||
{
|
||||
gPipeline.enableLightsDynamic();
|
||||
}
|
||||
target_shader = simple_shader;
|
||||
light_enabled = TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -741,7 +632,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
|
|||
|
||||
if (current_shader != target_shader)
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS);
|
||||
gPipeline.bindDeferredShader(*target_shader);
|
||||
current_shader = target_shader;
|
||||
}
|
||||
|
|
@ -755,25 +645,19 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
|
|||
target_shader = fullbright_shader;
|
||||
}
|
||||
|
||||
if(use_shaders && (current_shader != target_shader))
|
||||
if(current_shader != target_shader)
|
||||
{// If we need shaders, and we're not ALREADY using the proper shader, then bind it
|
||||
// (this way we won't rebind shaders unnecessarily).
|
||||
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_SHADER_BINDS);
|
||||
current_shader = target_shader;
|
||||
current_shader->bind();
|
||||
}
|
||||
else if (!use_shaders && current_shader != NULL)
|
||||
{
|
||||
LLGLSLShader::bindNoShader();
|
||||
current_shader = NULL;
|
||||
}
|
||||
|
||||
LLVector4 spec_color(1, 1, 1, 1);
|
||||
F32 env_intensity = 0.0f;
|
||||
F32 brightness = 1.0f;
|
||||
|
||||
// We have a material. Supply the appropriate data here.
|
||||
if (use_shaders && mat && deferred_render)
|
||||
if (mat && deferred_render)
|
||||
{
|
||||
spec_color = params.mSpecColor;
|
||||
env_intensity = params.mEnvIntensity;
|
||||
|
|
@ -792,20 +676,16 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
|
|||
params.mGroup->rebuildMesh();
|
||||
}
|
||||
|
||||
bool tex_setup = TexSetup(¶ms, use_shaders, use_shaders && (mat != nullptr), current_shader);
|
||||
bool tex_setup = TexSetup(¶ms, (mat != nullptr), current_shader);
|
||||
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_PUSH);
|
||||
|
||||
LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
|
||||
|
||||
gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
|
||||
params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0));
|
||||
params.mVertexBuffer->setBufferFast(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0));
|
||||
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DRAW);
|
||||
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
|
||||
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
|
||||
params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -814,8 +694,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
|
|||
draw_glow_for_this_partition &&
|
||||
params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE))
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_EMISSIVE);
|
||||
|
||||
if (batch_emissives)
|
||||
{
|
||||
emissives.push_back(¶ms);
|
||||
|
|
@ -835,19 +713,29 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
bool rebind = false;
|
||||
if (batch_fullbrights)
|
||||
{
|
||||
light_enabled = false;
|
||||
renderFullbrights(mask, fullbrights);
|
||||
if (!fullbrights.empty())
|
||||
{
|
||||
light_enabled = false;
|
||||
renderFullbrights(mask, fullbrights);
|
||||
rebind = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (batch_emissives)
|
||||
{
|
||||
light_enabled = true;
|
||||
renderEmissives(mask, emissives);
|
||||
if (!emissives.empty())
|
||||
{
|
||||
light_enabled = true;
|
||||
renderEmissives(mask, emissives);
|
||||
rebind = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_shader)
|
||||
if (current_shader && rebind)
|
||||
{
|
||||
current_shader->bind();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,15 +75,13 @@ private:
|
|||
LLGLSLShader* fullbright_shader;
|
||||
LLGLSLShader* emissive_shader;
|
||||
|
||||
void renderSimples(U32 mask, std::vector<LLDrawInfo*>& simples);
|
||||
void renderFullbrights(U32 mask, std::vector<LLDrawInfo*>& fullbrights);
|
||||
void renderMaterials(U32 mask, std::vector<LLDrawInfo*>& fullbrights);
|
||||
void renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives);
|
||||
|
||||
void drawEmissive(U32 mask, LLDrawInfo* draw);
|
||||
void drawEmissiveInline(U32 mask, LLDrawInfo* draw);
|
||||
|
||||
bool TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_material, LLGLSLShader* current_shader);
|
||||
bool TexSetup(LLDrawInfo* draw, bool use_material, LLGLSLShader* current_shader);
|
||||
void RestoreTexSetup(bool tex_setup);
|
||||
|
||||
// our 'normal' alpha blend function for this pass
|
||||
|
|
|
|||
|
|
@ -1685,7 +1685,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE);
|
||||
renderRigged(avatarp, RIGGED_NORMMAP);
|
||||
renderRigged(avatarp, RIGGED_NORMMAP_MASK);
|
||||
renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE);
|
||||
renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE);
|
||||
renderRigged(avatarp, RIGGED_SPECMAP);
|
||||
renderRigged(avatarp, RIGGED_SPECMAP_MASK);
|
||||
renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE);
|
||||
|
|
@ -2067,56 +2067,12 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
|
|||
LLVector4a* pos = (LLVector4a*) position.get();
|
||||
|
||||
LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL;
|
||||
|
||||
if (skin == nullptr)
|
||||
{
|
||||
skin = vobj->getSkinInfo();
|
||||
}
|
||||
|
||||
const MatrixPaletteCache& mpc = updateSkinInfoMatrixPalette(avatar, skin);
|
||||
const MatrixPaletteCache& mpc = updateSkinInfoMatrixPalette(avatar, vobj->getMeshID());
|
||||
const LLMatrix4a* mat = &(mpc.mMatrixPalette[0]);
|
||||
const LLMatrix4a& bind_shape_matrix = mpc.mBindShapeMatrix;
|
||||
|
||||
LLSkinningUtil::checkSkinWeights(weights, buffer->getNumVerts(), skin);
|
||||
const LLMatrix4a& bind_shape_matrix = skin->mBindShapeMatrix;
|
||||
|
||||
#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
|
||||
U8* joint_indices_cursor = vol_face.mJointIndices;
|
||||
// fast path with joint indices separate from weights
|
||||
if (joint_indices_cursor)
|
||||
{
|
||||
LLMatrix4a src[4];
|
||||
for (U32 j = 0; j < buffer->getNumVerts(); ++j)
|
||||
{
|
||||
LLMatrix4a final_mat;
|
||||
//LLMatrix4a final_mat_correct;
|
||||
|
||||
F32* jw = just_weights[j].getF32ptr();
|
||||
|
||||
LLSkinningUtil::getPerVertexSkinMatrixWithIndices(jw, joint_indices_cursor, mat, final_mat, src);
|
||||
|
||||
joint_indices_cursor += 4;
|
||||
|
||||
LLVector4a& v = vol_face.mPositions[j];
|
||||
|
||||
LLVector4a t;
|
||||
LLVector4a dst;
|
||||
bind_shape_matrix.affineTransform(v, t);
|
||||
final_mat.affineTransform(t, dst);
|
||||
pos[j] = dst;
|
||||
|
||||
if (norm)
|
||||
{
|
||||
LLVector4a& n = vol_face.mNormals[j];
|
||||
bind_shape_matrix.rotate(n, t);
|
||||
final_mat.rotate(t, dst);
|
||||
dst.normalize3fast();
|
||||
norm[j] = dst;
|
||||
}
|
||||
}
|
||||
}
|
||||
// slow path with joint indices calculated from weights
|
||||
else
|
||||
#endif
|
||||
if (!mpc.mMatrixPalette.empty())
|
||||
{
|
||||
for (U32 j = 0; j < buffer->getNumVerts(); ++j)
|
||||
{
|
||||
|
|
@ -2152,9 +2108,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
|||
return;
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
|
||||
const LLMeshSkinInfo* lastSkin = nullptr;
|
||||
LLUUID lastMeshId;
|
||||
|
||||
for (U32 i = 0; i < mRiggedFace[type].size(); ++i)
|
||||
{
|
||||
|
|
@ -2188,19 +2142,6 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
|||
continue;
|
||||
}
|
||||
|
||||
const LLMeshSkinInfo* skin = vobj->getSkinInfo();
|
||||
if (!skin)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//stop_glerror();
|
||||
|
||||
//const LLVolumeFace& vol_face = volume->getVolumeFace(te);
|
||||
//updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face);
|
||||
|
||||
//stop_glerror();
|
||||
|
||||
U32 data_mask = LLFace::getRiggedDataMask(type);
|
||||
|
||||
LLVertexBuffer* buff = face->getVertexBuffer();
|
||||
|
|
@ -2290,34 +2231,33 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
|||
{
|
||||
if (sShaderLevel > 0)
|
||||
{
|
||||
if (lastSkin != skin) // <== only upload matrix palette to GL if the skininfo changed
|
||||
auto& meshId = vobj->getMeshID();
|
||||
|
||||
if (lastMeshId != meshId) // <== only upload matrix palette to GL if the skininfo changed
|
||||
{
|
||||
// upload matrix palette to shader
|
||||
const MatrixPaletteCache& mpc = updateSkinInfoMatrixPalette(avatar, skin);
|
||||
const MatrixPaletteCache& mpc = updateSkinInfoMatrixPalette(avatar, meshId);
|
||||
U32 count = mpc.mMatrixPalette.size();
|
||||
|
||||
stop_glerror();
|
||||
if (count == 0)
|
||||
{
|
||||
//skin info not loaded yet, don't render
|
||||
continue;
|
||||
}
|
||||
|
||||
LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX,
|
||||
count,
|
||||
FALSE,
|
||||
(GLfloat*) &(mpc.mGLMp[0]));
|
||||
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
lastMeshId = meshId;
|
||||
}
|
||||
else
|
||||
{
|
||||
data_mask &= ~LLVertexBuffer::MAP_WEIGHT4;
|
||||
}
|
||||
|
||||
lastSkin = skin;
|
||||
|
||||
/*if (glow)
|
||||
{
|
||||
gGL.diffuseColor4f(0,0,0,face->getTextureEntry()->getGlow());
|
||||
}*/
|
||||
|
||||
if (mat)
|
||||
{
|
||||
//order is important here LLRender::DIFFUSE_MAP should be last, becouse it change
|
||||
|
|
@ -2332,13 +2272,17 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
|||
{
|
||||
specular = face->getTexture(LLRender::SPECULAR_MAP);
|
||||
}
|
||||
if (specular)
|
||||
if (specular && specular_channel >= 0)
|
||||
{
|
||||
gGL.getTexUnit(specular_channel)->bind(specular);
|
||||
gGL.getTexUnit(specular_channel)->bindFast(specular);
|
||||
}
|
||||
|
||||
gGL.getTexUnit(normal_channel)->bind(face->getTexture(LLRender::NORMAL_MAP));
|
||||
gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture(LLRender::DIFFUSE_MAP), false, true);
|
||||
if (normal_channel >= 0)
|
||||
{
|
||||
gGL.getTexUnit(normal_channel)->bindFast(face->getTexture(LLRender::NORMAL_MAP));
|
||||
}
|
||||
|
||||
gGL.getTexUnit(sDiffuseChannel)->bindFast(face->getTexture(LLRender::DIFFUSE_MAP));
|
||||
|
||||
|
||||
LLColor4 col = mat->getSpecularLightColor();
|
||||
|
|
@ -2369,23 +2313,28 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
|||
sVertexProgram->setMinimumAlpha(0.f);
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
|
||||
{
|
||||
LLViewerTexture* tex = face->getTexture(i);
|
||||
if (tex)
|
||||
{
|
||||
tex->addTextureStats(avatar->getPixelArea());
|
||||
}
|
||||
}
|
||||
if (!LLPipeline::sShadowRender && !LLPipeline::sReflectionRender)
|
||||
{
|
||||
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
|
||||
{
|
||||
LLViewerTexture* tex = face->getTexture(i);
|
||||
if (tex)
|
||||
{
|
||||
tex->addTextureStats(avatar->getPixelArea());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture());
|
||||
sVertexProgram->setMinimumAlpha(0.f);
|
||||
if (normal_channel > -1)
|
||||
{
|
||||
LLDrawPoolBump::bindBumpMap(face, normal_channel);
|
||||
}
|
||||
|
||||
gGL.getTexUnit(sDiffuseChannel)->bindFast(face->getTexture());
|
||||
|
||||
}
|
||||
|
||||
if (face->mTextureMatrix && vobj->mTexAnimMode)
|
||||
|
|
@ -2399,8 +2348,8 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
|||
gGL.loadMatrix((F32*) face->mTextureMatrix->mMatrix);
|
||||
}
|
||||
|
||||
buff->setBuffer(data_mask);
|
||||
buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
|
||||
buff->setBufferFast(data_mask);
|
||||
buff->drawRangeFast(LLRender::TRIANGLES, start, end, count, offset);
|
||||
|
||||
if (tex_index <= 1)
|
||||
{
|
||||
|
|
@ -2411,11 +2360,9 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
|||
}
|
||||
else
|
||||
{
|
||||
buff->setBuffer(data_mask);
|
||||
buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
|
||||
buff->setBufferFast(data_mask);
|
||||
buff->drawRangeFast(LLRender::TRIANGLES, start, end, count, offset);
|
||||
}
|
||||
|
||||
gPipeline.addTrianglesDrawn(count, LLRender::TRIANGLES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2476,8 +2423,6 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
|
|||
continue;
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
|
||||
LLVolumeFace& vol_face = volume->getVolumeFace(te);
|
||||
updateRiggedFaceVertexBuffer(avatar, face, vobj, volume, vol_face);
|
||||
}
|
||||
|
|
@ -2501,47 +2446,58 @@ void LLDrawPoolAvatar::updateSkinInfoMatrixPalettes(LLVOAvatar* avatarp)
|
|||
}
|
||||
}
|
||||
|
||||
const LLDrawPoolAvatar::MatrixPaletteCache& LLDrawPoolAvatar::updateSkinInfoMatrixPalette(LLVOAvatar * avatarp, const LLMeshSkinInfo* skin)
|
||||
const LLDrawPoolAvatar::MatrixPaletteCache& LLDrawPoolAvatar::updateSkinInfoMatrixPalette(LLVOAvatar * avatarp, const LLUUID& meshId)
|
||||
{
|
||||
MatrixPaletteCache& entry = mMatrixPaletteCache[skin];
|
||||
MatrixPaletteCache& entry = mMatrixPaletteCache[meshId];
|
||||
|
||||
if (entry.mFrame != gFrameCount)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
|
||||
const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(meshId);
|
||||
entry.mFrame = gFrameCount;
|
||||
//build matrix palette
|
||||
U32 count = LLSkinningUtil::getMeshJointCount(skin);
|
||||
entry.mMatrixPalette.resize(count);
|
||||
LLSkinningUtil::initSkinningMatrixPalette(&(entry.mMatrixPalette[0]), count, skin, avatarp);
|
||||
|
||||
const LLMatrix4a* mat = &(entry.mMatrixPalette[0]);
|
||||
|
||||
stop_glerror();
|
||||
|
||||
entry.mGLMp.resize(count * 12);
|
||||
|
||||
F32* mp = &(entry.mGLMp[0]);
|
||||
|
||||
for (U32 i = 0; i < count; ++i)
|
||||
if (skin != nullptr)
|
||||
{
|
||||
F32* m = (F32*)mat[i].mMatrix[0].getF32ptr();
|
||||
entry.mBindShapeMatrix = skin->mBindShapeMatrix;
|
||||
|
||||
U32 idx = i * 12;
|
||||
//build matrix palette
|
||||
U32 count = LLSkinningUtil::getMeshJointCount(skin);
|
||||
entry.mMatrixPalette.resize(count);
|
||||
LLSkinningUtil::initSkinningMatrixPalette(&(entry.mMatrixPalette[0]), count, skin, avatarp);
|
||||
|
||||
mp[idx + 0] = m[0];
|
||||
mp[idx + 1] = m[1];
|
||||
mp[idx + 2] = m[2];
|
||||
mp[idx + 3] = m[12];
|
||||
const LLMatrix4a* mat = &(entry.mMatrixPalette[0]);
|
||||
|
||||
mp[idx + 4] = m[4];
|
||||
mp[idx + 5] = m[5];
|
||||
mp[idx + 6] = m[6];
|
||||
mp[idx + 7] = m[13];
|
||||
entry.mGLMp.resize(count * 12);
|
||||
|
||||
mp[idx + 8] = m[8];
|
||||
mp[idx + 9] = m[9];
|
||||
mp[idx + 10] = m[10];
|
||||
mp[idx + 11] = m[14];
|
||||
F32* mp = &(entry.mGLMp[0]);
|
||||
|
||||
for (U32 i = 0; i < count; ++i)
|
||||
{
|
||||
F32* m = (F32*)mat[i].mMatrix[0].getF32ptr();
|
||||
|
||||
U32 idx = i * 12;
|
||||
|
||||
mp[idx + 0] = m[0];
|
||||
mp[idx + 1] = m[1];
|
||||
mp[idx + 2] = m[2];
|
||||
mp[idx + 3] = m[12];
|
||||
|
||||
mp[idx + 4] = m[4];
|
||||
mp[idx + 5] = m[5];
|
||||
mp[idx + 6] = m[6];
|
||||
mp[idx + 7] = m[13];
|
||||
|
||||
mp[idx + 8] = m[8];
|
||||
mp[idx + 9] = m[9];
|
||||
mp[idx + 10] = m[10];
|
||||
mp[idx + 11] = m[14];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
entry.mMatrixPalette.resize(0);
|
||||
entry.mGLMp.resize(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -283,12 +283,13 @@ typedef enum
|
|||
|
||||
std::vector<LLFace*> mRiggedFace[NUM_RIGGED_PASSES];
|
||||
|
||||
LL_ALIGN_PREFIX(16)
|
||||
class MatrixPaletteCache
|
||||
{
|
||||
public:
|
||||
U32 mFrame;
|
||||
LLMeshSkinInfo::matrix_list_t mMatrixPalette;
|
||||
|
||||
LL_ALIGN_16(LLMatrix4a mBindShapeMatrix);
|
||||
// Float array ready to be sent to GL
|
||||
std::vector<F32> mGLMp;
|
||||
|
||||
|
|
@ -296,11 +297,11 @@ typedef enum
|
|||
mFrame(gFrameCount-1)
|
||||
{
|
||||
}
|
||||
};
|
||||
} LL_ALIGN_POSTFIX(16);
|
||||
|
||||
const MatrixPaletteCache& updateSkinInfoMatrixPalette(LLVOAvatar* avatarp, const LLMeshSkinInfo* skin);
|
||||
const MatrixPaletteCache& updateSkinInfoMatrixPalette(LLVOAvatar* avatarp, const LLUUID& meshId);
|
||||
|
||||
typedef std::unordered_map<const LLMeshSkinInfo*, MatrixPaletteCache> matrix_palette_cache_t;
|
||||
typedef std::unordered_map<LLUUID, MatrixPaletteCache> matrix_palette_cache_t;
|
||||
matrix_palette_cache_t mMatrixPaletteCache;
|
||||
|
||||
/*virtual*/ LLViewerTexture *getDebugTexture();
|
||||
|
|
|
|||
|
|
@ -4045,7 +4045,7 @@ S32 LLMeshRepository::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo
|
|||
|
||||
const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj)
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH);
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
if (mesh_id.notNull())
|
||||
{
|
||||
skin_map::iterator iter = mSkinMap.find(mesh_id);
|
||||
|
|
@ -4055,6 +4055,7 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const
|
|||
}
|
||||
|
||||
//no skin info known about given mesh, try to fetch it
|
||||
if (requesting_obj != nullptr)
|
||||
{
|
||||
LLMutexLock lock(mMeshMutex);
|
||||
//add volume to list of loading meshes
|
||||
|
|
|
|||
|
|
@ -586,7 +586,7 @@ public:
|
|||
|
||||
S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
|
||||
static S32 getActualMeshLOD(LLSD& header, S32 lod);
|
||||
const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj);
|
||||
const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj = nullptr);
|
||||
LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id);
|
||||
void fetchPhysicsShape(const LLUUID& mesh_id);
|
||||
bool hasPhysicsShape(const LLUUID& mesh_id);
|
||||
|
|
|
|||
|
|
@ -3555,7 +3555,7 @@ const LLMeshSkinInfo* LLVOVolume::getSkinInfo() const
|
|||
{
|
||||
if (getVolume())
|
||||
{
|
||||
return gMeshRepo.getSkinInfo(getVolume()->getParams().getSculptID(), this);
|
||||
return gMeshRepo.getSkinInfo(getMeshID(), this);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -296,6 +296,9 @@ public:
|
|||
BOOL setIsFlexible(BOOL is_flexible);
|
||||
|
||||
const LLMeshSkinInfo* getSkinInfo() const;
|
||||
|
||||
//convenience accessor for mesh ID (which is stored in sculpt id for legacy reasons)
|
||||
const LLUUID& getMeshID() const { return getVolume()->getParams().getSculptID(); }
|
||||
|
||||
// Extended Mesh Properties
|
||||
U32 getExtendedMeshFlags() const;
|
||||
|
|
|
|||
Loading…
Reference in New Issue