summaryrefslogtreecommitdiff
path: root/indra/newview/lldrawpoolalpha.cpp
diff options
context:
space:
mode:
authorGraham Linden <graham@lindenlab.com>2019-03-04 08:04:18 -0800
committerGraham Linden <graham@lindenlab.com>2019-03-04 08:04:18 -0800
commit45a541d2d5ccff4279441c715d3f80890e71beb9 (patch)
treef16c1cf45d8bd5e2d4d021ed7b01d729f545d688 /indra/newview/lldrawpoolalpha.cpp
parent4c3050a3953153aa8753fc10706ad2ef464f3e3d (diff)
SL-10566
Disable pre-cull of water causing refraction/reflection map generation more than is necessary. Re-org alpha draws to limit state changes based on render type.
Diffstat (limited to 'indra/newview/lldrawpoolalpha.cpp')
-rw-r--r--indra/newview/lldrawpoolalpha.cpp621
1 files changed, 258 insertions, 363 deletions
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index be57e5afde..84f94d4497 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -64,6 +64,7 @@ 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");
LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) :
@@ -103,53 +104,22 @@ S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED);
- if (LLPipeline::sRenderDeferred)
- {
- emissive_shader = &gDeferredEmissiveProgram;
- }
- else
- {
- if (LLPipeline::sUnderWaterRender)
- {
- emissive_shader = &gObjectEmissiveWaterProgram;
- }
- else
- {
- emissive_shader = &gObjectEmissiveProgram;
- }
- }
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+
+ emissive_shader = (LLPipeline::sRenderDeferred) ? &gDeferredEmissiveProgram :
+ (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
emissive_shader->bind();
- if (LLPipeline::sRenderingHUDs)
- {
- emissive_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- emissive_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
+ emissive_shader->uniform1i(LLShaderMgr::NO_ATMO, (LLPipeline::sRenderingHUDs) ? 1 : 0);
+ emissive_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ emissive_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
if (pass == 0)
{
- if (LLPipeline::sImpostorRender)
- {
- simple_shader = &gDeferredAlphaImpostorProgram;
- fullbright_shader = &gDeferredFullbrightProgram;
- }
- else if (LLPipeline::sUnderWaterRender)
- {
- simple_shader = &gDeferredAlphaWaterProgram;
- fullbright_shader = &gDeferredFullbrightWaterProgram;
- }
- else
- {
- simple_shader = &gDeferredAlphaProgram;
- fullbright_shader = &gDeferredFullbrightProgram;
- }
-
- F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+ fullbright_shader = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightProgram :
+ (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightProgram;
fullbright_shader->bind();
fullbright_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
@@ -157,10 +127,14 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
fullbright_shader->unbind();
+ simple_shader = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
+ (LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram;
+
//prime simple shader (loads shadow relevant uniforms)
gPipeline.bindDeferredShader(*simple_shader);
simple_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
}
else if (!LLPipeline::sImpostorRender)
{
@@ -208,31 +182,47 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass)
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_SETUP);
- if (LLPipeline::sImpostorRender)
- {
- simple_shader = &gObjectSimpleImpostorProgram;
- fullbright_shader = &gObjectFullbrightProgram;
- emissive_shader = &gObjectEmissiveProgram;
- }
- else if (LLPipeline::sUnderWaterRender)
- {
- simple_shader = &gObjectSimpleWaterProgram;
- fullbright_shader = &gObjectFullbrightWaterProgram;
- emissive_shader = &gObjectEmissiveWaterProgram;
- }
- else
- {
- simple_shader = &gObjectSimpleProgram;
- fullbright_shader = &gObjectFullbrightProgram;
- emissive_shader = &gObjectEmissiveProgram;
- }
+ simple_shader = (LLPipeline::sImpostorRender) ? &gObjectSimpleImpostorProgram :
+ (LLPipeline::sUnderWaterRender) ? &gObjectSimpleWaterProgram : &gObjectSimpleProgram;
- if (mShaderLevel > 0)
+ fullbright_shader = (LLPipeline::sImpostorRender) ? &gObjectFullbrightProgram :
+ (LLPipeline::sUnderWaterRender) ? &gObjectFullbrightWaterProgram : &gObjectFullbrightProgram;
+
+ emissive_shader = (LLPipeline::sImpostorRender) ? &gObjectEmissiveProgram :
+ (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
+
+ if (LLPipeline::sImpostorRender)
{
- // Start out with no shaders.
- current_shader = target_shader = NULL;
- LLGLSLShader::bindNoShader();
+ if (mShaderLevel > 0)
+ {
+ fullbright_shader->bind();
+ fullbright_shader->setMinimumAlpha(0.5f);
+ fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
+ simple_shader->bind();
+ simple_shader->setMinimumAlpha(0.5f);
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
+ }
+ else
+ {
+ gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); //OK
+ }
}
+ else
+ {
+ if (mShaderLevel > 0)
+ {
+ fullbright_shader->bind();
+ fullbright_shader->setMinimumAlpha(0.f);
+ fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
+ simple_shader->bind();
+ simple_shader->setMinimumAlpha(0.f);
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
+ }
+ else
+ {
+ gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
+ }
+ }
gPipeline.enableLightsDynamic();
}
@@ -281,67 +271,6 @@ void LLDrawPoolAlpha::render(S32 pass)
mAlphaSFactor = LLRender::BF_ZERO; // } glow suppression
mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
-
- if (mShaderLevel > 0)
- {
- if (LLPipeline::sImpostorRender)
- {
- fullbright_shader->bind();
- fullbright_shader->setMinimumAlpha(0.5f);
- if (LLPipeline::sRenderingHUDs)
- {
- fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- simple_shader->bind();
- simple_shader->setMinimumAlpha(0.5f);
- if (LLPipeline::sRenderingHUDs)
- {
- simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- }
- else
- {
- fullbright_shader->bind();
- fullbright_shader->setMinimumAlpha(0.f);
- if (LLPipeline::sRenderingHUDs)
- {
- fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- simple_shader->bind();
- simple_shader->setMinimumAlpha(0.f);
- if (LLPipeline::sRenderingHUDs)
- {
- simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- }
- }
- else
- {
- if (LLPipeline::sImpostorRender)
- {
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); //OK
- }
- else
- {
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
- }
- }
}
if (mShaderLevel > 0)
@@ -428,282 +357,248 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
}
}
-void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
+inline bool IsFullbright(LLDrawInfo& params)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA);
+ return params.mFullbright;
+}
- BOOL initialized_lighting = FALSE;
- BOOL light_enabled = TRUE;
-
- BOOL use_shaders = gPipeline.canUseVertexShaders();
-
- for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
+inline bool IsMaterial(LLDrawInfo& params)
+{
+ return params.mMaterial != nullptr;
+}
+
+inline bool IsEmissive(LLDrawInfo& params)
+{
+ return params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE);
+}
+
+inline void Draw(LLDrawInfo* draw, U32 mask)
+{
+ draw->mVertexBuffer->setBuffer(mask);
+ LLRenderPass::applyModelMatrix(*draw);
+ draw->mVertexBuffer->drawRange(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
+ gPipeline.addTrianglesDrawn(draw->mCount, draw->mDrawMode);
+}
+
+inline bool TexSetup(LLDrawInfo* draw)
+{
+ bool tex_setup = false;
+
+ if (draw->mTextureMatrix)
{
- LLSpatialGroup* group = *i;
- llassert(group);
- if (!group)
- {
- continue;
- }
- LLSpatialPartition* partition = group->getSpatialPartition();
- llassert(partition);
- if (!partition)
+ tex_setup = true;
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadMatrix((GLfloat*) draw->mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+ }
+
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_TEX_BINDS);
+ for (U32 i = 0; i < draw->mTextureList.size(); ++i)
+ {
+ if (draw->mTextureList[i].notNull())
{
- continue;
+ gGL.getTexUnit(i)->bind(draw->mTextureList[i], TRUE);
}
+ }
- if (partition->mRenderByGroup &&
- !group->isDead())
- {
- bool is_particle_or_hud_particle = partition->mPartitionType == LLViewerRegion::PARTITION_PARTICLE
- || partition->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE;
-
- bool draw_glow_for_this_partition = mShaderLevel > 0; // no shaders = no glow.
+ return tex_setup;
+}
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_GROUP_LOOP);
+inline void RestoreTexSetup(bool tex_setup)
+{
+ if (tex_setup)
+ {
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
+}
- bool disable_cull = is_particle_or_hud_particle;
- LLGLDisable cull(disable_cull ? GL_CULL_FACE : 0);
+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);
+
+ for (LLDrawInfo* draw : simples)
+ {
+ bool tex_setup = TexSetup(draw);
+ Draw(draw, mask);
+ RestoreTexSetup(tex_setup);
+ }
+ simple_shader->unbind();
+}
- LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
+void LLDrawPoolAlpha::renderFullbrights(U32 mask, std::vector<LLDrawInfo*>& fullbrights)
+{
+ gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
+ fullbright_shader->bind();
+ fullbright_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.0f);
+ for (LLDrawInfo* draw : fullbrights)
+ {
+ bool tex_setup = TexSetup(draw);
+ Draw(draw, mask & ~(LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2));
+ RestoreTexSetup(tex_setup);
+ }
+ fullbright_shader->unbind();
+}
- for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
- {
- LLDrawInfo& params = **k;
+void LLDrawPoolAlpha::renderMaterials(U32 mask, std::vector<LLDrawInfo*>& materials)
+{
+ LLGLSLShader::bindNoShader();
+ current_shader = NULL;
- if ((params.mVertexBuffer->getTypeMask() & mask) != mask)
- { //FIXME!
- LL_WARNS_ONCE() << "Missing required components, expected mask: " << mask
- << " present: " << (params.mVertexBuffer->getTypeMask() & mask)
- << ". Skipping render batch." << LL_ENDL;
- continue;
- }
+ for (LLDrawInfo* draw : materials)
+ {
+ U32 mask = draw->mShaderMask;
- // Fix for bug - NORSPEC-271
- // If the face is more than 90% transparent, then don't update the Depth buffer for Dof
- // We don't want the nearly invisible objects to cause of DoF effects
- if(pass == 1 && !LLPipeline::sImpostorRender)
- {
- LLFace* face = params.mFace;
- if(face)
- {
- const LLTextureEntry* tep = face->getTextureEntry();
- if(tep)
- {
- if(tep->getColor().mV[3] < 0.1f)
- continue;
- }
- }
- }
+ llassert(mask < LLMaterial::SHADER_COUNT);
+ target_shader = (LLPipeline::sUnderWaterRender) ? &(gDeferredMaterialWaterProgram[mask]) : &(gDeferredMaterialProgram[mask]);
- LLRenderPass::applyModelMatrix(params);
+ 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);
+ if (!draw->mTexture.isNull())
+ {
+ current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, draw->mTexture);
+ }
- LLMaterial* mat = NULL;
+ 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);
- 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;
- if (use_shaders)
- {
- target_shader = fullbright_shader;
- }
- else
- {
- gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
- }
- light_enabled = FALSE;
- }
- }
- // Turn on lighting if it isn't already.
- else if (!light_enabled || !initialized_lighting)
- {
- initialized_lighting = TRUE;
- if (use_shaders)
- {
- target_shader = simple_shader;
- }
- else
- {
- gPipeline.enableLightsDynamic();
- }
- light_enabled = TRUE;
- }
+ {
+ 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);
+ }
+ }
- if (deferred_render && mat)
- {
- U32 mask = params.mShaderMask;
+ Draw(draw, mask);
+ RestoreTexSetup(tex_setup);
+ }
+}
- llassert(mask < LLMaterial::SHADER_COUNT);
- target_shader = &(gDeferredMaterialProgram[mask]);
+void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives)
+{
+ emissive_shader->bind();
- if (LLPipeline::sUnderWaterRender)
- {
- target_shader = &(gDeferredMaterialWaterProgram[mask]);
- }
+ // 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);
- if (current_shader != target_shader)
- {
- gPipeline.bindDeferredShader(*target_shader);
- }
- }
- else if (!params.mFullbright)
- {
- target_shader = simple_shader;
- }
- else
- {
- target_shader = fullbright_shader;
- }
-
- if(use_shaders && (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).
- current_shader = target_shader;
- current_shader->bind();
- }
- else if (!use_shaders && current_shader != NULL)
- {
- LLGLSLShader::bindNoShader();
- current_shader = NULL;
- }
+ for (LLDrawInfo* draw : emissives)
+ {
+ bool tex_setup = TexSetup(draw);
+ Draw(draw, (mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);
+ RestoreTexSetup(tex_setup);
+ }
- if (use_shaders && mat)
- {
- // We have a material. Supply the appropriate data here.
- if (LLPipeline::sRenderDeferred)
- {
- current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);
- current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity);
- current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f);
-
- if (params.mNormalMap)
- {
- params.mNormalMap->addTextureStats(params.mVSize);
- current_shader->bindTexture(LLShaderMgr::BUMP_MAP, params.mNormalMap);
- }
-
- if (params.mSpecularMap)
- {
- params.mSpecularMap->addTextureStats(params.mVSize);
- current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap);
- }
- }
-
- } else if (LLPipeline::sRenderDeferred && current_shader && (current_shader == simple_shader))
- {
- current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);
- current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f);
- LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(params.mVSize);
- current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
- LLViewerFetchedTexture::sWhiteImagep->addTextureStats(params.mVSize);
- current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
- }
+ // restore our alpha blend mode
+ gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
- if (params.mGroup)
- {
- params.mGroup->rebuildMesh();
- }
+ emissive_shader->unbind();
+}
- bool tex_setup = false;
+void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
+{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA);
- if (use_shaders && params.mTextureList.size() > 1)
- {
- for (U32 i = 0; i < params.mTextureList.size(); ++i)
- {
- if (params.mTextureList[i].notNull())
- {
- gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE);
- }
- }
- }
- else
- { //not batching textures or batch has only 1 texture -- might need a texture matrix
- if (params.mTexture.notNull())
- {
- params.mTexture->addTextureStats(params.mVSize);
- if (use_shaders && mat)
- {
- current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, params.mTexture);
- }
- else
- {
- gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;
- }
-
- if (params.mTextureMatrix)
- {
- tex_setup = true;
- gGL.getTexUnit(0)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
- gPipeline.mTextureMatrixOps++;
- }
- }
- else
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- }
- }
+ std::vector<LLDrawInfo*> simples_3d;
+ std::vector<LLDrawInfo*> fullbrights_3d;
+ std::vector<LLDrawInfo*> materials_3d;
+ std::vector<LLDrawInfo*> emissives_3d;
+ std::vector<LLDrawInfo*> simples_hud;
+ std::vector<LLDrawInfo*> fullbrights_hud;
+ std::vector<LLDrawInfo*> materials_hud;
+ std::vector<LLDrawInfo*> emissives_hud;
- {
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_PUSH);
+ for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
+ {
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_GROUP_LOOP);
- LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+ LLSpatialGroup* group = *i;
+ llassert(group);
- 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));
+ LLSpatialPartition* partition = group->getSpatialPartition();
+ llassert(partition);
- params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
- gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
- }
-
- // If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha.
- if (current_shader &&
- emissive_shader &&
- draw_glow_for_this_partition &&
- params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE))
- {
- // install glow-accumulating blend mode
- gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color
- LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow)
+ if (group->getSpatialPartition()->mRenderByGroup && !group->isDead())
+ {
+ bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE
+ || group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE;
- emissive_shader->bind();
- params.mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);
+ std::vector<LLDrawInfo*>* fullbrights = is_particle_or_hud_particle ? &fullbrights_hud : &fullbrights_3d;
+ std::vector<LLDrawInfo*>* materials = is_particle_or_hud_particle ? &materials_hud : &materials_3d;
+ std::vector<LLDrawInfo*>* simples = is_particle_or_hud_particle ? &simples_hud : &simples_3d;
+ std::vector<LLDrawInfo*>* emissives = is_particle_or_hud_particle ? &emissives_hud : &emissives_3d;
- // do the actual drawing, again
- params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
- gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
+ LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
- // restore our alpha blend mode
- gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
+ for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
+ {
+ LLDrawInfo& params = **k;
- current_shader->bind();
- }
-
- if (tex_setup)
+ if (params.mGroup)
{
- gGL.getTexUnit(0)->activate();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MESH_REBUILD);
+ params.mGroup->rebuildMesh();
}
- }
- }
+
+ (IsMaterial(params) ? materials :
+ IsFullbright(params) ? fullbrights :
+ simples)->push_back(&params);
+
+ if (IsEmissive(params))
+ {
+ emissives->push_back(&params);
+ }
+ }
+ }
}
+ renderSimples(mask, simples_3d);
+ renderFullbrights(mask, fullbrights_3d);
+ renderMaterials(mask, materials_3d);
+ renderEmissives(mask, emissives_3d);
+
+ LLGLDisable cull(GL_CULL_FACE);
+
+ renderSimples(mask, simples_hud);
+ renderFullbrights(mask, fullbrights_hud);
+ renderMaterials(mask, materials_hud);
+ renderEmissives(mask, emissives_hud);
+
+ LLGLSLShader::bindNoShader();
+ current_shader = NULL;
+
gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
LLVertexBuffer::unbind();
- if (!light_enabled)
- {
- gPipeline.enableLightsDynamic();
- }
+ gPipeline.enableLightsDynamic();
}