示例#1
0
void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
{
	for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
	{
		LLSpatialGroup* group = *i;
		if (group->mSpatialPartition->mRenderByGroup &&
			!group->isDead())
		{
			LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];	

			for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)	
			{
				LLDrawInfo& params = **k;
				
				if (params.mParticle)
				{
					continue;
				}

				LLRenderPass::applyModelMatrix(params);
				if (params.mGroup)
				{
					params.mGroup->rebuildMesh();
				}
				params.mVertexBuffer->setBuffer(mask);
				params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
				gPipeline.addTrianglesDrawn(params.mCount/3);
			}
		}
	}
}
示例#2
0
void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask, std::vector<LLSpatialGroup*>& groups)
{
#if !LL_RELEASE_FOR_DOWNLOAD
	LLGLState::checkClientArrays(mask);
#endif

	LLSpatialBridge* last_bridge = NULL;
	LLSpatialPartition* last_part = NULL;
	glPushMatrix();
	
	for (std::vector<LLSpatialGroup*>::iterator i = groups.begin(); i != groups.end(); ++i)
	{
		LLSpatialGroup* group = *i;
		if (group->mSpatialPartition->mRenderByGroup &&
			!group->isDead())
		{
			LLSpatialPartition* part = group->mSpatialPartition;
			if (part != last_part)
			{
				LLSpatialBridge* bridge = part->asBridge();
				if (bridge != last_bridge)
				{
					glPopMatrix();
					glPushMatrix();
					if (bridge)
					{
						glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix);
					}
					last_bridge = bridge;
				}
				
				last_part = part;
			}

			LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];	

			for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)	
			{
				LLDrawInfo& params = **k;
				
				if (params.mParticle)
				{
					continue;
				}
				params.mVertexBuffer->setBuffer(mask);
				U32* indices_pointer = (U32*) params.mVertexBuffer->getIndicesPointer();
				glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd, params.mCount,
									GL_UNSIGNED_INT, indices_pointer+params.mOffset);
				
				addIndicesDrawn(params.mCount);
			}
		}
	}
	glPopMatrix();
}
void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
{
	for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
	{
		LLSpatialGroup* group = *i;
		if (group->mSpatialPartition->mRenderByGroup &&
			!group->isDead())
		{
			LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];	

			for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)	
			{
				LLDrawInfo& params = **k;
				
				if (params.mParticle)
				{
					continue;
				}

				LLRenderPass::applyModelMatrix(params);
				if (params.mGroup)
				{
					params.mGroup->rebuildMesh();
				}
                // KL Batching Textures, taken from renderAlpha and fiddled to enable highlighting transparent to work
				if (params.mTextureList.size() > 1)
				{
				    gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); // not sure on this
                    glColor4f(1,0,0,1);
                    // KL someone set us up the bomb... make your peace					 
					for (U32 i = 0; i < params.mTextureList.size(); ++i)
					{
						if (params.mTextureList[i].notNull())
						{
							gGL.getTexUnit(i)->bind(LLViewerFetchedTexture::sSmokeImagep, TRUE);
						}
					}
				}
			
				params.mVertexBuffer->setBuffer(mask);
				params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
				gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
			}
		}
	}
}
示例#4
0
void LLDrawPoolAlpha::renderAlpha(U32 mask, std::vector<LLSpatialGroup*>& groups)
{
#if !LL_RELEASE_FOR_DOWNLOAD
	LLGLState::checkClientArrays(mask);
#endif

	LLSpatialBridge* last_bridge = NULL;
	LLSpatialPartition* last_part = NULL;
	glPushMatrix();
	LLGLDepthTest depth(GL_TRUE, GL_FALSE);

	for (std::vector<LLSpatialGroup*>::iterator i = groups.begin(); i != groups.end(); ++i)
	{
		LLSpatialGroup* group = *i;
		if (group->mSpatialPartition->mRenderByGroup &&
			!group->isDead())
		{
			LLSpatialPartition* part = group->mSpatialPartition;
			if (part != last_part)
			{
				LLSpatialBridge* bridge = part->asBridge();
				if (bridge != last_bridge)
				{
					glPopMatrix();
					glPushMatrix();
					if (bridge)
					{
						glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix);
					}
					last_bridge = bridge;
				}

//				if (!last_part || part->mDepthMask != last_part->mDepthMask)
//				{
//					glDepthMask(part->mDepthMask);
//				}
				last_part = part;
			}

			renderGroupAlpha(group,LLRenderPass::PASS_ALPHA,mask,TRUE);
		}
	}
	
	glPopMatrix();
}
示例#5
0
void LLDrawPoolAlpha::renderAlpha(U32 mask)
{
	BOOL initialized_lighting = FALSE;
	BOOL light_enabled = TRUE;
	//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)
	{
		LLSpatialGroup* group = *i;
		llassert(group);
		llassert(group->mSpatialPartition);

		if (group->mSpatialPartition->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;

			LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];

			for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)	
			{
				LLDrawInfo& params = **k;

				LLRenderPass::applyModelMatrix(params);

				{
					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;
					}

					// 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))
					{
						llassert(target_shader != NULL);
						if (deferred_render && current_shader != NULL)
						{
							gPipeline.unbindDeferredShader(*current_shader);
						}
						current_shader = target_shader;
						if (deferred_render)
						{
							gPipeline.bindDeferredShader(*current_shader);
						}
						else
						{
							current_shader->bind();
						}
					}
					else if (!use_shaders && current_shader != NULL)
					{
					
						if (deferred_render)
						{
							gPipeline.unbindDeferredShader(*current_shader);
						}
						LLGLSLShader::bindNoShader();
						current_shader = NULL;
					}

					if (params.mGroup)
					{
						params.mGroup->rebuildMesh();
					}

					
					if (params.mTexture.notNull())
					{
						gGL.getTexUnit(0)->bind(params.mTexture.get());
						if(params.mTexture.notNull())
						{
							params.mTexture->addTextureStats(params.mVSize);
						}
						if (params.mTextureMatrix)
						{
							gGL.getTexUnit(0)->activate();
							glMatrixMode(GL_TEXTURE);
							glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);
							gPipeline.mTextureMatrixOps++;
						}
					}
				}
				params.mVertexBuffer->setBuffer(mask);
				params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
				gPipeline.addTrianglesDrawn(params.mCount/3);
				
				// 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)
				{
					// 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);

					// do the actual drawing, again
					params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
					gPipeline.addTrianglesDrawn(params.mCount/3);

					// restore our alpha blend mode
					gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
				}
			
				if (params.mTextureMatrix && params.mTexture.notNull())
				{
					gGL.getTexUnit(0)->activate();
					glLoadIdentity();
					glMatrixMode(GL_MODELVIEW);
				}
			}
		}
	}

	if (deferred_render && current_shader != NULL)
	{
		gPipeline.unbindDeferredShader(*current_shader);
		LLVertexBuffer::unbind();	
		LLGLState::checkStates();
		LLGLState::checkTextureChannels();
		LLGLState::checkClientArrays();
	}
	
	if (!light_enabled)
	{
		gPipeline.enableLightsDynamic();
	}
}
void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
{
	BOOL initialized_lighting = FALSE;
	BOOL light_enabled = TRUE;
	
	BOOL use_shaders = gPipeline.canUseVertexShaders();
		
	for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
	{
		LLSpatialGroup* group = *i;
		llassert(group);
		llassert(group->getSpatialPartition());

		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;


			// <FS:LO> Dont suspend partical processing while particles are hidden, just skip over drawing them
			if(!(gPipeline.sRenderParticles) && (
												 group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE ||
												 group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE))
			{
				continue;
			}
			// </FS:LO>


			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];

			for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)	
			{
				LLDrawInfo& params = **k;

				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)
				{
					LLFace*	face = params.mFace;
					if(face)
					{
						const LLTextureEntry* tep = face->getTextureEntry();
						if(tep)
						{
							if(tep->getColor().mV[3] < 0.1f)
								continue;
						}
					}
				}

				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 = 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;
				}

				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 (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;
				}

				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);
				}

				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())
					{
						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);
					}
				}

				{
					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 (current_shader && 
					draw_glow_for_this_partition &&
					// <FS:Ansariel> Re-add particle rendering optimization
					//params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE))
					params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE) &&
					(!params.mParticle || params.mHasGlow))
					// </FS:Ansariel>
				{
					// <FS:Ansariel> LL materials support merge error
					LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_GLOW);

					// 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)

					// <FS:Ansariel> LL materials support merge error
					//emissive_shader->bind();
					//
					//params.mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);
					params.mVertexBuffer->setBuffer(mask | LLVertexBuffer::MAP_EMISSIVE);
					// </FS:Ansariel>
					
					// 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
					// <FS:Ansariel> LL materials support merge error
					//gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);

					//current_shader->bind();
					// </FS:Ansariel>
				}
			
				if (tex_setup)
				{
					gGL.getTexUnit(0)->activate();
					gGL.loadIdentity();
					gGL.matrixMode(LLRender::MM_MODELVIEW);
				}
			}
		}
	}

	gGL.setSceneBlendType(LLRender::BT_ALPHA);

	LLVertexBuffer::unbind();	
		
	if (!light_enabled)
	{
		gPipeline.enableLightsDynamic();
	}
}
示例#7
0
void LLDrawPoolAlpha::renderAlpha(U32 mask)
{
	BOOL initialized_lighting = FALSE;
	BOOL light_enabled = TRUE;
	//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)
	{
		LLSpatialGroup* group = *i;
		if (group->mSpatialPartition->mRenderByGroup &&
			!group->isDead())
		{
			LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];

			for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)	
			{
				LLDrawInfo& params = **k;

				LLRenderPass::applyModelMatrix(params);

				if (params.mTexture.notNull())
				{
					gGL.getTexUnit(0)->activate();
					gGL.getTexUnit(0)->bind(params.mTexture.get());

					if (params.mTextureMatrix)
					{
						glMatrixMode(GL_TEXTURE);
						glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);
						gPipeline.mTextureMatrixOps++;
					}
				}

				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;
				}

				// 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))
				{
					llassert(target_shader != NULL);
					if (deferred_render && current_shader != NULL)
					{
						gPipeline.unbindDeferredShader(*current_shader);
					}
					current_shader = target_shader;
					if (deferred_render)
					{
						gPipeline.bindDeferredShader(*current_shader);
					}
					else
					{
						current_shader->bind();
					}
				}
				else if (!use_shaders && current_shader != NULL)
				{
					LLGLSLShader::bindNoShader();
					if (deferred_render)
					{
						gPipeline.unbindDeferredShader(*current_shader);
					}
					current_shader = NULL;
				}

				if (params.mGroup)
				{
					params.mGroup->rebuildMesh();
				}
				params.mVertexBuffer->setBuffer(mask);
				params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
				gPipeline.addTrianglesDrawn(params.mCount/3);

				if (params.mTextureMatrix && params.mTexture.notNull())
				{
					gGL.getTexUnit(0)->activate();
					glLoadIdentity();
					glMatrixMode(GL_MODELVIEW);
				}
			}
		}
	}

	if (!light_enabled)
	{
		gPipeline.enableLightsDynamic();
	}
}