void LLPostProcess::applyColorFilterShader(void)
{	
	if(gPostColorFilterProgram.mProgramObject == 0)
		return;

	gPostColorFilterProgram.bind();

	gGL.getTexUnit(0)->bind(mSceneRenderTexture);

	gPostColorFilterProgram.uniform1f("gamma", tweaks.getGamma());
	gPostColorFilterProgram.uniform1f("brightness", tweaks.getBrightness());
	gPostColorFilterProgram.uniform1f("contrast", tweaks.getContrast());
	float baseI = (tweaks.getContrastBaseR() + tweaks.getContrastBaseG() + tweaks.getContrastBaseB()) / 3.0f;
	baseI = tweaks.getContrastBaseIntensity() / ((baseI < 0.001f) ? 0.001f : baseI);
	float baseR = tweaks.getContrastBaseR() * baseI;
	float baseG = tweaks.getContrastBaseG() * baseI;
	float baseB = tweaks.getContrastBaseB() * baseI;
	gPostColorFilterProgram.uniform3fv("contrastBase", 1, LLVector3(baseR, baseG, baseB).mV);
	gPostColorFilterProgram.uniform1f("saturation", tweaks.getSaturation());
	gPostColorFilterProgram.uniform3fv("lumWeights", 1, LLVector3(LUMINANCE_R, LUMINANCE_G, LUMINANCE_B).mV);
		
	/// Draw a screen space quad
	drawOrthoQuad(QUAD_NORMAL);
	gPostColorFilterProgram.unbind();
}
void LLPostProcess::applyNightVisionShader(void)
{	
	if(gPostNightVisionProgram.mProgramObject == 0)
		return;

	gPostNightVisionProgram.bind();

	gGL.getTexUnit(0)->bind(mSceneRenderTexture);
	gGL.getTexUnit(1)->bind(mNoiseTexture);
	
	gPostNightVisionProgram.uniform1f("brightMult", tweaks.getBrightMult());
	gPostNightVisionProgram.uniform1f("noiseStrength", tweaks.getNoiseStrength());
	mNoiseTextureScale = 0.001f + ((100.f - tweaks.getNoiseSize()) / 100.f);
	mNoiseTextureScale *= (mScreenHeight / NOISE_SIZE);
	
	/// Draw a screen space quad
	drawOrthoQuad(QUAD_NOISE);
	gPostNightVisionProgram.unbind();
}
void LLPostProcess::applyShaders(void)
{
	QuadType quad;
	bool primary_rendertarget = 1;
	for(std::list<LLPointer<LLPostProcessShader> >::iterator it=mShaders.begin();it!=mShaders.end();++it)
	{
		if((quad = (*it)->bind()) != QUAD_NONE)
		{
			S32 color_channel = (*it)->getColorChannel();
			S32 depth_channel = (*it)->getDepthChannel();

			if(depth_channel >= 0)
				gGL.getTexUnit(depth_channel)->bindManual(LLTexUnit::TT_RECT_TEXTURE, mDepthTexture);

			U32 pass = 1;

			while((*it)->draw(pass++))
			{
				mRenderTarget[!primary_rendertarget].bindTarget();

				if(color_channel >= 0)
					mRenderTarget[mRenderTarget[0].getFBO() ? primary_rendertarget : !primary_rendertarget].bindTexture(0,color_channel);

				drawOrthoQuad(quad);
				mRenderTarget[!primary_rendertarget].flush();
				if(mRenderTarget[0].getFBO())
					primary_rendertarget = !primary_rendertarget;
			}
			(*it)->unbind();
		}
	}
	//Only need to copy to framebuffer if FBOs are supported, else we've already been drawing to the framebuffer to begin with.
	if(mRenderTarget[0].getFBO())
	{
		//copyContentsToFramebuffer also binds the main framebuffer.
		LLRenderTarget::copyContentsToFramebuffer(mRenderTarget[primary_rendertarget],0,0,mScreenWidth,mScreenHeight,0,0,mScreenWidth,mScreenHeight,GL_COLOR_BUFFER_BIT, GL_NEAREST);
	}
	stop_glerror();
}
void LLPostProcess::applyGaussBlurShader(void)
{
	int pass_count = tweaks.getGaussBlurPasses();
	if(!pass_count || gPostGaussianBlurProgram.mProgramObject == 0)
		return;

	gPostGaussianBlurProgram.bind();

	gGL.getTexUnit(0)->bind(mSceneRenderTexture);

	GLint horiz_pass = gPostGaussianBlurProgram.getUniformLocation("horizontalPass");
	for(int i = 0;i<pass_count;++i)
	{
		for(int j = 0;j<2;++j)
		{
			if(i || j)
				copyFrameBuffer();		
			glUniform1iARB(horiz_pass, j);
			drawOrthoQuad(QUAD_NORMAL);
		}
	}
	gPostGaussianBlurProgram.unbind();
}