From 5b400d50e1f25667e2c865d85fd93546ffe7f96f Mon Sep 17 00:00:00 2001
From: Graham Linden <graham@lindenlab.com>
Date: Tue, 6 Aug 2013 14:16:46 -0700
Subject: [PATCH] NORSPEC-322 NORSPEC-342 fix issues with black impostors and
 missing alpha attachments on impostors

---
 .../shaders/class1/deferred/impostorF.glsl    | 31 +++++++++++++++++--
 indra/newview/lldrawpoolalpha.cpp             |  9 ++++--
 indra/newview/lldrawpoolavatar.cpp            | 21 ++-----------
 indra/newview/pipeline.cpp                    | 21 ++++++-------
 4 files changed, 48 insertions(+), 34 deletions(-)

diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
index bc0719cb82d..d52744103f7 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
@@ -38,6 +38,31 @@ uniform sampler2D specularMap;
 
 VARYING vec2 vary_texcoord0;
 
+vec2 encode_normal(vec3 n)
+{
+	float f = sqrt(8 * n.z + 8);
+	return n.xy / f + 0.5;
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+	cl = clamp(cl, vec3(0), vec3(1));
+	vec3 low_range  = cl * 12.92;
+	vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+	bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+	vec3 result;
+	result.r = lt.r ? low_range.r : high_range.r;
+	result.g = lt.g ? low_range.g : high_range.g;
+	result.b = lt.b ? low_range.b : high_range.b;
+    return result;
+#else
+	return mix(high_range, low_range, lt);
+#endif
+
+}
+
 void main() 
 {
 	vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
@@ -47,7 +72,7 @@ void main()
 		discard;
 	}
 
-	frag_data[0] = vec4(col.rgb, col.a * 0.005);
-	frag_data[1] = texture2D(specularMap, vary_texcoord0.xy);
-	frag_data[2] = vec4(texture2D(normalMap, vary_texcoord0.xy).xyz, 0.0);
+	frag_data[0] = vec4(linear_to_srgb(col.rgb), col.a);
+	frag_data[1] = vec4(texture2D(specularMap, vary_texcoord0.xy));
+	frag_data[2] = vec4(texture2D(normalMap, vary_texcoord0.xy).xy,0,0);
 }
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index b5d37ba5cc7..60e22c08dcd 100755
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -224,8 +224,13 @@ void LLDrawPoolAlpha::render(S32 pass)
 		gGL.setColorMask(true, true);
 	}
 	
-	LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy || 
-				(deferred_render && pass == 1) ? GL_TRUE : GL_FALSE);
+	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::sImpostorRender;
+
+	LLGLDepthTest depth(GL_TRUE, write_depth ? GL_TRUE : GL_FALSE);
 
 	if (deferred_render && pass == 1)
 	{
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index e2a23ef56f8..9434b51685f 100755
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -505,7 +505,7 @@ S32 LLDrawPoolAvatar::getNumDeferredPasses()
 {
 	if (LLPipeline::sImpostorRender)
 	{
-		return 3;
+		return 19;
 	}
 	else
 	{
@@ -690,28 +690,15 @@ void LLDrawPoolAvatar::beginDeferredImpostor()
 		LLVOAvatar::sNumVisibleAvatars = 0;
 	}
 
-#if DEFERRED_IMPOSTORS
 	sVertexProgram = &gDeferredImpostorProgram;
-
-	specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
-	normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL);
-	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-#else
-	sVertexProgram = &gImpostorProgram;
-	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-#endif
-	sVertexProgram->bind();
+	gPipeline.bindDeferredShader(*sVertexProgram);
 	sVertexProgram->setMinimumAlpha(0.01f);
 }
 
 void LLDrawPoolAvatar::endDeferredImpostor()
 {
 	sShaderLevel = mVertexShaderLevel;
-	sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL);
-	sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP);
-	sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-	sVertexProgram->unbind();
-	gGL.getTexUnit(0)->activate();
+	gPipeline.unbindDeferredShader(*sVertexProgram);
 }
 
 void LLDrawPoolAvatar::beginDeferredRigid()
@@ -1268,7 +1255,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 
 		if (impostor)
 		{
-#if DEFERRED_IMPOSTORS
 			if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && avatarp->mImpostor.isComplete()) 
 			{
 				if (normal_channel > -1)
@@ -1280,7 +1266,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 					avatarp->mImpostor.bindTexture(1, specular_channel);
 				}
 			}
-#endif
 			avatarp->renderImpostor(LLColor4U(255,255,255,255), sDiffuseChannel);
 		}
 		return;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 9aa375767b1..29b7e306558 100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -11358,15 +11358,18 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
 		if (!avatar->mImpostor.isComplete())
 		{
 			LLFastTimer t(FTM_IMPOSTOR_ALLOCATE);
-			avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE);
+			
 
-#if DEFERRED_IMPOSTORS
 			if (LLPipeline::sRenderDeferred)
 			{
+				avatar->mImpostor.allocate(resX,resY,GL_SRGB8_ALPHA8,TRUE,FALSE);
 				addDeferredAttachments(avatar->mImpostor);
 			}
-#endif
-			
+			else
+			{
+				avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE);
+			}
+
 			gGL.getTexUnit(0)->bind(&avatar->mImpostor);
 			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
 			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -11374,38 +11377,34 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
 		else if(resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight())
 		{
 			LLFastTimer t(FTM_IMPOSTOR_RESIZE);
-			avatar->mImpostor.resize(resX,resY,GL_RGBA);
+			avatar->mImpostor.resize(resX,resY,LLPipeline::sRenderDeferred ? GL_SRGB8_ALPHA8 : GL_RGBA);
 		}
 
 		avatar->mImpostor.bindTarget();		
 	}
 
-#if DEFERRED_IMPOSTORS
 	if (LLPipeline::sRenderDeferred)
 	{
-		avatar->mImpostor.clear();
+		avatar->mImpostor.clear();		
 		renderGeomDeferred(camera);
 		renderGeomPostDeferred(camera);
 	}
 	else
-#endif
 	{		
 		LLGLEnable scissor(GL_SCISSOR_TEST);
 		glScissor(0, 0, resX, resY);	
 		avatar->mImpostor.clear();
 		renderGeom(camera);
 	}
-	
+
 	{ //create alpha mask based on depth buffer (grey out if muted)
 		LLFastTimer t(FTM_IMPOSTOR_BACKGROUND);
 
-#if DEFERRED_IMPOSTORS
 		if (LLPipeline::sRenderDeferred)
 		{
 			GLuint buff = GL_COLOR_ATTACHMENT0;
 			glDrawBuffersARB(1, &buff);
 		}
-#endif
 
 		LLGLDisable blend(GL_BLEND);
 
-- 
GitLab