summaryrefslogtreecommitdiff
path: root/indra/newview/lldrawpoolalpha.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/lldrawpoolalpha.cpp')
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpoolalpha.cpp523
1 files changed, 351 insertions, 172 deletions
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index a2428d2de0..84ead0bdde 100644..100755
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -54,7 +54,7 @@ static BOOL deferred_render = FALSE;
LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) :
LLRenderPass(type), current_shader(NULL), target_shader(NULL),
- simple_shader(NULL), fullbright_shader(NULL),
+ simple_shader(NULL), fullbright_shader(NULL), emissive_shader(NULL),
mColorSFactor(LLRender::BF_UNDEF), mColorDFactor(LLRender::BF_UNDEF),
mAlphaSFactor(LLRender::BF_UNDEF), mAlphaDFactor(LLRender::BF_UNDEF)
{
@@ -71,48 +71,85 @@ void LLDrawPoolAlpha::prerender()
mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
-S32 LLDrawPoolAlpha::getNumDeferredPasses()
-{
- return 1;
-}
-
-void LLDrawPoolAlpha::beginDeferredPass(S32 pass)
-{
-
+S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
+{
+ if (LLPipeline::sImpostorRender)
+ { //skip depth buffer filling pass when rendering impostors
+ return 1;
+ }
+ else if (gSavedSettings.getBOOL("RenderDepthOfField"))
+ {
+ return 2;
+ }
+ else
+ {
+ return 1;
+ }
}
-void LLDrawPoolAlpha::endDeferredPass(S32 pass)
-{
-
-}
+void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
+{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA);
-void LLDrawPoolAlpha::renderDeferred(S32 pass)
-{
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f);
+ if (pass == 0)
{
- LLFastTimer t(FTM_RENDER_GRASS);
- gDeferredTreeProgram.bind();
- LLGLEnable test(GL_ALPHA_TEST);
- //render alpha masked objects
- LLRenderPass::renderTexture(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask());
- gDeferredTreeProgram.unbind();
- }
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
-}
+ 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->bind();
+ fullbright_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ fullbright_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+ fullbright_shader->unbind();
-S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
-{
- return 1;
-}
+ //prime simple shader (loads shadow relevant uniforms)
+ gPipeline.bindDeferredShader(*simple_shader);
-void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
-{
- LLFastTimer t(FTM_RENDER_ALPHA);
+ simple_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+ }
+ else if (!LLPipeline::sImpostorRender)
+ {
+ //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();
+ simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
+ gObjectFullbrightAlphaMaskProgram.bind();
+ gObjectFullbrightAlphaMaskProgram.setMinimumAlpha(0.33f);
+ }
+
+
+ if (LLPipeline::sRenderDeferred)
+ {
+ emissive_shader = &gDeferredEmissiveProgram;
+ }
+ else
+ {
+ if (LLPipeline::sUnderWaterRender)
+ {
+ emissive_shader = &gObjectEmissiveWaterProgram;
+ }
+ else
+ {
+ emissive_shader = &gObjectEmissiveProgram;
+ }
+ }
- simple_shader = &gDeferredAlphaProgram;
- fullbright_shader = &gDeferredFullbrightProgram;
-
deferred_render = TRUE;
if (mVertexShaderLevel > 0)
{
@@ -124,6 +161,13 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)
{
+ if (pass == 1 && !LLPipeline::sImpostorRender)
+ {
+ gPipeline.mDeferredDepth.flush();
+ gPipeline.mScreen.bindTarget();
+ gObjectFullbrightAlphaMaskProgram.unbind();
+ }
+
deferred_render = FALSE;
endRenderPass(pass);
}
@@ -135,17 +179,25 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
void LLDrawPoolAlpha::beginRenderPass(S32 pass)
{
- LLFastTimer t(FTM_RENDER_ALPHA);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA);
- if (LLPipeline::sUnderWaterRender)
+ 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;
}
if (mVertexShaderLevel > 0)
@@ -159,7 +211,7 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass)
void LLDrawPoolAlpha::endRenderPass( S32 pass )
{
- LLFastTimer t(FTM_RENDER_ALPHA);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA);
LLRenderPass::endRenderPass(pass);
if(gPipeline.canUseWindLightShaders())
@@ -170,80 +222,121 @@ void LLDrawPoolAlpha::endRenderPass( S32 pass )
void LLDrawPoolAlpha::render(S32 pass)
{
- LLFastTimer t(FTM_RENDER_ALPHA);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA);
LLGLSPipelineAlpha gls_pipeline_alpha;
- gGL.setColorMask(true, true);
+ if (deferred_render && pass == 1)
+ { //depth only
+ gGL.setColorMask(false, false);
+ }
+ else
+ {
+ gGL.setColorMask(true, true);
+ }
+
+ bool write_depth = LLDrawPoolWater::sSkipScreenCopy
+ || (deferred_render && pass == 1)
+ // we want depth written so that rendered alpha will
+ // contribute to the alpha mask used for impostors
+ || LLPipeline::sImpostorRenderAlphaDepthPass;
+
+ LLGLDepthTest depth(GL_TRUE, write_depth ? GL_TRUE : GL_FALSE);
- if (LLPipeline::sAutoMaskAlphaNonDeferred && !deferred_render)
+ if (deferred_render && pass == 1)
+ {
+ gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
+ }
+ else
{
- mColorSFactor = LLRender::BF_ONE; // }
- mColorDFactor = LLRender::BF_ZERO; // } these are like disabling blend on the color channels, but we're still blending on the alpha channel so that we can suppress glow
- mAlphaSFactor = LLRender::BF_ZERO;
- mAlphaDFactor = LLRender::BF_ZERO; // block (zero-out) glow where the alpha test succeeds
+ mColorSFactor = LLRender::BF_SOURCE_ALPHA; // } regular alpha blend
+ mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
+ mAlphaSFactor = LLRender::BF_ZERO; // } glow suppression
+ mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f);
if (mVertexShaderLevel > 0)
{
- if (!LLPipeline::sRenderDeferred)
+ if (LLPipeline::sImpostorRender)
+ {
+ fullbright_shader->bind();
+ fullbright_shader->setMinimumAlpha(0.5f);
+ simple_shader->bind();
+ simple_shader->setMinimumAlpha(0.5f);
+ }
+ else
{
+ fullbright_shader->bind();
+ fullbright_shader->setMinimumAlpha(0.f);
simple_shader->bind();
- pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask());
+ simple_shader->setMinimumAlpha(0.f);
}
- fullbright_shader->bind();
- pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask());
- LLGLSLShader::bindNoShader();
}
else
{
- gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
- pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask());
- gPipeline.enableLightsDynamic();
- pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask());
+ if (LLPipeline::sImpostorRender)
+ {
+ gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); //OK
+ }
+ else
+ {
+ gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
+ }
}
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}
- LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ? GL_TRUE : GL_FALSE);
-
- mColorSFactor = LLRender::BF_SOURCE_ALPHA; // } regular alpha blend
- mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
- mAlphaSFactor = LLRender::BF_ZERO; // } glow suppression
- mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
- gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
-
- renderAlpha(getVertexDataMask());
+ if (mVertexShaderLevel > 0)
+ {
+ renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, pass);
+ }
+ else
+ {
+ renderAlpha(getVertexDataMask(), pass);
+ }
gGL.setColorMask(true, false);
- if (deferred_render && current_shader != NULL)
+ if (deferred_render && pass == 1)
{
- gPipeline.unbindDeferredShader(*current_shader);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
if (sShowDebugAlpha)
{
- if(gPipeline.canUseWindLightShaders())
+ BOOL shaders = gPipeline.canUseVertexShaders();
+ if(shaders)
+ {
+ gHighlightProgram.bind();
+ }
+ else
{
- LLGLSLShader::bindNoShader();
+ gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
}
- gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
- glColor4f(1,0,0,1);
+
+ gGL.diffuseColor4f(1,0,0,1);
+
LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f*1024.f);
gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep, TRUE) ;
renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_TEXCOORD0);
+
+ pushBatches(LLRenderPass::PASS_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ pushBatches(LLRenderPass::PASS_ALPHA_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+
+ if(shaders)
+ {
+ gHighlightProgram.unbind();
+ }
}
}
void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
{
- for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
+ for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
{
LLSpatialGroup* group = *i;
- if (group->mSpatialPartition->mRenderByGroup &&
+ if (group->getSpatialPartition()->mRenderByGroup &&
!group->isDead())
{
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
@@ -270,42 +363,35 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
}
}
-void LLDrawPoolAlpha::renderAlpha(U32 mask)
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_GROUP_LOOP("Alpha Group");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_PUSH("Alpha Push Verts");
+
+void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
{
BOOL initialized_lighting = FALSE;
BOOL light_enabled = TRUE;
- S32 diffuse_channel = 0;
-
- //BOOL is_particle = FALSE;
- BOOL use_shaders = (LLPipeline::sUnderWaterRender && gPipeline.canUseVertexShaders())
- || gPipeline.canUseWindLightShadersOnObjects();
- // check to see if it's a particle and if it's "close"
- {
- if (LLPipeline::sImpostorRender)
- {
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
- }
- else
- {
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
- }
- }
-
- for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
+ BOOL use_shaders = gPipeline.canUseVertexShaders();
+
+ for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
{
LLSpatialGroup* group = *i;
llassert(group);
- llassert(group->mSpatialPartition);
+ llassert(group->getSpatialPartition());
- if (group->mSpatialPartition->mRenderByGroup &&
+ if (group->getSpatialPartition()->mRenderByGroup &&
!group->isDead())
{
- bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow.
- // All particle systems seem to come off the wire with texture entries which claim that they glow. This is probably a bug in the data. Suppress.
- group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_PARTICLE &&
- group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_CLOUD &&
- group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE;
+ bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE
+ || group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE;
+
+ bool draw_glow_for_this_partition = mVertexShaderLevel > 0; // no shaders = no glow.
+
+
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_GROUP_LOOP);
+
+ bool disable_cull = is_particle_or_hud_particle;
+ LLGLDisable cull(disable_cull ? GL_CULL_FACE : 0);
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
@@ -313,139 +399,232 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
{
LLDrawInfo& params = **k;
- LLRenderPass::applyModelMatrix(params);
+ if ((params.mVertexBuffer->getTypeMask() & mask) != mask)
+ { //FIXME!
+ LL_WARNS() << "Missing required components, skipping render batch." << LL_ENDL;
+ continue;
+ }
+ // 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)
{
- if (params.mFullbright)
+ LLFace* face = params.mFace;
+ if(face)
{
- // Turn off lighting if it hasn't already been so.
- if (light_enabled || !initialized_lighting)
+ const LLTextureEntry* tep = face->getTextureEntry();
+ if(tep)
{
- initialized_lighting = TRUE;
- if (use_shaders)
- {
- target_shader = fullbright_shader;
- }
- else
- {
- gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
- }
- light_enabled = FALSE;
+ if(tep->getColor().mV[3] < 0.1f)
+ continue;
}
}
- // Turn on lighting if it isn't already.
- else if (!light_enabled || !initialized_lighting)
+ }
+
+ LLRenderPass::applyModelMatrix(params);
+
+ LLMaterial* mat = NULL;
+
+ 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 = simple_shader;
+ target_shader = fullbright_shader;
}
else
{
- gPipeline.enableLightsDynamic();
+ gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
}
- light_enabled = TRUE;
+ 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;
+ }
+
+ if (deferred_render && mat)
+ {
+ U32 mask = params.mShaderMask;
+
+ llassert(mask < LLMaterial::SHADER_COUNT);
+ target_shader = &(gDeferredMaterialProgram[mask]);
- // If we need shaders, and we're not ALREADY using the proper shader, then bind it
- // (this way we won't rebind shaders unnecessarily).
- if(use_shaders && (current_shader != target_shader))
+ if (LLPipeline::sUnderWaterRender)
{
- llassert(target_shader != NULL);
- if (deferred_render && current_shader != NULL)
- {
- gPipeline.unbindDeferredShader(*current_shader);
- diffuse_channel = 0;
- }
- current_shader = target_shader;
- if (deferred_render)
- {
- gPipeline.bindDeferredShader(*current_shader);
- diffuse_channel = current_shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- }
- else
- {
- current_shader->bind();
- }
+ target_shader = &(gDeferredMaterialWaterProgram[mask]);
}
- else if (!use_shaders && current_shader != NULL)
+
+ if (current_shader != target_shader)
{
- if (deferred_render)
- {
- gPipeline.unbindDeferredShader(*current_shader);
- diffuse_channel = 0;
- }
- LLGLSLShader::bindNoShader();
- current_shader = NULL;
+ 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;
+ }
- if (params.mGroup)
+ if (use_shaders && mat)
+ {
+ // We have a material. Supply the appropriate data here.
+ if (LLPipeline::sRenderDeferred)
{
- params.mGroup->rebuildMesh();
+ 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);
+ }
+
+ if (params.mGroup)
+ {
+ params.mGroup->rebuildMesh();
+ }
+
+ bool tex_setup = false;
+
+ 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())
{
- gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get());
- if(params.mTexture.notNull())
+ params.mTexture->addTextureStats(params.mVSize);
+ if (use_shaders && mat)
{
- params.mTexture->addTextureStats(params.mVSize);
+ 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();
- glMatrixMode(GL_TEXTURE);
- glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
gPipeline.mTextureMatrixOps++;
}
}
+ else
+ {
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ }
}
- params.mVertexBuffer->setBuffer(mask);
+ {
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_PUSH);
+ 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->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 (draw_glow_for_this_partition &&
- params.mGlowColor.mV[3] > 0)
+ if (current_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)
- // glow doesn't use vertex colors from the mesh data
- params.mVertexBuffer->setBuffer(mask & ~LLVertexBuffer::MAP_COLOR);
- glColor4ubv(params.mGlowColor.mV);
-
+ emissive_shader->bind();
+
+ params.mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);
+
// do the actual drawing, again
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
// restore our alpha blend mode
gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
+
+ current_shader->bind();
}
- if (params.mTextureMatrix && params.mTexture.notNull())
+ if (tex_setup)
{
gGL.getTexUnit(0)->activate();
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
}
}
}
}
- if (deferred_render && current_shader != NULL)
- {
- gPipeline.unbindDeferredShader(*current_shader);
- LLVertexBuffer::unbind();
- LLGLState::checkStates();
- LLGLState::checkTextureChannels();
- LLGLState::checkClientArrays();
- }
-
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+ LLVertexBuffer::unbind();
+
if (!light_enabled)
{
gPipeline.enableLightsDynamic();