From 14f6bbadef2c39e58a3b54c0c6212949acf50e45 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 8 Aug 2011 15:29:23 -0500
Subject: SH-2242 Work in progress migrating to glVertexAttrib everywhere

---
 indra/llrender/llgl.cpp           |  79 +--------
 indra/llrender/llgl.h             |  12 +-
 indra/llrender/llglslshader.cpp   |   4 +
 indra/llrender/llrender.cpp       |  99 +++++++++++
 indra/llrender/llrender.h         |   6 +
 indra/llrender/llvertexbuffer.cpp | 352 ++++++++++++++++++++++++++++++--------
 indra/llrender/llvertexbuffer.h   |  10 ++
 7 files changed, 406 insertions(+), 156 deletions(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 2f6ef2b663..f58d4937d4 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -1329,8 +1329,6 @@ void LLGLState::initClass()
 
 	sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;
 	glDisable(GL_MULTISAMPLE_ARB);
-
-	glEnableClientState(GL_VERTEX_ARRAY);
 }
 
 //static
@@ -1604,7 +1602,7 @@ void LLGLState::checkTextureChannels(const std::string& msg)
 
 void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
 {
-	if (!gDebugGL)
+	if (!gDebugGL || LLGLSLShader::sNoFixedFunction)
 	{
 		return;
 	}
@@ -1661,7 +1659,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
 	};
 
 
-	for (S32 j = 0; j < 4; j++)
+	for (S32 j = 1; j < 4; j++)
 	{
 		if (glIsEnabled(value[j]))
 		{
@@ -1875,79 +1873,6 @@ void LLGLManager::initGLStates()
 
 ////////////////////////////////////////////////////////////////////////////////
 
-void enable_vertex_weighting(const S32 index)
-{
-#if GL_ARB_vertex_program
-	if (index > 0) glEnableVertexAttribArrayARB(index);	// vertex weights
-#endif
-}
-
-void disable_vertex_weighting(const S32 index)
-{
-#if GL_ARB_vertex_program
-	if (index > 0) glDisableVertexAttribArrayARB(index);	// vertex weights
-#endif
-}
-
-void enable_binormals(const S32 index)
-{
-#if GL_ARB_vertex_program
-	if (index > 0)
-	{
-		glEnableVertexAttribArrayARB(index);	// binormals
-	}
-#endif
-}
-
-void disable_binormals(const S32 index)
-{
-#if GL_ARB_vertex_program
-	if (index > 0)
-	{
-		glDisableVertexAttribArrayARB(index);	// binormals
-	}
-#endif
-}
-
-
-void enable_cloth_weights(const S32 index)
-{
-#if GL_ARB_vertex_program
-	if (index > 0)	glEnableVertexAttribArrayARB(index);
-#endif
-}
-
-void disable_cloth_weights(const S32 index)
-{
-#if GL_ARB_vertex_program
-	if (index > 0) glDisableVertexAttribArrayARB(index);
-#endif
-}
-
-void set_vertex_weights(const S32 index, const U32 stride, const F32 *weights)
-{
-#if GL_ARB_vertex_program
-	if (index > 0) glVertexAttribPointerARB(index, 1, GL_FLOAT, FALSE, stride, weights);
-	stop_glerror();
-#endif
-}
-
-void set_vertex_clothing_weights(const S32 index, const U32 stride, const LLVector4 *weights)
-{
-#if GL_ARB_vertex_program
-	if (index > 0) glVertexAttribPointerARB(index, 4, GL_FLOAT, TRUE, stride, weights);
-	stop_glerror();
-#endif
-}
-
-void set_binormals(const S32 index, const U32 stride,const LLVector3 *binormals)
-{
-#if GL_ARB_vertex_program
-	if (index > 0) glVertexAttribPointerARB(index, 3, GL_FLOAT, FALSE, stride, binormals);
-	stop_glerror();
-#endif
-}
-
 void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific )
 {
 	// GL_VERSION returns a null-terminated string with the format: 
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index d736133f3f..495e523c31 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -252,7 +252,7 @@ public:
 	static void dumpStates();
 	static void checkStates(const std::string& msg = "");
 	static void checkTextureChannels(const std::string& msg = "");
-	static void checkClientArrays(const std::string& msg = "", U32 data_mask = 0x0001);
+	static void checkClientArrays(const std::string& msg = "", U32 data_mask = 0);
 	
 protected:
 	static boost::unordered_map<LLGLenum, LLGLboolean> sStateMap;
@@ -419,15 +419,7 @@ extern LLMatrix4 gGLObliqueProjectionInverse;
 #include "llglstates.h"
 
 void init_glstates();
-void enable_vertex_weighting(const S32 index);
-void disable_vertex_weighting(const S32 index);
-void enable_binormals(const S32 index);
-void disable_binormals(const S32 index);
-void enable_cloth_weights(const S32 index);
-void disable_cloth_weights(const S32 index);
-void set_vertex_weights(const S32 index, const U32 stride, const F32 *weights);
-void set_vertex_clothing_weights(const S32 index, const U32 stride, const LLVector4 *weights);
-void set_binormals(const S32 index, const U32 stride, const LLVector3 *binormals);
+
 void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific );
 
 extern BOOL gClothRipple;
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index f51d83abe4..b6cb84d10c 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -31,6 +31,7 @@
 #include "llshadermgr.h"
 #include "llfile.h"
 #include "llrender.h"
+#include "llvertexbuffer.h"
 
 #if LL_DARWIN
 #include "OpenGL/OpenGL.h"
@@ -386,6 +387,7 @@ void LLGLSLShader::bind()
 	gGL.flush();
 	if (gGLManager.mHasShaderObjects)
 	{
+		LLVertexBuffer::unbind();
 		glUseProgramObjectARB(mProgramObject);
 		sCurBoundShader = mProgramObject;
 		sCurBoundShaderPtr = this;
@@ -411,6 +413,7 @@ void LLGLSLShader::unbind()
 				stop_glerror();
 			}
 		}
+		LLVertexBuffer::unbind();
 		glUseProgramObjectARB(0);
 		sCurBoundShader = 0;
 		sCurBoundShaderPtr = NULL;
@@ -420,6 +423,7 @@ void LLGLSLShader::unbind()
 
 void LLGLSLShader::bindNoShader(void)
 {
+	LLVertexBuffer::unbind();
 	glUseProgramObjectARB(0);
 	sCurBoundShader = 0;
 	sCurBoundShaderPtr = NULL;
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index d72918b15d..da85bc202c 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -1580,6 +1580,105 @@ void LLRender::color3fv(const GLfloat* c)
 	color4f(c[0],c[1],c[2],1);
 }
 
+void LLRender::diffuseColor3f(F32 r, F32 g, F32 b)
+{
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+	S32 loc = -1;
+	if (shader)
+	{
+		loc = shader->getAttribLocation(LLVertexBuffer::TYPE_COLOR);
+	}
+
+	if (loc >= 0)
+	{
+		glVertexAttrib3fARB(loc, r,g,b);
+	}
+	else
+	{
+		glColor3f(r,g,b);
+	}
+}
+
+void LLRender::diffuseColor3fv(const F32* c)
+{
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+	S32 loc = -1;
+	if (shader)
+	{
+		loc = shader->getAttribLocation(LLVertexBuffer::TYPE_COLOR);
+	}
+
+	if (loc >= 0)
+	{
+		glVertexAttrib3fvARB(loc, c);
+	}
+	else
+	{
+		glColor3fv(c);
+	}
+}
+
+void LLRender::diffuseColor4f(F32 r, F32 g, F32 b, F32 a)
+{
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+	S32 loc = -1;
+	if (shader)
+	{
+		loc = shader->getAttribLocation(LLVertexBuffer::TYPE_COLOR);
+	}
+
+	if (loc >= 0)
+	{
+		glVertexAttrib4fARB(loc, r,g,b,a);
+	}
+	else
+	{
+		glColor4f(r,g,b,a);
+	}
+
+}
+
+void LLRender::diffuseColor4fv(const F32* c)
+{
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+	S32 loc = -1;
+	if (shader)
+	{
+		loc = shader->getAttribLocation(LLVertexBuffer::TYPE_COLOR);
+	}
+
+	if (loc >= 0)
+	{
+		glVertexAttrib4fvARB(loc, c);
+	}
+	else
+	{
+		glColor4fv(c);
+	}
+}
+
+void LLRender::diffuseColor4ubv(const U8* c)
+{
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+	S32 loc = -1;
+	if (shader)
+	{
+		loc = shader->getAttribLocation(LLVertexBuffer::TYPE_COLOR);
+	}
+
+	if (loc >= 0)
+	{
+		glVertexAttrib4ubvARB(loc, c);
+	}
+	else
+	{
+		glColor4ubv(c);
+	}
+}
+
+
+
+
 void LLRender::debugTexUnits(void)
 {
 	LL_INFOS("TextureUnit") << "Active TexUnit: " << mCurrTextureUnitIndex << LL_ENDL;
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 9eedebe2ce..5f97bff1c4 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -350,6 +350,12 @@ public:
 	void color3fv(const GLfloat* c);
 	void color4ubv(const GLubyte* c);
 
+	void diffuseColor3f(F32 r, F32 g, F32 b);
+	void diffuseColor3fv(const F32* c);
+	void diffuseColor4f(F32 r, F32 g, F32 b, F32 a);
+	void diffuseColor4fv(const F32* c);
+	void diffuseColor4ubv(const U8* c);
+
 	void vertexBatchPreTransformed(LLVector3* verts, S32 vert_count);
 	void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count);
 	void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U*, S32 vert_count);
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 1180afa631..30f73bf2c6 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -130,6 +130,7 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
 	sizeof(LLVector2), // TYPE_TEXCOORD2,
 	sizeof(LLVector2), // TYPE_TEXCOORD3,
 	sizeof(LLColor4U), // TYPE_COLOR,
+	sizeof(U8),		   // TYPE_EMISSIVE
 	sizeof(LLVector4), // TYPE_BINORMAL,
 	sizeof(F32),	   // TYPE_WEIGHT,
 	sizeof(LLVector4), // TYPE_WEIGHT4,
@@ -156,36 +157,79 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
 		llerrs << "Cannot use LLGLImmediate and LLVertexBuffer simultaneously!" << llendl;
 	}*/
 
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+
 	if (sLastMask != data_mask)
 	{
+		llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
+		static LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr;
+		llassert(sLastMask == 0 || last_shader == shader);
+		last_shader = shader;
+
 		U32 mask[] =
 		{
 			MAP_VERTEX,
 			MAP_NORMAL,
 			MAP_TEXCOORD0,
 			MAP_COLOR,
+			MAP_EMISSIVE,
+			MAP_WEIGHT,
+			MAP_WEIGHT4,
+			MAP_BINORMAL,
+			MAP_CLOTHWEIGHT,
 		};
 		
+		U32 type[] =
+		{
+			TYPE_VERTEX,
+			TYPE_NORMAL,
+			TYPE_TEXCOORD0,
+			TYPE_COLOR,
+			TYPE_EMISSIVE,
+			TYPE_WEIGHT,
+			TYPE_WEIGHT4,
+			TYPE_BINORMAL,
+			TYPE_CLOTHWEIGHT,
+		};
+
 		GLenum array[] =
 		{
 			GL_VERTEX_ARRAY,
 			GL_NORMAL_ARRAY,
 			GL_TEXTURE_COORD_ARRAY,
 			GL_COLOR_ARRAY,
+			0,
+			0,
+			0,
+			0,
+			0,
 		};
 
 		BOOL error = FALSE;
-		for (U32 i = 0; i < 4; ++i)
+		for (U32 i = 0; i < 9; ++i)
 		{
+			S32 loc = -1;
+			if (shader)
+			{
+				loc = shader->getAttribLocation(type[i]);
+			}
+
 			if (sLastMask & mask[i])
 			{ //was enabled
-				if (!(data_mask & mask[i]) && i > 0)
+				if (!(data_mask & mask[i]))
 				{ //needs to be disabled
-					glDisableClientState(array[i]);
+					if (loc >= 0)
+					{
+						glDisableVertexAttribArrayARB(loc);
+					}
+					else if (!shader)
+					{
+						glDisableClientState(array[i]);
+					}
 				}
-				else if (gDebugGL)
-				{ //needs to be enabled, make sure it was (DEBUG TEMPORARY)
-					if (i > 0 && !glIsEnabled(array[i]))
+				else if (gDebugGL && !shader && array[i])
+				{ //needs to be enabled, make sure it was (DEBUG)
+					if (loc < 0 && !glIsEnabled(array[i]))
 					{
 						if (gDebugSession)
 						{
@@ -201,11 +245,18 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
 			}
 			else 
 			{	//was disabled
-				if (data_mask & mask[i] && i > 0)
+				if (data_mask & mask[i])
 				{ //needs to be enabled
-					glEnableClientState(array[i]);
+					if (loc >= 0)
+					{
+						glEnableVertexAttribArrayARB(loc);
+					}
+					else if (!shader)
+					{
+						glEnableClientState(array[i]);
+					}
 				}
-				else if (gDebugGL && i > 0 && glIsEnabled(array[i]))
+				else if (!shader && array[i] && gDebugGL && glIsEnabled(array[i]))
 				{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)
 					if (gDebugSession)
 					{
@@ -232,62 +283,71 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
 			MAP_TEXCOORD3
 		};
 
+		U32 type_tc[] = 
+		{
+			TYPE_TEXCOORD1,
+			TYPE_TEXCOORD2,
+			TYPE_TEXCOORD3
+		};
+
 		for (U32 i = 0; i < 3; i++)
 		{
+			S32 loc = -1;
+			if (shader)
+			{
+				loc = shader->getAttribLocation(type_tc[i]);
+			}
+
 			if (sLastMask & map_tc[i])
 			{
 				if (!(data_mask & map_tc[i]))
-				{
-					glClientActiveTextureARB(GL_TEXTURE1_ARB+i);
-					glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-					glClientActiveTextureARB(GL_TEXTURE0_ARB);
+				{ //disable
+					if (loc >= 0)
+					{
+						glDisableVertexAttribArrayARB(loc);
+					}
+					else if (!shader)
+					{
+						glClientActiveTextureARB(GL_TEXTURE1_ARB+i);
+						glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+						glClientActiveTextureARB(GL_TEXTURE0_ARB);
+					}
 				}
 			}
 			else if (data_mask & map_tc[i])
 			{
-				glClientActiveTextureARB(GL_TEXTURE1_ARB+i);
-				glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-				glClientActiveTextureARB(GL_TEXTURE0_ARB);
+				if (loc >= 0)
+				{
+					glEnableVertexAttribArrayARB(loc);
+				}
+				else if (!shader)
+				{
+					glClientActiveTextureARB(GL_TEXTURE1_ARB+i);
+					glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+					glClientActiveTextureARB(GL_TEXTURE0_ARB);
+				}
 			}
 		}
 
-		if (sLastMask & MAP_BINORMAL)
+		if (!shader)
 		{
-			if (!(data_mask & MAP_BINORMAL))
+			if (sLastMask & MAP_BINORMAL)
 			{
-				glClientActiveTextureARB(GL_TEXTURE2_ARB);
-				glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-				glClientActiveTextureARB(GL_TEXTURE0_ARB);
+				if (!(data_mask & MAP_BINORMAL))
+				{
+					glClientActiveTextureARB(GL_TEXTURE2_ARB);
+					glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+					glClientActiveTextureARB(GL_TEXTURE0_ARB);
+				}
 			}
-		}
-		else if (data_mask & MAP_BINORMAL)
-		{
-			glClientActiveTextureARB(GL_TEXTURE2_ARB);
-			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-			glClientActiveTextureARB(GL_TEXTURE0_ARB);
-		}
-	
-		if (sLastMask & MAP_WEIGHT4)
-		{
-			if (sWeight4Loc < 0)
+			else if (data_mask & MAP_BINORMAL)
 			{
-				llerrs << "Weighting disabled but vertex buffer still bound!" << llendl;
-			}
-
-			if (!(data_mask & MAP_WEIGHT4))
-			{ //disable 4-component skin weight			
-				glDisableVertexAttribArrayARB(sWeight4Loc);
-			}
-		}
-		else if (data_mask & MAP_WEIGHT4)
-		{
-			if (sWeight4Loc >= 0)
-			{ //enable 4-component skin weight
-				glEnableVertexAttribArrayARB(sWeight4Loc);
+				glClientActiveTextureARB(GL_TEXTURE2_ARB);
+				glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+				glClientActiveTextureARB(GL_TEXTURE0_ARB);
 			}
 		}
-				
-
+		
 		sLastMask = data_mask;
 	}
 }
@@ -1592,6 +1652,10 @@ bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index, S
 {
 	return VertexBufferStrider<LLColor4U,TYPE_COLOR>::get(*this, strider, index, count, map_range);
 }
+bool LLVertexBuffer::getEmissiveStrider(LLStrider<U8>& strider, S32 index, S32 count, bool map_range)
+{
+	return VertexBufferStrider<U8,TYPE_EMISSIVE>::get(*this, strider, index, count, map_range);
+}
 bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, S32 index, S32 count, bool map_range)
 {
 	return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index, count, map_range);
@@ -1810,46 +1874,166 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
 		llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;
 	}
 
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+
+	//assert that fixed function is allowed OR a shader is currently bound
+	llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
+
 	if (data_mask & MAP_NORMAL)
 	{
-		glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL]));
+		S32 loc = -1;
+		if (shader)
+		{
+			loc = shader->getAttribLocation(TYPE_NORMAL);
+		}
+
+		if (loc >= 0)
+		{
+			glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL]));
+		}
+		else if (!shader)
+		{
+			glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL]));
+		}
 	}
 	if (data_mask & MAP_TEXCOORD3)
 	{
-		glClientActiveTextureARB(GL_TEXTURE3_ARB);
-		glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3]));
-		glClientActiveTextureARB(GL_TEXTURE0_ARB);
+		S32 loc = -1;
+		if (shader)
+		{
+			loc = shader->getAttribLocation(TYPE_TEXCOORD3);
+		}
+
+		if (loc >= 0)
+		{
+			glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3]));
+		}
+		else if (!shader)
+		{
+			glClientActiveTextureARB(GL_TEXTURE3_ARB);
+			glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3]));
+			glClientActiveTextureARB(GL_TEXTURE0_ARB);
+		}
 	}
 	if (data_mask & MAP_TEXCOORD2)
 	{
-		glClientActiveTextureARB(GL_TEXTURE2_ARB);
-		glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2]));
-		glClientActiveTextureARB(GL_TEXTURE0_ARB);
+		S32 loc = -1;
+		if (shader)
+		{
+			loc = shader->getAttribLocation(TYPE_TEXCOORD2);
+		}
+
+		if (loc >= 0)
+		{
+			glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2]));
+		}
+		else if (!shader)
+		{
+			glClientActiveTextureARB(GL_TEXTURE2_ARB);
+			glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2]));
+			glClientActiveTextureARB(GL_TEXTURE0_ARB);
+		}
 	}
 	if (data_mask & MAP_TEXCOORD1)
 	{
-		glClientActiveTextureARB(GL_TEXTURE1_ARB);
-		glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
-		glClientActiveTextureARB(GL_TEXTURE0_ARB);
+		S32 loc = -1;
+		if (shader)
+		{
+			loc = shader->getAttribLocation(TYPE_TEXCOORD1);
+		}
+
+		if (loc >= 0)
+		{
+			glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
+		}
+		else if (!shader)
+		{
+			glClientActiveTextureARB(GL_TEXTURE1_ARB);
+			glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
+			glClientActiveTextureARB(GL_TEXTURE0_ARB);
+		}
 	}
 	if (data_mask & MAP_BINORMAL)
 	{
-		glClientActiveTextureARB(GL_TEXTURE2_ARB);
-		glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL]));
-		glClientActiveTextureARB(GL_TEXTURE0_ARB);
+		S32 loc = -1;
+		if (shader)
+		{
+			loc = shader->getAttribLocation(TYPE_BINORMAL);
+		}
+
+		if (loc >= 0)
+		{
+			glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL]));
+		}
+		else if (!shader)
+		{
+			glClientActiveTextureARB(GL_TEXTURE2_ARB);
+			glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL]));
+			glClientActiveTextureARB(GL_TEXTURE0_ARB);
+		}
 	}
 	if (data_mask & MAP_TEXCOORD0)
 	{
-		glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
+		S32 loc = -1;
+		if (shader)
+		{
+			loc = shader->getAttribLocation(TYPE_TEXCOORD0);
+		}
+
+		if (loc >= 0)
+		{
+			glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
+		}
+		else if (!shader)
+		{
+			glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
+		}
 	}
 	if (data_mask & MAP_COLOR)
 	{
-		glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR]));
+		S32 loc = -1;
+		if (shader)
+		{
+			loc = shader->getAttribLocation(TYPE_COLOR);
+		}
+
+		if (loc >= 0)
+		{
+			glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR]));
+		}
+		else if (!shader)
+		{
+			glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR]));
+		}
+	}
+	if (data_mask & MAP_EMISSIVE)
+	{
+		S32 loc = -1;
+		if (shader)
+		{
+			loc = shader->getAttribLocation(TYPE_EMISSIVE);
+		}
+
+		if (loc >= 0)
+		{
+			glVertexAttribPointerARB(loc, 1, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], (void*)(base + mOffsets[TYPE_EMISSIVE]));
+		}
 	}
-	
 	if (data_mask & MAP_WEIGHT)
 	{
-		glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], (void*)(base + mOffsets[TYPE_WEIGHT]));
+		S32 loc = -1;
+		if (shader)
+		{
+			loc = shader->getAttribLocation(TYPE_WEIGHT);
+		}
+
+		if (loc < 0)
+		{ //legacy behavior, some shaders have weight hardcoded to location 1
+			loc = 1;
+		}
+		
+		glVertexAttribPointerARB(loc, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], (void*)(base + mOffsets[TYPE_WEIGHT]));
+		
 	}
 
 	if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1)
@@ -1859,17 +2043,47 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
 
 	if (data_mask & MAP_CLOTHWEIGHT)
 	{
-		glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE,  LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]));
+		S32 loc = -1;
+		if (shader)
+		{
+			loc = shader->getAttribLocation(TYPE_CLOTHWEIGHT);
+		}
+
+		if (loc < 0)
+		{ //legacy behavior, some shaders have weight hardcoded to location 4
+			loc = 4;
+		}
+		glVertexAttribPointerARB(loc, 4, GL_FLOAT, TRUE,  LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]));
 	}
 	if (data_mask & MAP_VERTEX)
 	{
-		if (data_mask & MAP_TEXTURE_INDEX)
+		S32 loc = -1;
+		if (shader)
 		{
-			glVertexPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
+			loc = shader->getAttribLocation(TYPE_VERTEX);
 		}
-		else
+
+		if (loc >= 0)
 		{
-			glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
+			if (data_mask & MAP_TEXTURE_INDEX)
+			{
+				glVertexAttribPointerARB(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
+			}
+			else
+			{
+				glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
+			}
+		}
+		else if (!shader)
+		{
+			if (data_mask & MAP_TEXTURE_INDEX)
+			{
+				glVertexPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
+			}
+			else
+			{
+				glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
+			}
 		}
 	}
 
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index cc5d11e1c2..3cccdf62ec 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -133,6 +133,12 @@ public:
 	static S32 calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices);		
 
 	
+	//WARNING -- when updating these enums you MUST 
+	// 1 - update LLVertexBuffer::sTypeSize
+	// 2 - add a strider accessor
+	// 3 - modify LLVertexBuffer::setupVertexBuffer
+	// 4 - modify LLVertexBuffer::setupClientArray
+	// 5 - modify LLViewerShaderMgr::mReservedAttribs
 	enum {
 		TYPE_VERTEX,
 		TYPE_NORMAL,
@@ -141,6 +147,7 @@ public:
 		TYPE_TEXCOORD2,
 		TYPE_TEXCOORD3,
 		TYPE_COLOR,
+		TYPE_EMISSIVE,
 		// These use VertexAttribPointer and should possibly be made generic
 		TYPE_BINORMAL,
 		TYPE_WEIGHT,
@@ -160,6 +167,7 @@ public:
 		MAP_TEXCOORD2 = (1<<TYPE_TEXCOORD2),
 		MAP_TEXCOORD3 = (1<<TYPE_TEXCOORD3),
 		MAP_COLOR = (1<<TYPE_COLOR),
+		MAP_EMISSIVE = (1<<TYPE_EMISSIVE),
 		// These use VertexAttribPointer and should possibly be made generic
 		MAP_BINORMAL = (1<<TYPE_BINORMAL),
 		MAP_WEIGHT = (1<<TYPE_WEIGHT),
@@ -218,10 +226,12 @@ public:
 	bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
 	bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
 	bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
+	bool getEmissiveStrider(LLStrider<U8>& strider, S32 index=0, S32 count = -1, bool map_range = false);
 	bool getWeightStrider(LLStrider<F32>& strider, S32 index=0, S32 count = -1, bool map_range = false);
 	bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
 	bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
 	
+
 	BOOL isEmpty() const					{ return mEmpty; }
 	BOOL isLocked() const					{ return mVertexLocked || mIndexLocked; }
 	S32 getNumVerts() const					{ return mNumVerts; }
-- 
cgit v1.2.3


From 2ee815478043c4d5845f094f744a055707dba0e0 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 10 Aug 2011 13:01:14 -0500
Subject: SH-2238, SH-2223, SH-SH-2242 glVertexAttrib throughout main render
 pipeline complete, preview renders and debug displays still pending.  Also
 fixed a render glitch and a crash (JIRAs listed).

---
 indra/llrender/llglslshader.cpp   |  2 +
 indra/llrender/llrendersphere.cpp | 97 +--------------------------------------
 indra/llrender/llrendersphere.h   |  5 --
 indra/llrender/llvertexbuffer.cpp | 62 +++++++++++++++++++++++--
 indra/llrender/llvertexbuffer.h   |  3 +-
 5 files changed, 63 insertions(+), 106 deletions(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index b6cb84d10c..02bcc9e338 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -934,7 +934,9 @@ void LLGLSLShader::uniform4fv(const string& uniform, U32 count, const GLfloat* v
 		std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
 		if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
 		{
+			stop_glerror();
 			glUniform4fvARB(location, count, v);
+			stop_glerror();
 			mValue[location] = vec;
 		}
 	}
diff --git a/indra/llrender/llrendersphere.cpp b/indra/llrender/llrendersphere.cpp
index a5cd70445f..e7e07a1ab2 100644
--- a/indra/llrender/llrendersphere.cpp
+++ b/indra/llrender/llrendersphere.cpp
@@ -35,106 +35,11 @@
 
 #include "llglheaders.h"
 
-GLUquadricObj *gQuadObj2 = NULL;
 LLRenderSphere gSphere;
 
-void drawSolidSphere(GLdouble radius, GLint slices, GLint stacks);
-
-void drawSolidSphere(GLdouble radius, GLint slices, GLint stacks)
-{
-	if (!gQuadObj2)
-	{
-		gQuadObj2 = gluNewQuadric();
-		if (!gQuadObj2)
-		{
-			llwarns << "drawSolidSphere couldn't allocate quadric" << llendl;
-			return;
-		}
-	}
-
-	gluQuadricDrawStyle(gQuadObj2, GLU_FILL);
-	gluQuadricNormals(gQuadObj2, GLU_SMOOTH);
-	// If we ever changed/used the texture or orientation state
-	// of quadObj, we'd need to change it to the defaults here
-	// with gluQuadricTexture and/or gluQuadricOrientation.
-	gluQuadricTexture(gQuadObj2, GL_TRUE);
-	gluSphere(gQuadObj2, radius, slices, stacks);
-}
-
-
-// A couple thoughts on sphere drawing:
-// 1) You need more slices than stacks, but little less than 2:1
-// 2) At low LOD, setting stacks to an odd number avoids a "band" around the equator, making things look smoother
-void LLRenderSphere::prerender()
-{
-	//  Create a series of display lists for different LODs
-	mDList[0] = glGenLists(1);
-	glNewList(mDList[0], GL_COMPILE);
-	drawSolidSphere(1.0, 30, 20);
-	glEndList();
-
-	mDList[1] = glGenLists(1);
-	glNewList(mDList[1], GL_COMPILE);
-	drawSolidSphere(1.0, 20, 15);
-	glEndList();
-
-	mDList[2] = glGenLists(1);
-	glNewList(mDList[2], GL_COMPILE);
-	drawSolidSphere(1.0, 12, 8);
-	glEndList();
-
-	mDList[3] = glGenLists(1);
-	glNewList(mDList[3], GL_COMPILE);
-	drawSolidSphere(1.0, 8, 5);
-	glEndList();
-}
-
-void LLRenderSphere::cleanupGL()
-{
-	for (S32 detail = 0; detail < 4; detail++)
-	{
-		glDeleteLists(mDList[detail], 1);
-		mDList[detail] = 0;
-	}
-	
-	if (gQuadObj2)
-	{
-		gluDeleteQuadric(gQuadObj2);
-		gQuadObj2 = NULL;
-	}
-}
-
-// Constants here are empirically derived from my eyeballs, JNC
-//
-// The toughest adjustment is the cutoff for the lowest LOD
-// Maybe we should have more LODs at the low end?
-void LLRenderSphere::render(F32 pixel_area)
-{
-	S32 level_of_detail;
-
-	if (pixel_area > 10000.f)
-	{
-		level_of_detail = 0;
-	}
-	else if (pixel_area > 800.f)
-	{
-		level_of_detail = 1;
-	}
-	else if (pixel_area > 100.f)
-	{
-		level_of_detail = 2;
-	}
-	else
-	{
-		level_of_detail = 3;
-	}
-	glCallList(mDList[level_of_detail]);
-}
-
-
 void LLRenderSphere::render()
 {
-	glCallList(mDList[0]);
+	renderGGL();
 }
 
 inline LLVector3 polar_to_cart(F32 latitude, F32 longitude)
diff --git a/indra/llrender/llrendersphere.h b/indra/llrender/llrendersphere.h
index 96a6bec80c..f8e9e86e7f 100644
--- a/indra/llrender/llrendersphere.h
+++ b/indra/llrender/llrendersphere.h
@@ -40,11 +40,6 @@ void lat2xyz(LLVector3 * result, F32 lat, F32 lon);			// utility routine
 class LLRenderSphere  
 {
 public:
-	LLGLuint	mDList[5];
-
-	void prerender();
-	void cleanupGL();
-	void render(F32 pixel_area);		// of a box of size 1.0 at that position
 	void render();						// render at highest LOD
 	void renderGGL();                   // render using LLRender
 
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index a5977d658d..5d19168842 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -62,7 +62,6 @@ U32 LLVertexBuffer::sAllocatedBytes = 0;
 BOOL LLVertexBuffer::sMapped = FALSE;
 BOOL LLVertexBuffer::sUseStreamDraw = TRUE;
 BOOL LLVertexBuffer::sPreferStreamDraw = FALSE;
-S32	LLVertexBuffer::sWeight4Loc = -1;
 
 std::vector<U32> LLVertexBuffer::sDeleteList;
 
@@ -355,6 +354,8 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
 //static
 void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm)
 {
+	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
+
 	U32 count = pos.size();
 	llassert_always(norm.size() >= pos.size());
 	llassert_always(count > 0) ;
@@ -369,6 +370,49 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con
 	glDrawArrays(sGLMode[mode], 0, count);
 }
 
+//static
+void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp)
+{
+	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
+
+	U32 mask = LLVertexBuffer::MAP_VERTEX;
+	if (tc)
+	{
+		mask = mask | LLVertexBuffer::MAP_TEXCOORD0;
+	}
+
+	unbind();
+	
+	setupClientArrays(mask);
+
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+
+	if (shader)
+	{
+		S32 loc = shader->getAttribLocation(LLVertexBuffer::TYPE_VERTEX);
+		if (loc > -1)
+		{
+			glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 16, pos);
+
+			if (tc)
+			{
+				loc = shader->getAttribLocation(LLVertexBuffer::TYPE_TEXCOORD0);
+				if (loc > -1)
+				{
+					glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, 0, tc);
+				}
+			}
+		}
+	}
+	else
+	{
+		glTexCoordPointer(2, GL_FLOAT, 0, tc);
+		glVertexPointer(3, GL_FLOAT, 16, pos);
+	}
+
+	glDrawElements(sGLMode[mode], num_indices, GL_UNSIGNED_SHORT, indicesp);
+}
+
 void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const
 {
 	if (start >= (U32) mRequestedNumVerts ||
@@ -403,6 +447,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
 	validateRange(start, end, count, indices_offset);
 
 	llassert(mRequestedNumVerts >= 0);
+	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
 
 	if (mGLIndices != sGLRenderIndices)
 	{
@@ -431,6 +476,8 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
 
 void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
 {
+	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
+
 	llassert(mRequestedNumIndices >= 0);
 	if (indices_offset >= (U32) mRequestedNumIndices ||
 	    indices_offset + count > (U32) mRequestedNumIndices)
@@ -463,6 +510,8 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
 
 void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
 {
+	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
+
 	llassert(mRequestedNumVerts >= 0);
 	if (first >= (U32) mRequestedNumVerts ||
 	    first + count > (U32) mRequestedNumVerts)
@@ -2037,9 +2086,16 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
 		
 	}
 
-	if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1)
+	if (data_mask & MAP_WEIGHT4)
 	{
-		glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], (void*)(base+mOffsets[TYPE_WEIGHT4]));
+		if (shader)
+		{
+			S32 loc = shader->getAttribLocation(TYPE_WEIGHT4);
+			if (loc > -1)
+			{
+				glVertexAttribPointerARB(loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], (void*)(base+mOffsets[TYPE_WEIGHT4]));
+			}
+		}
 	}
 
 	if (data_mask & MAP_CLOTHWEIGHT)
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index 3cccdf62ec..9497bc9357 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -111,8 +111,6 @@ public:
 	static LLVBOPool sStreamIBOPool;
 	static LLVBOPool sDynamicIBOPool;
 
-	static S32	sWeight4Loc;
-
 	static BOOL	sUseStreamDraw;
 	static BOOL	sPreferStreamDraw;
 
@@ -120,6 +118,7 @@ public:
 	static void cleanupClass();
 	static void setupClientArrays(U32 data_mask);
 	static void drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm);
+	static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp);
 
  	static void clientCopy(F64 max_time = 0.005); //copy data from client to GL
 	static void unbind(); //unbind any bound vertex buffer
-- 
cgit v1.2.3


From 2dd8ce53e4e0d14f2bc20796eb6bdf1ef12a65df Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Thu, 11 Aug 2011 14:19:58 -0500
Subject: SH-2242 FXAA support instead of unreliable multisample textures (done
 here because it's a smaller change than integrating glVertexAttrib with FSAA
 pipe).  Shader integration with LLDynamicTexture subclasses.

---
 indra/llrender/llgl.cpp        |  2 ++
 indra/llrender/llshadermgr.cpp | 13 ++++++++++---
 2 files changed, 12 insertions(+), 3 deletions(-)

(limited to 'indra/llrender')

diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 87a6b9b885..1a2fe0ea0e 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -582,6 +582,8 @@ bool LLGLManager::initGL()
 		glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords);
 	}
 
+	//HACK always disable texture multisample, use FXAA instead
+	mHasTextureMultisample = FALSE;
 #if LL_WINDOWS
 	if (mIsATI)
 	{ //using multisample textures on ATI results in black screen for some reason
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 986c1f2774..2334435644 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -531,9 +531,9 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 	}
 
 	//we can't have any lines longer than 1024 characters 
-	//or any shaders longer than 1024 lines... deal - DaveP
+	//or any shaders longer than 4096 lines... deal - DaveP
 	GLcharARB buff[1024];
-	GLcharARB* text[1024];
+	GLcharARB* text[4096];
 	GLuint count = 0;
 
 	if (gGLManager.mGLVersion < 2.1f)
@@ -649,7 +649,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 	}
 
 	//copy file into memory
-	while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(buff) ) 
+	while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(text) ) 
 	{
 		text[count++] = (GLcharARB *)strdup((char *)buff); 
 	}
@@ -709,6 +709,13 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 				for (GLuint i = 0; i < count; i++)
 				{
 					ostr << i << ": " << text[i];
+
+					if (i % 128 == 0)
+					{ //dump every 128 lines
+						LL_WARNS("ShaderLoading") << "\n" << ostr.str() << llendl;
+						ostr = std::stringstream();
+					}
+
 				}
 
 				LL_WARNS("ShaderLoading") << "\n" << ostr.str() << llendl;
-- 
cgit v1.2.3