summaryrefslogtreecommitdiff
path: root/indra/newview/lldrawpoolalpha.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/lldrawpoolalpha.cpp')
-rw-r--r--indra/newview/lldrawpoolalpha.cpp352
1 files changed, 212 insertions, 140 deletions
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 6c1abb24c9..aa8d4d167e 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -50,10 +50,14 @@
#include "llglcommonfunc.h"
#include "llvoavatar.h"
+#include "llenvironment.h"
+
BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
#define current_shader (LLGLSLShader::sCurBoundShaderPtr)
+LLVector4 LLDrawPoolAlpha::sWaterPlane;
+
static BOOL deferred_render = FALSE;
// minimum alpha before discarding a fragment
@@ -82,6 +86,11 @@ void LLDrawPoolAlpha::prerender()
// 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);
+
+ if (LLPipeline::sRenderPBR)
+ {
+ gPipeline.setupHWLights(NULL);
+ }
}
S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
@@ -90,11 +99,13 @@ S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
}
// set some common parameters on the given shader to prepare for alpha rendering
-static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool deferredEnvironment)
+static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool deferredEnvironment, F32 water_sign)
{
static LLCachedControl<F32> displayGamma(gSavedSettings, "RenderDeferredDisplayGamma");
F32 gamma = displayGamma;
+ static LLStaticHashedString waterSign("waterSign");
+
// Does this deferred shader need environment uniforms set such as sun_dir, etc. ?
// NOTE: We don't actually need a gbuffer since we are doing forward rendering (for transparency) post deferred rendering
// TODO: bindDeferredShader() probably should have the updating of the environment uniforms factored out into updateShaderEnvironmentUniforms()
@@ -109,6 +120,8 @@ static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool d
}
shader->uniform1i(LLShaderMgr::NO_ATMO, (LLPipeline::sRenderingHUDs) ? 1 : 0);
shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
+ shader->uniform1f(waterSign, water_sign);
+ shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV);
if (LLPipeline::sImpostorRender)
{
@@ -126,33 +139,55 @@ static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool d
//also prepare rigged variant
if (shader->mRiggedVariant && shader->mRiggedVariant != shader)
{
- prepare_alpha_shader(shader->mRiggedVariant, textureGamma, deferredEnvironment);
+ prepare_alpha_shader(shader->mRiggedVariant, textureGamma, deferredEnvironment, water_sign);
}
}
+extern BOOL gCubeSnapshot;
+
void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+
+ if ((!LLPipeline::sRenderTransparentWater || gCubeSnapshot) && getType() == LLDrawPool::POOL_ALPHA_PRE_WATER)
+ { // don't render alpha objects on the other side of the water plane if water is opaque
+ return;
+ }
deferred_render = TRUE;
+ F32 water_sign = 1.f;
+
+ if (getType() == LLDrawPool::POOL_ALPHA_PRE_WATER)
+ {
+ water_sign = -1.f;
+ }
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ water_sign *= -1.f;
+ }
+
// prepare shaders
emissive_shader = (LLPipeline::sRenderDeferred) ? &gDeferredEmissiveProgram :
(LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
- prepare_alpha_shader(emissive_shader, true, false);
+ prepare_alpha_shader(emissive_shader, true, false, water_sign);
fullbright_shader = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightAlphaMaskProgram :
(LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightAlphaMaskProgram;
- prepare_alpha_shader(fullbright_shader, true, false);
+ prepare_alpha_shader(fullbright_shader, true, true, water_sign);
simple_shader = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
(LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram;
- prepare_alpha_shader(simple_shader, false, true); //prime simple shader (loads shadow relevant uniforms)
+ prepare_alpha_shader(simple_shader, false, true, water_sign); //prime simple shader (loads shadow relevant uniforms)
- for (int i = 0; i < LLMaterial::SHADER_COUNT; ++i)
+ LLGLSLShader* materialShader = LLPipeline::sUnderWaterRender ? gDeferredMaterialWaterProgram : gDeferredMaterialProgram;
+ for (int i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
{
- prepare_alpha_shader(LLPipeline::sUnderWaterRender ? &gDeferredMaterialWaterProgram[i] : &gDeferredMaterialProgram[i], false, false); // note: bindDeferredShader will get called during render loop for materials
+ prepare_alpha_shader(&materialShader[i], false, false, water_sign);
}
+ prepare_alpha_shader(&gDeferredPBRAlphaProgram, false, false, water_sign);
+
// first pass, render rigged objects only and render to depth buffer
forwardRender(true);
@@ -160,13 +195,13 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
forwardRender();
// final pass, render to depth for depth of field effects
- if (!LLPipeline::sImpostorRender && gSavedSettings.getBOOL("RenderDepthOfField"))
+ if (!LLPipeline::sImpostorRender && gSavedSettings.getBOOL("RenderDepthOfField") && !gCubeSnapshot)
{
//update depth buffer sampler
- gPipeline.mScreen.flush();
- gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(),
- 0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
- gPipeline.mDeferredDepth.bindTarget();
+ /*gPipeline.mRT->screen.flush();
+ gPipeline.mRT->deferredDepth.copyContents(gPipeline.mRT->deferredScreen, 0, 0, gPipeline.mRT->deferredScreen.getWidth(), gPipeline.mRT->deferredScreen.getHeight(),
+ 0, 0, gPipeline.mRT->deferredDepth.getWidth(), gPipeline.mRT->deferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ gPipeline.mRT->deferredDepth.bindTarget();*/
simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
simple_shader->bind();
@@ -180,8 +215,8 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2,
true); // <--- discard mostly transparent faces
- gPipeline.mDeferredDepth.flush();
- gPipeline.mScreen.bindTarget();
+ //gPipeline.mRT->deferredDepth.flush();
+ //gPipeline.mRT->screen.bindTarget();
gGL.setColorMask(true, false);
}
@@ -407,62 +442,76 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material)
{
bool tex_setup = false;
- if (deferred_render && use_material && current_shader)
+ if (draw->mGLTFMaterial)
{
- 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);
- }
+ if (draw->mTextureMatrix)
+ {
+ tex_setup = true;
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadMatrix((GLfloat*)draw->mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+ }
}
- else if (current_shader == simple_shader || current_shader == simple_shader->mRiggedVariant)
+ else
{
- current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
- current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
- }
- if (draw->mTextureList.size() > 1)
- {
- for (U32 i = 0; i < draw->mTextureList.size(); ++i)
- {
- if (draw->mTextureList[i].notNull())
- {
- gGL.getTexUnit(i)->bindFast(draw->mTextureList[i]);
- }
- }
- }
- else
- { //not batching textures or batch has only 1 texture -- might need a texture matrix
- if (draw->mTexture.notNull())
- {
- if (use_material)
- {
- current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, draw->mTexture);
- }
- else
- {
- gGL.getTexUnit(0)->bindFast(draw->mTexture);
- }
+ if (deferred_render && use_material && current_shader)
+ {
+ if (draw->mNormalMap)
+ {
+ draw->mNormalMap->addTextureStats(draw->mVSize);
+ current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap);
+ }
- if (draw->mTextureMatrix)
- {
- tex_setup = true;
- gGL.getTexUnit(0)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadMatrix((GLfloat*) draw->mTextureMatrix->mMatrix);
- gPipeline.mTextureMatrixOps++;
- }
- }
- else
- {
- gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE);
- }
- }
+ if (draw->mSpecularMap)
+ {
+ draw->mSpecularMap->addTextureStats(draw->mVSize);
+ current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap);
+ }
+ }
+ else if (current_shader == simple_shader || current_shader == simple_shader->mRiggedVariant)
+ {
+ current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
+ current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
+ }
+ if (draw->mTextureList.size() > 1)
+ {
+ for (U32 i = 0; i < draw->mTextureList.size(); ++i)
+ {
+ if (draw->mTextureList[i].notNull())
+ {
+ gGL.getTexUnit(i)->bindFast(draw->mTextureList[i]);
+ }
+ }
+ }
+ else
+ { //not batching textures or batch has only 1 texture -- might need a texture matrix
+ if (draw->mTexture.notNull())
+ {
+ if (use_material)
+ {
+ current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, draw->mTexture);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->bindFast(draw->mTexture);
+ }
+
+ if (draw->mTextureMatrix)
+ {
+ tex_setup = true;
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadMatrix((GLfloat*)draw->mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+ }
+ }
+ else
+ {
+ gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE);
+ }
+ }
+ }
return tex_setup;
}
@@ -611,94 +660,117 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
}
}
- LLRenderPass::applyModelMatrix(params);
+ LLRenderPass::applyModelMatrix(params);
- LLMaterial* mat = NULL;
+ LLMaterial* mat = NULL;
+ LLGLTFMaterial *gltf_mat = params.mGLTFMaterial; // Also see: LLPipeline::getPoolTypeFromTE()
+ bool is_pbr = LLPipeline::sRenderPBR && gltf_mat;
- if (deferred_render)
- {
- mat = params.mMaterial;
- }
-
- if (params.mFullbright)
- {
- // Turn off lighting if it hasn't already been so.
- if (light_enabled || !initialized_lighting)
- {
- initialized_lighting = TRUE;
- target_shader = fullbright_shader;
+ LLGLDisable cull_face(is_pbr && gltf_mat->mDoubleSided ? GL_CULL_FACE : 0);
- light_enabled = FALSE;
- }
- }
- // Turn on lighting if it isn't already.
- else if (!light_enabled || !initialized_lighting)
- {
- initialized_lighting = TRUE;
- target_shader = simple_shader;
- light_enabled = TRUE;
- }
+ if (is_pbr && gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_BLEND)
+ {
+ target_shader = &gDeferredPBRAlphaProgram;
+ if (params.mAvatar != nullptr)
+ {
+ target_shader = target_shader->mRiggedVariant;
+ }
- if (deferred_render && mat)
- {
- U32 mask = params.mShaderMask;
+ if (current_shader != target_shader)
+ {
+ gPipeline.bindDeferredShader(*target_shader);
+ }
- llassert(mask < LLMaterial::SHADER_COUNT);
- target_shader = &(gDeferredMaterialProgram[mask]);
+ params.mGLTFMaterial->bind(target_shader);
+ }
+ else
+ {
+ if (deferred_render)
+ {
+ mat = params.mMaterial;
+ }
+
+ if (params.mFullbright)
+ {
+ // Turn off lighting if it hasn't already been so.
+ if (light_enabled || !initialized_lighting)
+ {
+ initialized_lighting = TRUE;
+ target_shader = fullbright_shader;
+
+ light_enabled = FALSE;
+ }
+ }
+ // Turn on lighting if it isn't already.
+ else if (!light_enabled || !initialized_lighting)
+ {
+ initialized_lighting = TRUE;
+ target_shader = simple_shader;
+ light_enabled = TRUE;
+ }
+
+ if (deferred_render && mat)
+ {
+ U32 mask = params.mShaderMask;
+
+ llassert(mask < LLMaterial::SHADER_COUNT);
+ target_shader = &(gDeferredMaterialProgram[mask]);
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ target_shader = &(gDeferredMaterialWaterProgram[mask]);
+ }
+
+ if (params.mAvatar != nullptr)
+ {
+ llassert(target_shader->mRiggedVariant != nullptr);
+ target_shader = target_shader->mRiggedVariant;
+ }
+
+ if (current_shader != target_shader)
+ {
+ gPipeline.bindDeferredShader(*target_shader);
+ }
+ }
+ else if (!params.mFullbright)
+ {
+ target_shader = simple_shader;
+ }
+ else
+ {
+ target_shader = fullbright_shader;
+ }
- if (LLPipeline::sUnderWaterRender)
- {
- target_shader = &(gDeferredMaterialWaterProgram[mask]);
- }
if (params.mAvatar != nullptr)
{
- llassert(target_shader->mRiggedVariant != nullptr);
target_shader = target_shader->mRiggedVariant;
}
- if (current_shader != target_shader)
- {
- gPipeline.bindDeferredShader(*target_shader);
- }
- }
- else if (!params.mFullbright)
- {
- target_shader = simple_shader;
- }
- else
- {
- target_shader = fullbright_shader;
- }
-
- if (params.mAvatar != nullptr)
- {
- target_shader = target_shader->mRiggedVariant;
- }
-
- 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).
- target_shader->bind();
- }
+ 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).
+ gPipeline.bindDeferredShader(*target_shader);
+ }
- LLVector4 spec_color(1, 1, 1, 1);
- F32 env_intensity = 0.0f;
- F32 brightness = 1.0f;
+ 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 (mat && deferred_render)
- {
- spec_color = params.mSpecColor;
- env_intensity = params.mEnvIntensity;
- brightness = params.mFullbright ? 1.f : 0.f;
- }
+ // We have a material. Supply the appropriate data here.
+ if (mat && deferred_render)
+ {
+ spec_color = params.mSpecColor;
+ env_intensity = params.mEnvIntensity;
+ brightness = params.mFullbright ? 1.f : 0.f;
+ }
- if (current_shader)
- {
- current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, spec_color.mV[0], spec_color.mV[1], spec_color.mV[2], spec_color.mV[3]);
- current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env_intensity);
- current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, brightness);
+ if (current_shader)
+ {
+ current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, spec_color.mV[0], spec_color.mV[1], spec_color.mV[2], spec_color.mV[3]);
+ current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env_intensity);
+ current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, brightness);
+ }
}
if (params.mGroup)
@@ -725,7 +797,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
bool tex_setup = TexSetup(&params, (mat != nullptr));
{
- LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+ //LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);