summaryrefslogtreecommitdiff
path: root/indra/newview/lldrawpoolavatar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/lldrawpoolavatar.cpp')
-rw-r--r--indra/newview/lldrawpoolavatar.cpp411
1 files changed, 321 insertions, 90 deletions
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 63abadbcf4..687b13d2c8 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -105,8 +105,8 @@ S32 cube_channel = -1;
static LLTrace::BlockTimerStatHandle FTM_SHADOW_AVATAR("Avatar Shadow");
-LLDrawPoolAvatar::LLDrawPoolAvatar() :
- LLFacePool(POOL_AVATAR)
+LLDrawPoolAvatar::LLDrawPoolAvatar(U32 type) :
+ LLFacePool(type)
{
}
@@ -135,26 +135,17 @@ BOOL LLDrawPoolAvatar::isDead()
}
return TRUE;
}
-
-//-----------------------------------------------------------------------------
-// instancePool()
-//-----------------------------------------------------------------------------
-LLDrawPool *LLDrawPoolAvatar::instancePool()
-{
- return new LLDrawPoolAvatar();
-}
-
-S32 LLDrawPoolAvatar::getVertexShaderLevel() const
+S32 LLDrawPoolAvatar::getShaderLevel() const
{
- return (S32) LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);
+ return (S32) LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);
}
void LLDrawPoolAvatar::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
if (sShaderLevel > 0)
{
@@ -305,7 +296,7 @@ void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass)
void LLDrawPoolAvatar::beginPostDeferredAlpha()
{
sSkipOpaque = TRUE;
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
sVertexProgram = &gDeferredAvatarAlphaProgram;
sRenderingSkinned = TRUE;
@@ -396,7 +387,7 @@ void LLDrawPoolAvatar::endPostDeferredAlpha()
gPipeline.unbindDeferredShader(*sVertexProgram);
sDiffuseChannel = 0;
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
}
void LLDrawPoolAvatar::renderPostDeferred(S32 pass)
@@ -455,8 +446,13 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
sVertexProgram = &gDeferredAvatarAlphaShadowProgram;
// bind diffuse tex so we can reference the alpha channel...
- sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-
+ S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
+ sDiffuseChannel = 0;
+ if (loc != -1)
+ {
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ }
+
if ((sShaderLevel > 0)) // for hardware blending
{
sRenderingSkinned = TRUE;
@@ -470,8 +466,13 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
sVertexProgram = &gDeferredAvatarAlphaMaskShadowProgram;
// bind diffuse tex so we can reference the alpha channel...
- sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-
+ S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
+ sDiffuseChannel = 0;
+ if (loc != -1)
+ {
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ }
+
if ((sShaderLevel > 0)) // for hardware blending
{
sRenderingSkinned = TRUE;
@@ -485,7 +486,12 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
sVertexProgram = &gDeferredAttachmentAlphaShadowProgram;
// bind diffuse tex so we can reference the alpha channel...
- sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
+ sDiffuseChannel = 0;
+ if (loc != -1)
+ {
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ }
if ((sShaderLevel > 0)) // for hardware blending
{
@@ -500,7 +506,12 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
sVertexProgram = &gDeferredAttachmentAlphaMaskShadowProgram;
// bind diffuse tex so we can reference the alpha channel...
- sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
+ sDiffuseChannel = 0;
+ if (loc != -1)
+ {
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ }
if ((sShaderLevel > 0)) // for hardware blending
{
@@ -513,7 +524,12 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
else // SHADOW_PASS_ATTACHMENT_OPAQUE
{
sVertexProgram = &gDeferredAttachmentShadowProgram;
- sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
+ sDiffuseChannel = 0;
+ if (loc != -1)
+ {
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ }
sVertexProgram->bind();
}
}
@@ -556,12 +572,12 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
{
return;
}
-
- BOOL impostor = avatarp->isImpostor();
- if (impostor
- && LLVOAvatar::AV_DO_NOT_RENDER != avatarp->getVisualMuteSettings()
- && LLVOAvatar::AV_ALWAYS_RENDER != avatarp->getVisualMuteSettings())
+ LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();
+ BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();
+ if (oa == LLVOAvatar::AOA_INVISIBLE ||
+ (impostor && oa == LLVOAvatar::AOA_JELLYDOLL))
{
+ // No shadows for jellydolled or invisible avs.
return;
}
@@ -776,7 +792,7 @@ void LLDrawPoolAvatar::beginImpostor()
gImpostorProgram.setMinimumAlpha(0.01f);
}
- gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
+ gPipeline.enableLightsFullbright();
sDiffuseChannel = 0;
}
@@ -806,6 +822,14 @@ void LLDrawPoolAvatar::beginRigid()
{ //eyeballs render with the specular shader
sVertexProgram->bind();
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
}
else
@@ -816,7 +840,7 @@ void LLDrawPoolAvatar::beginRigid()
void LLDrawPoolAvatar::endRigid()
{
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
if (sVertexProgram != NULL)
{
sVertexProgram->unbind();
@@ -841,7 +865,7 @@ void LLDrawPoolAvatar::beginDeferredImpostor()
void LLDrawPoolAvatar::endDeferredImpostor()
{
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL);
sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP);
sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
@@ -856,11 +880,19 @@ void LLDrawPoolAvatar::beginDeferredRigid()
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
sVertexProgram->bind();
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
void LLDrawPoolAvatar::endDeferredRigid()
{
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
sVertexProgram->unbind();
gGL.getTexUnit(0)->activate();
@@ -899,6 +931,14 @@ void LLDrawPoolAvatar::beginSkinned()
sVertexProgram->bind();
sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
gGL.getTexUnit(0)->activate();
}
else
@@ -908,6 +948,14 @@ void LLDrawPoolAvatar::beginSkinned()
// software skinning, use a basic shader for windlight.
// TODO: find a better fallback method for software skinning.
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
}
@@ -926,7 +974,7 @@ void LLDrawPoolAvatar::endSkinned()
sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP);
gGL.getTexUnit(0)->activate();
sVertexProgram->unbind();
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
}
else
{
@@ -970,6 +1018,14 @@ void LLDrawPoolAvatar::beginRiggedSimple()
{
sDiffuseChannel = 0;
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
}
@@ -1035,6 +1091,16 @@ void LLDrawPoolAvatar::beginRiggedGlow()
sVertexProgram->bind();
sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, LLPipeline::sRenderDeferred ? 2.2f : 1.1f);
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
}
@@ -1082,16 +1148,22 @@ void LLDrawPoolAvatar::beginRiggedFullbright()
sDiffuseChannel = 0;
sVertexProgram->bind();
- if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else if (LLPipeline::sRenderDeferred)
{
- sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+ sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
}
else
{
- sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
-
- F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
- sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
}
}
}
@@ -1134,6 +1206,14 @@ void LLDrawPoolAvatar::beginRiggedShinySimple()
if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
{
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false);
}
}
@@ -1184,17 +1264,32 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()
if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
{
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false);
- if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
+ if (LLPipeline::sRenderingHUDs)
{
sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
- }
- else
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else if (LLPipeline::sRenderDeferred)
{
- sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+ else
+ {
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
}
}
}
@@ -1216,6 +1311,14 @@ void LLDrawPoolAvatar::beginDeferredRiggedSimple()
sVertexProgram = &gDeferredSkinnedDiffuseProgram;
sDiffuseChannel = 0;
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
void LLDrawPoolAvatar::endDeferredRiggedSimple()
@@ -1229,6 +1332,14 @@ void LLDrawPoolAvatar::beginDeferredRiggedBump()
{
sVertexProgram = &gDeferredSkinnedBumpProgram;
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
}
@@ -1261,6 +1372,14 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass)
}
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
@@ -1288,13 +1407,21 @@ void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass)
void LLDrawPoolAvatar::beginDeferredSkinned()
{
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
sVertexProgram = &gDeferredAvatarProgram;
sRenderingSkinned = TRUE;
sVertexProgram->bind();
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
-
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
gGL.getTexUnit(0)->activate();
}
@@ -1307,7 +1434,7 @@ void LLDrawPoolAvatar::endDeferredSkinned()
sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
gGL.getTexUnit(0)->activate();
}
@@ -1337,7 +1464,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
return;
}
- LLVOAvatar *avatarp;
+ LLVOAvatar *avatarp = NULL;
if (single_avatar)
{
@@ -1383,11 +1510,12 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
return;
}
- BOOL impostor = avatarp->isImpostor() && !single_avatar;
+ BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor() && !single_avatar;
if (( avatarp->isInMuteList()
|| impostor
- || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()) ) && pass != 0)
+ || (LLVOAvatar::AOA_NORMAL != avatarp->getOverallAppearance() && !avatarp->needsImpostorUpdate()) ) && pass != 0)
+// || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()) ) && pass != 0)
{ //don't draw anything but the impostor for impostored avatars
return;
}
@@ -1397,6 +1525,13 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
return;
}
+ LLVOAvatar *attached_av = avatarp->getAttachedAvatar();
+ if (attached_av && LLVOAvatar::AOA_NORMAL != attached_av->getOverallAppearance())
+ {
+ // Animesh attachment of a jellydolled or invisible parent - don't show
+ return;
+ }
+
if (pass == 0)
{
if (!LLPipeline::sReflectionRender)
@@ -1404,7 +1539,8 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
LLVOAvatar::sNumVisibleAvatars++;
}
- if (impostor || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()))
+// if (impostor || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()))
+ if (impostor || (LLVOAvatar::AOA_NORMAL != avatarp->getOverallAppearance() && !avatarp->needsImpostorUpdate()))
{
if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && avatarp->mImpostor.isComplete())
{
@@ -1604,11 +1740,16 @@ void LLDrawPoolAvatar::getRiggedGeometry(
LLVolume* volume,
const LLVolumeFace& vol_face)
{
- face->setGeomIndex(0);
- face->setIndicesIndex(0);
-
- //rigged faces do not batch textures
- face->setTextureIndex(255);
+ face->setGeomIndex(0);
+ face->setIndicesIndex(0);
+
+ if (face->getTextureIndex() != FACE_DO_NOT_BATCH_TEXTURES)
+ {
+ face->setDrawInfo(NULL);
+ }
+
+ //rigged faces do not batch textures
+ face->setTextureIndex(FACE_DO_NOT_BATCH_TEXTURES);
if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable())
{
@@ -1673,7 +1814,7 @@ void LLDrawPoolAvatar::getRiggedGeometry(
}
else
{
- face->setPoolType(LLDrawPool::POOL_AVATAR);
+ face->setPoolType(mType); // either POOL_AVATAR or POOL_CONTROL_AV
}
//LL_INFOS() << "Rebuilt face " << face->getTEOffset() << " of " << face->getDrawable() << " at " << gFrameTimeSeconds << LL_ENDL;
@@ -1697,15 +1838,13 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
LLFace* face,
const LLMeshSkinInfo* skin,
LLVolume* volume,
- const LLVolumeFace& vol_face)
+ LLVolumeFace& vol_face)
{
LLVector4a* weights = vol_face.mWeights;
if (!weights)
{
return;
}
- // FIXME ugly const cast
- LLSkinningUtil::scrubInvalidJoints(avatar, const_cast<LLMeshSkinInfo*>(skin));
LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();
LLDrawable* drawable = face->getDrawable();
@@ -1715,6 +1854,48 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
return;
}
+ const U32 max_joints = LLSkinningUtil::getMaxJointCount();
+
+#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
+ #define CONDITION_WEIGHT(f) ((U8)llclamp((S32)f, (S32)0, (S32)max_joints-1))
+ LLVector4a* just_weights = vol_face.mJustWeights;
+ // we need to calculate the separated indices and store just the matrix weights for this vol...
+ if (!vol_face.mJointIndices)
+ {
+ // not very consty after all...
+ vol_face.allocateJointIndices(vol_face.mNumVertices);
+ just_weights = vol_face.mJustWeights;
+
+ U8* joint_indices_cursor = vol_face.mJointIndices;
+ for (int i = 0; i < vol_face.mNumVertices; i++)
+ {
+ F32* w = weights[i].getF32ptr();
+ F32* w_ = just_weights[i].getF32ptr();
+
+ F32 w0 = floorf(w[0]);
+ F32 w1 = floorf(w[1]);
+ F32 w2 = floorf(w[2]);
+ F32 w3 = floorf(w[3]);
+
+ joint_indices_cursor[0] = CONDITION_WEIGHT(w0);
+ joint_indices_cursor[1] = CONDITION_WEIGHT(w1);
+ joint_indices_cursor[2] = CONDITION_WEIGHT(w2);
+ joint_indices_cursor[3] = CONDITION_WEIGHT(w3);
+
+ // remove joint portion of combined weight
+ w_[0] = w[0] - w0;
+ w_[1] = w[1] - w1;
+ w_[2] = w[2] - w2;
+ w_[3] = w[3] - w3;
+
+ joint_indices_cursor += 4;
+ }
+ }
+#endif
+
+ // FIXME ugly const cast
+ LLSkinningUtil::scrubInvalidJoints(avatar, const_cast<LLMeshSkinInfo*>(skin));
+
U32 data_mask = face->getRiggedVertexBufferDataMask();
if (!vol_face.mWeightsScrubbed)
@@ -1791,29 +1972,67 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
LLMatrix4a bind_shape_matrix;
bind_shape_matrix.loadu(skin->mBindShapeMatrix);
- const U32 max_joints = LLSkinningUtil::getMaxJointCount();
- for (U32 j = 0; j < buffer->getNumVerts(); ++j)
- {
- LLMatrix4a final_mat;
- LLSkinningUtil::getPerVertexSkinMatrix(weights[j].getF32ptr(), mat, false, final_mat, max_joints);
-
- 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;
- }
- }
+#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
+ {
+ for (U32 j = 0; j < buffer->getNumVerts(); ++j)
+ {
+ LLMatrix4a final_mat;
+ LLSkinningUtil::getPerVertexSkinMatrix(weights[j].getF32ptr(), mat, false, final_mat, max_joints);
+
+ 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;
+ }
+ }
+ }
}
}
@@ -2079,12 +2298,24 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
if (face->mTextureMatrix && vobj->mTexAnimMode)
{
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadMatrix((F32*) face->mTextureMatrix->mMatrix);
+ U32 tex_index = gGL.getCurrentTexUnitIndex();
+
+ if (tex_index <= 1)
+ {
+ gGL.matrixMode(LLRender::eMatrixMode(LLRender::MM_TEXTURE0 + tex_index));
+ gGL.pushMatrix();
+ gGL.loadMatrix((F32*) face->mTextureMatrix->mMatrix);
+ }
+
buff->setBuffer(data_mask);
buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+
+ if (tex_index <= 1)
+ {
+ gGL.matrixMode(LLRender::eMatrixMode(LLRender::MM_TEXTURE0 + tex_index));
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
}
else
{
@@ -2153,7 +2384,7 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
stop_glerror();
- const LLVolumeFace& vol_face = volume->getVolumeFace(te);
+ LLVolumeFace& vol_face = volume->getVolumeFace(te);
updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face);
}
}
@@ -2267,7 +2498,7 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const
void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type)
{
llassert (facep->isState(LLFace::RIGGED));
- llassert(getType() == LLDrawPool::POOL_AVATAR);
+ llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV);
if (facep->getPool() && facep->getPool() != this)
{
LL_ERRS() << "adding rigged face that's already in another pool" << LL_ENDL;
@@ -2289,7 +2520,7 @@ void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type)
void LLDrawPoolAvatar::removeRiggedFace(LLFace* facep)
{
llassert (facep->isState(LLFace::RIGGED));
- llassert(getType() == LLDrawPool::POOL_AVATAR);
+ llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV);
if (facep->getPool() != this)
{
LL_ERRS() << "Tried to remove a rigged face from the wrong pool" << LL_ENDL;