summaryrefslogtreecommitdiff
path: root/indra/newview/lldrawpoolavatar.cpp
diff options
context:
space:
mode:
authorGraham Linden <graham@lindenlab.com>2018-08-16 00:31:39 +0100
committerGraham Linden <graham@lindenlab.com>2018-08-16 00:31:39 +0100
commit3237923e10a34d14ac4aac17400811cb1c7c3bdf (patch)
tree94815c2fd75507f0cee47562af427a4426e86e69 /indra/newview/lldrawpoolavatar.cpp
parent3983f5b1e2d79602a7d685633271d824a906ed2f (diff)
MAINT-3699 new shaders supporting alpha blend/mask rigged content.
Make shader loading debug logging of uniforms use ShaderUniform to make supression simpler.
Diffstat (limited to 'indra/newview/lldrawpoolavatar.cpp')
-rw-r--r--indra/newview/lldrawpoolavatar.cpp236
1 files changed, 209 insertions, 27 deletions
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index ef69990170..b318156cf8 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -60,6 +60,7 @@ static U32 sShaderLevel = 0;
LLGLSLShader* LLDrawPoolAvatar::sVertexProgram = NULL;
BOOL LLDrawPoolAvatar::sSkipOpaque = FALSE;
BOOL LLDrawPoolAvatar::sSkipTransparent = FALSE;
+S32 LLDrawPoolAvatar::sShadowPass = -1;
S32 LLDrawPoolAvatar::sDiffuseChannel = 0;
F32 LLDrawPoolAvatar::sMinimumAlpha = 0.2f;
@@ -403,19 +404,33 @@ void LLDrawPoolAvatar::renderPostDeferred(S32 pass)
S32 LLDrawPoolAvatar::getNumShadowPasses()
{
- return 2;
+ // avatars opaque, avatar alpha, avatar alpha mask, alpha attachments, alpha mask attachments, opaque attachments...
+ return NUM_SHADOW_PASSES;
}
void LLDrawPoolAvatar::beginShadowPass(S32 pass)
{
LL_RECORD_BLOCK_TIME(FTM_SHADOW_AVATAR);
- if (pass == 0)
+ if (pass == SHADOW_PASS_AVATAR_OPAQUE)
{
sVertexProgram = &gDeferredAvatarShadowProgram;
- //gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.2f);
+ if ((sShaderLevel > 0)) // for hardware blending
+ {
+ sRenderingSkinned = TRUE;
+ sVertexProgram->bind();
+ }
+ gGL.diffuseColor4f(1,1,1,1);
+ }
+ else if (pass == SHADOW_PASS_AVATAR_ALPHA_BLEND)
+ {
+ sVertexProgram = &gDeferredAvatarAlphaShadowProgram;
+
+ // bind diffuse tex so we can reference the alpha channel...
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+
if ((sShaderLevel > 0)) // for hardware blending
{
sRenderingSkinned = TRUE;
@@ -424,7 +439,52 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
gGL.diffuseColor4f(1,1,1,1);
}
- else
+ else if (pass == SHADOW_PASS_AVATAR_ALPHA_MASK)
+ {
+ sVertexProgram = &gDeferredAvatarAlphaMaskShadowProgram;
+
+ // bind diffuse tex so we can reference the alpha channel...
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+
+ if ((sShaderLevel > 0)) // for hardware blending
+ {
+ sRenderingSkinned = TRUE;
+ sVertexProgram->bind();
+ }
+
+ gGL.diffuseColor4f(1,1,1,1);
+ }
+ else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_BLEND)
+ {
+ sVertexProgram = &gDeferredAttachmentAlphaShadowProgram;
+
+ // bind diffuse tex so we can reference the alpha channel...
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+
+ if ((sShaderLevel > 0)) // for hardware blending
+ {
+ sRenderingSkinned = TRUE;
+ sVertexProgram->bind();
+ }
+
+ gGL.diffuseColor4f(1,1,1,1);
+ }
+ else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_MASK)
+ {
+ sVertexProgram = &gDeferredAttachmentAlphaMaskShadowProgram;
+
+ // bind diffuse tex so we can reference the alpha channel...
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+
+ if ((sShaderLevel > 0)) // for hardware blending
+ {
+ sRenderingSkinned = TRUE;
+ sVertexProgram->bind();
+ }
+
+ gGL.diffuseColor4f(1,1,1,1);
+ }
+ else // SHADOW_PASS_ATTACHMENT_OPAQUE
{
sVertexProgram = &gDeferredAttachmentShadowProgram;
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
@@ -435,20 +495,19 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
void LLDrawPoolAvatar::endShadowPass(S32 pass)
{
LL_RECORD_BLOCK_TIME(FTM_SHADOW_AVATAR);
- if (pass == 0)
- {
- if (sShaderLevel > 0)
- {
- sRenderingSkinned = FALSE;
- sVertexProgram->unbind();
- }
- }
- else
+
+ if (pass == SHADOW_PASS_ATTACHMENT_OPAQUE)
{
LLVertexBuffer::unbind();
+ }
+
+ if (sShaderLevel > 0)
+ {
sVertexProgram->unbind();
- sVertexProgram = NULL;
}
+ sVertexProgram = NULL;
+ sRenderingSkinned = FALSE;
+ LLDrawPoolAvatar::sShadowPass = -1;
}
void LLDrawPoolAvatar::renderShadow(S32 pass)
@@ -480,16 +539,68 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
return;
}
- if (pass == 0)
+ LLDrawPoolAvatar::sShadowPass = pass;
+
+ if (pass == SHADOW_PASS_AVATAR_OPAQUE)
{
+ LLDrawPoolAvatar::sSkipTransparent = true;
avatarp->renderSkinned();
+ LLDrawPoolAvatar::sSkipTransparent = false;
}
- else
+ else if (pass == SHADOW_PASS_AVATAR_ALPHA_BLEND)
{
- for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i)
- {
- renderRigged(avatarp, i);
- }
+ LLDrawPoolAvatar::sSkipOpaque = true;
+ avatarp->renderSkinned();
+ LLDrawPoolAvatar::sSkipOpaque = false;
+ }
+ else if (pass == SHADOW_PASS_AVATAR_ALPHA_MASK)
+ {
+ LLDrawPoolAvatar::sSkipOpaque = true;
+ avatarp->renderSkinned();
+ LLDrawPoolAvatar::sSkipOpaque = false;
+ }
+ else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_BLEND) // rigged alpha
+ {
+ LLDrawPoolAvatar::sSkipOpaque = true;
+ renderRigged(avatarp, RIGGED_MATERIAL_ALPHA);
+ renderRigged(avatarp, RIGGED_MATERIAL_ALPHA);
+ renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE);
+ renderRigged(avatarp, RIGGED_ALPHA);
+ renderRigged(avatarp, RIGGED_FULLBRIGHT_ALPHA);
+ renderRigged(avatarp, RIGGED_GLOW);
+ LLDrawPoolAvatar::sSkipOpaque = false;
+ }
+ else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_MASK) // rigged alpha mask
+ {
+ LLDrawPoolAvatar::sSkipOpaque = true;
+ renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_MASK);
+ renderRigged(avatarp, RIGGED_NORMMAP_MASK);
+ renderRigged(avatarp, RIGGED_SPECMAP_MASK);
+ renderRigged(avatarp, RIGGED_NORMSPEC_MASK);
+ renderRigged(avatarp, RIGGED_GLOW);
+ LLDrawPoolAvatar::sSkipOpaque = false;
+ }
+ else // rigged opaque (SHADOW_PASS_ATTACHMENT_OPAQUE
+ {
+ LLDrawPoolAvatar::sSkipTransparent = true;
+ renderRigged(avatarp, RIGGED_MATERIAL);
+ renderRigged(avatarp, RIGGED_SPECMAP);
+ renderRigged(avatarp, RIGGED_SPECMAP_BLEND);
+ renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE);
+ renderRigged(avatarp, RIGGED_NORMMAP);
+ renderRigged(avatarp, RIGGED_NORMMAP_BLEND);
+ renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE);
+ renderRigged(avatarp, RIGGED_NORMSPEC);
+ renderRigged(avatarp, RIGGED_NORMSPEC_BLEND);
+ renderRigged(avatarp, RIGGED_NORMSPEC_EMISSIVE);
+ renderRigged(avatarp, RIGGED_SIMPLE);
+ renderRigged(avatarp, RIGGED_FULLBRIGHT);
+ renderRigged(avatarp, RIGGED_SHINY);
+ renderRigged(avatarp, RIGGED_FULLBRIGHT_SHINY);
+ renderRigged(avatarp, RIGGED_GLOW);
+ renderRigged(avatarp, RIGGED_DEFERRED_BUMP);
+ renderRigged(avatarp, RIGGED_DEFERRED_SIMPLE);
+ LLDrawPoolAvatar::sSkipTransparent = false;
}
}
@@ -1737,8 +1848,81 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
LLVertexBuffer* buff = face->getVertexBuffer();
+ const LLTextureEntry* tex_entry = face->getTextureEntry();
+ LLMaterial* mat = tex_entry ? tex_entry->getMaterialParams().get() : nullptr;
+
+ if (LLDrawPoolAvatar::sShadowPass >= 0)
+ {
+ bool is_alpha_blend = false;
+ bool is_alpha_mask = false;
+
+ if (mat)
+ {
+ switch (LLMaterial::eDiffuseAlphaMode(mat->getDiffuseAlphaMode()))
+ {
+ case LLMaterial::DIFFUSE_ALPHA_MODE_MASK:
+ {
+ is_alpha_mask = true;
+ }
+ break;
+
+ case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND:
+ {
+ is_alpha_blend = true;
+ }
+ break;
+
+ case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE:
+ case LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT:
+ case LLMaterial::DIFFUSE_ALPHA_MODE_NONE:
+ default:
+ break;
+ }
+ }
+
+ if (tex_entry)
+ {
+ if (tex_entry->getAlpha() <= 0.99f)
+ {
+ is_alpha_blend = true;
+ }
+ }
+
+ LLViewerTexture* tex = face->getTexture(LLRender::DIFFUSE_MAP);
+ if (tex)
+ {
+ LLGLenum image_format = tex->getPrimaryFormat();
+ if (tex->getIsAlphaMask())
+ {
+ is_alpha_mask = true;
+ }
+ else if (!is_alpha_mask && (image_format == GL_RGBA || image_format == GL_ALPHA))
+ {
+ is_alpha_blend = true;
+ }
+ }
+
+ // if this is alpha mask content and we're doing opaques or a non-alpha-mask shadow pass...
+ if (is_alpha_mask && (LLDrawPoolAvatar::sSkipTransparent || LLDrawPoolAvatar::sShadowPass != SHADOW_PASS_ATTACHMENT_ALPHA_MASK))
+ {
+ return;
+ }
+
+ // if this is alpha blend content and we're doing opaques or a non-alpha-blend shadow pass...
+ if (is_alpha_blend && (LLDrawPoolAvatar::sSkipTransparent || LLDrawPoolAvatar::sShadowPass != SHADOW_PASS_ATTACHMENT_ALPHA_BLEND))
+ {
+ return;
+ }
+
+ // if this is opaque content and we're skipping opaques...
+ if (!is_alpha_mask && !is_alpha_blend && LLDrawPoolAvatar::sSkipOpaque)
+ {
+ return;
+ }
+ }
+
if (buff)
- {
+ {
if (sShaderLevel > 0)
{
// upload matrix palette to shader
@@ -1794,9 +1978,6 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
gGL.diffuseColor4f(0,0,0,face->getTextureEntry()->getGlow());
}*/
- const LLTextureEntry* te = face->getTextureEntry();
- LLMaterial* mat = te->getMaterialParams().get();
-
if (mat)
{
//order is important here LLRender::DIFFUSE_MAP should be last, becouse it change
@@ -1827,12 +2008,12 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
if (mat->getSpecularID().isNull())
{
- env = te->getShiny()*0.25f;
+ env = tex_entry->getShiny()*0.25f;
col.set(env,env,env,0);
spec = env;
}
- BOOL fullbright = te->getFullbright();
+ BOOL fullbright = tex_entry->getFullbright();
sVertexProgram->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, fullbright ? 1.f : 0.f);
sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec);
@@ -1840,7 +2021,8 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
{
- sVertexProgram->setMinimumAlpha(mat->getAlphaMaskCutoff()/255.f);
+ F32 cutoff = mat->getAlphaMaskCutoff()/255.f;
+ sVertexProgram->setMinimumAlpha(cutoff);
}
else
{