diff --git a/doc/contributions.txt b/doc/contributions.txt
index 988410701b741e0022592b6a1ca9c3305585a816..31dcf8541f820b7fbef75ae50fc78a0ea5dbed92 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -1107,6 +1107,7 @@ Tofu Buzzard
 	CTS-411
 	STORM-546
 	VWR-24509
+	SH-2477
 Tony Kembia
 Torben Trautman
 TouchaHoney Perhaps
diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp
index 31cdb1219bd3d1235c915c5e0c5dcafc784f6d92..9b86daebe5d93441a6541c8f47be17bd3356518f 100644
--- a/indra/llmessage/llassetstorage.cpp
+++ b/indra/llmessage/llassetstorage.cpp
@@ -149,8 +149,8 @@ void LLAssetInfo::setFromNameValue( const LLNameValue& nv )
 	setName( buf );
 	buf.assign( str, pos2, std::string::npos );
 	setDescription( buf );
-	llinfos << "uuid: " << mUuid << llendl;
-	llinfos << "creator: " << mCreatorID << llendl;
+	LL_DEBUGS("AssetStorage") << "uuid: " << mUuid << llendl;
+	LL_DEBUGS("AssetStorage") << "creator: " << mCreatorID << llendl;
 }
 
 ///----------------------------------------------------------------------------
@@ -434,9 +434,9 @@ bool LLAssetStorage::findInStaticVFSAndInvokeCallback(const LLUUID& uuid, LLAsse
 // IW - uuid is passed by value to avoid side effects, please don't re-add &    
 void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, LLGetAssetCallback callback, void *user_data, BOOL is_priority)
 {
-	lldebugs << "LLAssetStorage::getAssetData() - " << uuid << "," << LLAssetType::lookup(type) << llendl;
+	LL_DEBUGS("AssetStorage") << "LLAssetStorage::getAssetData() - " << uuid << "," << LLAssetType::lookup(type) << llendl;
 
-	llinfos << "ASSET_TRACE requesting " << uuid << " type " << LLAssetType::lookup(type) << llendl;
+	LL_DEBUGS("AssetStorage") << "ASSET_TRACE requesting " << uuid << " type " << LLAssetType::lookup(type) << llendl;
 
 	if (user_data)
 	{
@@ -446,7 +446,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, LL
 
 	if (mShutDown)
 	{
-		llinfos << "ASSET_TRACE cancelled " << uuid << " type " << LLAssetType::lookup(type) << " shutting down" << llendl;
+		LL_DEBUGS("AssetStorage") << "ASSET_TRACE cancelled " << uuid << " type " << LLAssetType::lookup(type) << " shutting down" << llendl;
 
 		if (callback)
 		{
@@ -468,7 +468,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, LL
 	// Try static VFS first.
 	if (findInStaticVFSAndInvokeCallback(uuid,type,callback,user_data))
 	{
-		llinfos << "ASSET_TRACE asset " << uuid << " found in static VFS" << llendl;
+		LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << uuid << " found in static VFS" << llendl;
 		return;
 	}
 
@@ -486,7 +486,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, LL
 			callback(mVFS, uuid, type, user_data, LL_ERR_NOERR, LL_EXSTAT_VFS_CACHED);
 		}
 
-		llinfos << "ASSET_TRACE asset " << uuid << " found in VFS" << llendl;
+		LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << uuid << " found in VFS" << llendl;
 	}
 	else
 	{
@@ -520,7 +520,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, LL
 		}
 		if (duplicate)
 		{
-			llinfos << "Adding additional non-duplicate request for asset " << uuid 
+			LL_DEBUGS("AssetStorage") << "Adding additional non-duplicate request for asset " << uuid 
 					<< "." << LLAssetType::lookup(type) << llendl;
 		}
 		
@@ -584,9 +584,9 @@ void LLAssetStorage::downloadCompleteCallback(
 	LLAssetType::EType file_type,
 	void* user_data, LLExtStat ext_status)
 {
-	llinfos << "ASSET_TRACE asset " << file_id << " downloadCompleteCallback" << llendl;
+	LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << file_id << " downloadCompleteCallback" << llendl;
 
-	lldebugs << "LLAssetStorage::downloadCompleteCallback() for " << file_id
+	LL_DEBUGS("AssetStorage") << "LLAssetStorage::downloadCompleteCallback() for " << file_id
 		 << "," << LLAssetType::lookup(file_type) << llendl;
 	LLAssetRequest* req = (LLAssetRequest*)user_data;
 	if(!req)
@@ -731,7 +731,7 @@ void LLAssetStorage::getEstateAsset(const LLHost &object_sim, const LLUUID &agen
 			tpvf.setAsset(asset_id, atype);
 			tpvf.setCallback(downloadEstateAssetCompleteCallback, req);
 
-			llinfos << "Starting transfer for " << asset_id << llendl;
+			LL_DEBUGS("AssetStorage") << "Starting transfer for " << asset_id << llendl;
 			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(source_host, LLTCT_ASSET);
 			ttcp->requestTransfer(spe, tpvf, 100.f + (is_priority ? 1.f : 0.f));
 		}
@@ -871,7 +871,7 @@ void LLAssetStorage::getInvItemAsset(const LLHost &object_sim, const LLUUID &age
 			tpvf.setAsset(asset_id, atype);
 			tpvf.setCallback(downloadInvItemCompleteCallback, req);
 
-			llinfos << "Starting transfer for inventory asset "
+			LL_DEBUGS("AssetStorage") << "Starting transfer for inventory asset "
 				<< item_id << " owned by " << owner_id << "," << task_id
 				<< llendl;
 			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(source_host, LLTCT_ASSET);
@@ -1211,7 +1211,7 @@ bool LLAssetStorage::deletePendingRequest(LLAssetStorage::ERequestType rt,
 	request_list_t* requests = getRequestList(rt);
 	if (deletePendingRequestImpl(requests, asset_type, asset_id))
 	{
-		llinfos << "Asset " << getRequestName(rt) << " request for "
+		LL_DEBUGS("AssetStorage") << "Asset " << getRequestName(rt) << " request for "
 				<< asset_id << "." << LLAssetType::lookup(asset_type)
 				<< " removed from pending queue." << llendl;
 		return true;
@@ -1307,7 +1307,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, vo
 			user_data == ((LLLegacyAssetRequest *)tmp->mUserData)->mUserData)
 		{
 			// this is a duplicate from the same subsystem - throw it away
-			llinfos << "Discarding duplicate request for UUID " << uuid << llendl;
+			LL_DEBUGS("AssetStorage") << "Discarding duplicate request for UUID " << uuid << llendl;
 			return;
 		}
 	}
@@ -1490,7 +1490,7 @@ void LLAssetStorage::reportMetric( const LLUUID& asset_id, const LLAssetType::ET
 {
 	if( !metric_recipient )
 	{
-		llinfos << "Couldn't store LLAssetStoreage::reportMetric - no metrics_recipient" << llendl;
+		LL_DEBUGS("AssetStorage") << "Couldn't store LLAssetStoreage::reportMetric - no metrics_recipient" << llendl;
 		return;
 	}
 
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
index 1b10354c22919e597b2ee67d0660cf579d6c30fb..45a3b18179a8aff6b2646aaf02e5aea96bf05add 100644
--- a/indra/llrender/llcubemap.cpp
+++ b/indra/llrender/llcubemap.cpp
@@ -36,6 +36,7 @@
 #include "m4math.h"
 
 #include "llrender.h"
+#include "llglslshader.h"
 
 #include "llglheaders.h"
 
@@ -195,7 +196,7 @@ void LLCubeMap::enableTexture(S32 stage)
 void LLCubeMap::enableTextureCoords(S32 stage)
 {
 	mTextureCoordStage = stage;
-	if (gGLManager.mHasCubeMap && stage >= 0 && LLCubeMap::sUseCubeMaps)
+	if (!LLGLSLShader::sNoFixedFunction && gGLManager.mHasCubeMap && stage >= 0 && LLCubeMap::sUseCubeMaps)
 	{
 		if (stage > 0)
 		{
@@ -237,7 +238,7 @@ void LLCubeMap::disableTexture(void)
 
 void LLCubeMap::disableTextureCoords(void)
 {
-	if (gGLManager.mHasCubeMap && mTextureCoordStage >= 0 && LLCubeMap::sUseCubeMaps)
+	if (!LLGLSLShader::sNoFixedFunction && gGLManager.mHasCubeMap && mTextureCoordStage >= 0 && LLCubeMap::sUseCubeMaps)
 	{
 		if (mTextureCoordStage > 0)
 		{
@@ -264,19 +265,19 @@ void LLCubeMap::setMatrix(S32 stage)
 		gGL.getTexUnit(stage)->activate();
 	}
 
-	LLVector3 x(LLVector3d(gGLModelView+0));
-	LLVector3 y(LLVector3d(gGLModelView+4));
-	LLVector3 z(LLVector3d(gGLModelView+8));
+	LLVector3 x(gGLModelView+0);
+	LLVector3 y(gGLModelView+4);
+	LLVector3 z(gGLModelView+8);
 
 	LLMatrix3 mat3;
 	mat3.setRows(x,y,z);
 	LLMatrix4 trans(mat3);
 	trans.transpose();
 
-	glMatrixMode(GL_TEXTURE);
-	glPushMatrix();
-	glLoadMatrixf((F32 *)trans.mMatrix);
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.pushMatrix();
+	gGL.loadMatrix((F32 *)trans.mMatrix);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	
 	/*if (stage > 0)
 	{
@@ -292,9 +293,9 @@ void LLCubeMap::restoreMatrix()
 	{
 		gGL.getTexUnit(mMatrixStage)->activate();
 	}
-	glMatrixMode(GL_TEXTURE);
-	glPopMatrix();
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.popMatrix();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	
 	/*if (mMatrixStage > 0)
 	{
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 4e3cfb9c8aa5aba028caaaf8baa6f63549024e43..c0d15fe6f368f2b7854b12cc48b91c5cf6bb9978 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -67,6 +67,36 @@ static const std::string HEADLESS_VERSION_STRING("1.0");
 
 std::ofstream gFailLog;
 
+#if GL_ARB_debug_output
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+
+void APIENTRY gl_debug_callback(GLenum source,
+                                GLenum type,
+                                GLuint id,
+                                GLenum severity,
+                                GLsizei length,
+                                const GLchar* message,
+                                GLvoid* userParam)
+{
+	if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
+	{
+		llwarns << "----- GL ERROR --------" << llendl;
+	}
+	else
+	{
+		llwarns << "----- GL WARNING -------" << llendl;
+	}
+	llwarns << "Type: " << std::hex << type << llendl;
+	llwarns << "ID: " << std::hex << id << llendl;
+	llwarns << "Severity: " << std::hex << severity << llendl;
+	llwarns << "Message: " << message << llendl;
+	llwarns << "-----------------------" << llendl;
+}
+#endif
+
 void ll_init_fail_log(std::string filename)
 {
 	gFailLog.open(filename.c_str());
@@ -110,6 +140,11 @@ std::list<LLGLUpdate*> LLGLUpdate::sGLQ;
 
 #if (LL_WINDOWS || LL_LINUX || LL_SOLARIS)  && !LL_MESA_HEADLESS
 // ATI prototypes
+
+#if LL_WINDOWS
+PFNGLGETSTRINGIPROC glGetStringi = NULL;
+#endif
+
 // vertex blending prototypes
 PFNGLWEIGHTPOINTERARBPROC			glWeightPointerARB = NULL;
 PFNGLVERTEXBLENDARBPROC				glVertexBlendARB = NULL;
@@ -128,6 +163,12 @@ PFNGLUNMAPBUFFERARBPROC				glUnmapBufferARB = NULL;
 PFNGLGETBUFFERPARAMETERIVARBPROC	glGetBufferParameterivARB = NULL;
 PFNGLGETBUFFERPOINTERVARBPROC		glGetBufferPointervARB = NULL;
 
+//GL_ARB_vertex_array_object
+PFNGLBINDVERTEXARRAYPROC glBindVertexArray = NULL;
+PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays = NULL;
+PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = NULL;
+PFNGLISVERTEXARRAYPROC glIsVertexArray = NULL;
+
 // GL_ARB_map_buffer_range
 PFNGLMAPBUFFERRANGEPROC			glMapBufferRange = NULL;
 PFNGLFLUSHMAPPEDBUFFERRANGEPROC	glFlushMappedBufferRange = NULL;
@@ -197,10 +238,16 @@ PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample = NULL;
 PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer = NULL;
 
 //GL_ARB_texture_multisample
-PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
-PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
-PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
-PFNGLSAMPLEMASKIPROC glSampleMaski;
+PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample = NULL;
+PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample = NULL;
+PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv = NULL;
+PFNGLSAMPLEMASKIPROC glSampleMaski = NULL;
+
+//GL_ARB_debug_output
+PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB = NULL;
+PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB = NULL;
+PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB = NULL;
+PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB = NULL;
 
 // GL_EXT_blend_func_separate
 PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT = NULL;
@@ -249,6 +296,10 @@ PFNGLGETUNIFORMFVARBPROC glGetUniformfvARB = NULL;
 PFNGLGETUNIFORMIVARBPROC glGetUniformivARB = NULL;
 PFNGLGETSHADERSOURCEARBPROC glGetShaderSourceARB = NULL;
 
+#if LL_WINDOWS
+PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
+#endif
+
 // vertex shader prototypes
 #if LL_LINUX || LL_SOLARIS
 PFNGLVERTEXATTRIB1DARBPROC glVertexAttrib1dARB = NULL;
@@ -349,6 +400,7 @@ LLGLManager::LLGLManager() :
 	mHasBlendFuncSeparate(FALSE),
 	mHasSync(FALSE),
 	mHasVertexBufferObject(FALSE),
+	mHasVertexArrayObject(FALSE),
 	mHasMapBufferRange(FALSE),
 	mHasFlushBufferRange(FALSE),
 	mHasPBuffer(FALSE),
@@ -370,6 +422,7 @@ LLGLManager::LLGLManager() :
 	mHasAnisotropic(FALSE),
 	mHasARBEnvCombine(FALSE),
 	mHasCubeMap(FALSE),
+	mHasDebugOutput(FALSE),
 
 	mIsATI(FALSE),
 	mIsNVIDIA(FALSE),
@@ -409,6 +462,15 @@ void LLGLManager::initWGL()
 		LL_WARNS("RenderInit") << "No ARB pixel format extensions" << LL_ENDL;
 	}
 
+	if (ExtensionExists("WGL_ARB_create_context",gGLHExts.mSysExts))
+	{
+		GLH_EXT_NAME(wglCreateContextAttribsARB) = (PFNWGLCREATECONTEXTATTRIBSARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglCreateContextAttribsARB");
+	}
+	else
+	{
+		LL_WARNS("RenderInit") << "No ARB create context extensions" << LL_ENDL;
+	}
+	
 	if (ExtensionExists("WGL_EXT_swap_control", gGLHExts.mSysExts))
 	{
         GLH_EXT_NAME(wglSwapIntervalEXT) = (PFNWGLSWAPINTERVALEXTPROC)GLH_EXT_GET_PROC_ADDRESS("wglSwapIntervalEXT");
@@ -438,13 +500,45 @@ bool LLGLManager::initGL()
 		LL_ERRS("RenderInit") << "Calling init on LLGLManager after already initialized!" << LL_ENDL;
 	}
 
-	GLint alpha_bits;
-	glGetIntegerv( GL_ALPHA_BITS, &alpha_bits );
-	if( 8 != alpha_bits )
+	stop_glerror();
+
+#if LL_WINDOWS
+	if (!glGetStringi)
 	{
-		LL_WARNS("RenderInit") << "Frame buffer has less than 8 bits of alpha.  Avatar texture compositing will fail." << LL_ENDL;
+		glGetStringi = (PFNGLGETSTRINGIPROC) GLH_EXT_GET_PROC_ADDRESS("glGetStringi");
 	}
 
+	//reload extensions string (may have changed after using wglCreateContextAttrib)
+	if (glGetStringi)
+	{
+		std::stringstream str;
+
+		GLint count = 0;
+		glGetIntegerv(GL_NUM_EXTENSIONS, &count);
+		for (GLint i = 0; i < count; ++i)
+		{
+			std::string ext((const char*) glGetStringi(GL_EXTENSIONS, i));
+			str << ext << " ";
+			LL_DEBUGS("GLExtensions") << ext << llendl;
+		}
+		
+		{
+			PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = 0;
+			wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
+			if(wglGetExtensionsStringARB)
+			{
+				str << (const char*) wglGetExtensionsStringARB(wglGetCurrentDC());
+			}
+		}
+
+		free(gGLHExts.mSysExts);
+		std::string extensions = str.str();
+		gGLHExts.mSysExts = strdup(extensions.c_str());
+	}
+#endif
+	
+	stop_glerror();
+
 	// Extract video card strings and convert to upper case to
 	// work around driver-to-driver variation in capitalization.
 	mGLVendor = std::string((const char *)glGetString(GL_VENDOR));
@@ -531,8 +625,12 @@ bool LLGLManager::initGL()
 		mGLVendorShort = "MISC";
 	}
 	
+	stop_glerror();
 	// This is called here because it depends on the setting of mIsGF2or4MX, and sets up mHasMultitexture.
 	initExtensions();
+	stop_glerror();
+
+	S32 old_vram = mVRAM;
 
 	if (mHasATIMemInfo)
 	{ //ask the gl how much vram is free at startup and attempt to use no more than half of that
@@ -548,7 +646,27 @@ bool LLGLManager::initGL()
 		mVRAM = dedicated_memory/1024;
 	}
 
-	if (mHasMultitexture)
+	if (mVRAM < 256)
+	{ //something likely went wrong using the above extensions, fall back to old method
+		mVRAM = old_vram;
+	}
+
+	stop_glerror();
+
+	stop_glerror();
+
+	if (mHasFragmentShader)
+	{
+		GLint num_tex_image_units;
+		glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
+		mNumTextureImageUnits = llmin(num_tex_image_units, 32);
+	}
+
+	if (LLRender::sGLCoreProfile)
+	{
+		mNumTextureUnits = llmin(mNumTextureImageUnits, MAX_GL_TEXTURE_UNITS);
+	}
+	else if (mHasMultitexture)
 	{
 		GLint num_tex_units;		
 		glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &num_tex_units);
@@ -567,12 +685,7 @@ bool LLGLManager::initGL()
 		return false;
 	}
 	
-	if (mHasFragmentShader)
-	{
-		GLint num_tex_image_units;
-		glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
-		mNumTextureImageUnits = llmin(num_tex_image_units, 32);
-	}
+	stop_glerror();
 
 	if (mHasTextureMultisample)
 	{
@@ -582,6 +695,21 @@ bool LLGLManager::initGL()
 		glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords);
 	}
 
+	stop_glerror();
+
+#if LL_WINDOWS
+	if (mHasDebugOutput && gDebugGL)
+	{ //setup debug output callback
+		//glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, GL_TRUE);
+		glDebugMessageCallbackARB((GLDEBUGPROCARB) gl_debug_callback, NULL);
+		glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
+	}
+#endif
+
+	stop_glerror();
+
+	//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
@@ -593,10 +721,17 @@ bool LLGLManager::initGL()
 	{
 		glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples);
 	}
+
+	stop_glerror();
 	
 	setToDebugGPU();
 
+	stop_glerror();
+
 	initGLStates();
+
+	stop_glerror();
+
 	return true;
 }
 
@@ -774,7 +909,7 @@ void LLGLManager::initExtensions()
 	mHasVertexShader = FALSE;
 	mHasFragmentShader = FALSE;
 	mHasTextureRectangle = FALSE;
-#else // LL_MESA_HEADLESS
+#else // LL_MESA_HEADLESS //important, gGLHExts.mSysExts is uninitialized until after glh_init_extensions is called
 	mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
 	mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts);
 	mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts);
@@ -788,6 +923,7 @@ void LLGLManager::initExtensions()
 	mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);
 	mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts);
 	mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
+	mHasVertexArrayObject = ExtensionExists("GL_ARB_vertex_array_object", gGLHExts.mSysExts);
 	mHasSync = ExtensionExists("GL_ARB_sync", gGLHExts.mSysExts);
 	mHasMapBufferRange = ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts);
 	mHasFlushBufferRange = ExtensionExists("GL_APPLE_flush_buffer_range", gGLHExts.mSysExts);
@@ -806,13 +942,14 @@ void LLGLManager::initExtensions()
 	mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts);
 	mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts);
 	mHasTextureMultisample = ExtensionExists("GL_ARB_texture_multisample", gGLHExts.mSysExts);
+	mHasDebugOutput = ExtensionExists("GL_ARB_debug_output", gGLHExts.mSysExts);
 #if !LL_DARWIN
 	mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
 #endif
-	mHasShaderObjects = ExtensionExists("GL_ARB_shader_objects", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
+	mHasShaderObjects = ExtensionExists("GL_ARB_shader_objects", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
 	mHasVertexShader = ExtensionExists("GL_ARB_vertex_program", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_vertex_shader", gGLHExts.mSysExts)
-						&& ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
-	mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
+		&& (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
+	mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
 #endif
 
 #if LL_LINUX || LL_SOLARIS
@@ -985,6 +1122,13 @@ void LLGLManager::initExtensions()
 			mHasVertexBufferObject = FALSE;
 		}
 	}
+	if (mHasVertexArrayObject)
+	{
+		glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) GLH_EXT_GET_PROC_ADDRESS("glBindVertexArray");
+		glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteVertexArrays");
+		glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) GLH_EXT_GET_PROC_ADDRESS("glGenVertexArrays");
+		glIsVertexArray = (PFNGLISVERTEXARRAYPROC) GLH_EXT_GET_PROC_ADDRESS("glIsVertexArray");
+	}
 	if (mHasSync)
 	{
 		glFenceSync = (PFNGLFENCESYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glFenceSync");
@@ -1039,6 +1183,13 @@ void LLGLManager::initExtensions()
 		glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetMultisamplefv");
 		glSampleMaski = (PFNGLSAMPLEMASKIPROC) GLH_EXT_GET_PROC_ADDRESS("glSampleMaski");
 	}	
+	if (mHasDebugOutput)
+	{
+		glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageControlARB");
+		glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageInsertARB");
+		glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageCallbackARB");
+		glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetDebugMessageLogARB");
+	}
 #if (!LL_LINUX && !LL_SOLARIS) || LL_LINUX_NV_GL_HEADERS
 	// This is expected to be a static symbol on Linux GL implementations, except if we use the nvidia headers - bah
 	glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
@@ -1193,7 +1344,7 @@ void rotate_quat(LLQuaternion& rotation)
 {
 	F32 angle_radians, x, y, z;
 	rotation.getAngleAxis(&angle_radians, &x, &y, &z);
-	glRotatef(angle_radians * RAD_TO_DEG, x, y, z);
+	gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
 }
 
 void flush_glerror()
@@ -1230,10 +1381,6 @@ void log_glerror()
 
 void do_assert_glerror()
 {
-	if (LL_UNLIKELY(!gGLManager.mInited))
-	{
-		LL_ERRS("RenderInit") << "GL not initialized" << LL_ENDL;
-	}
 	//  Create or update texture to be used with this data 
 	GLenum error;
 	error = glGetError();
@@ -1326,11 +1473,6 @@ void LLGLState::initClass()
 	//make sure multisample defaults to disabled
 	sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;
 	glDisable(GL_MULTISAMPLE_ARB);
-
-	sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;
-	glDisable(GL_MULTISAMPLE_ARB);
-
-	glEnableClientState(GL_VERTEX_ARRAY);
 }
 
 //static
@@ -1604,7 +1746,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 +1803,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]))
 		{
@@ -1783,17 +1925,26 @@ LLGLState::LLGLState(LLGLenum state, S32 enabled) :
 	mState(state), mWasEnabled(FALSE), mIsEnabled(FALSE)
 {
 	if (LLGLSLShader::sNoFixedFunction)
-	{ //always disable state that's deprecated post GL 3.0
+	{ //always ignore state that's deprecated post GL 3.0
 		switch (state)
 		{
 			case GL_ALPHA_TEST:
-				enabled = 0;
+			case GL_NORMALIZE:
+			case GL_TEXTURE_GEN_R:
+			case GL_TEXTURE_GEN_S:
+			case GL_TEXTURE_GEN_T:
+			case GL_TEXTURE_GEN_Q:
+			case GL_LIGHTING:
+			case GL_COLOR_MATERIAL:
+			case GL_FOG:
+			case GL_LINE_STIPPLE:
+				mState = 0;
 				break;
 		}
 	}
 
 	stop_glerror();
-	if (state)
+	if (mState)
 	{
 		mWasEnabled = sStateMap[state];
 		llassert(mWasEnabled == glIsEnabled(state));
@@ -1875,79 +2026,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: 
@@ -2060,20 +2138,20 @@ void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
     glh::matrix4f suffix;
     suffix.set_row(2, cplane);
     glh::matrix4f newP = suffix * P;
-    glMatrixMode(GL_PROJECTION);
-	glPushMatrix();
-    glLoadMatrixf(newP.m);
+    gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.pushMatrix();
+    gGL.loadMatrix(newP.m);
 	gGLObliqueProjectionInverse = LLMatrix4(newP.inverse().transpose().m);
-    glMatrixMode(GL_MODELVIEW);
+    gGL.matrixMode(LLRender::MM_MODELVIEW);
 }
 
 LLGLUserClipPlane::~LLGLUserClipPlane()
 {
 	if (mApply)
 	{
-		glMatrixMode(GL_PROJECTION);
-		glPopMatrix();
-		glMatrixMode(GL_MODELVIEW);
+		gGL.matrixMode(LLRender::MM_PROJECTION);
+		gGL.popMatrix();
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
 	}
 }
 
@@ -2263,16 +2341,16 @@ LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P, U32 layer)
 		P.element(2, i) = P.element(3, i) * depth;
 	}
 
-	glMatrixMode(GL_PROJECTION);
-	glPushMatrix();
-	glLoadMatrixf(P.m);
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.pushMatrix();
+	gGL.loadMatrix(P.m);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 }
 
 LLGLSquashToFarClip::~LLGLSquashToFarClip()
 {
-	glMatrixMode(GL_PROJECTION);
-	glPopMatrix();
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.popMatrix();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 }
 
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index d736133f3ffc14ba21ec732be273c5338bcf0e76..dee7ec07395c2646e704ccbb9ae87d3c6612c5c1 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -88,6 +88,7 @@ class LLGLManager
 		
 	// ARB Extensions
 	BOOL mHasVertexBufferObject;
+	BOOL mHasVertexArrayObject;
 	BOOL mHasSync;
 	BOOL mHasMapBufferRange;
 	BOOL mHasFlushBufferRange;
@@ -112,6 +113,7 @@ class LLGLManager
 	BOOL mHasAnisotropic;
 	BOOL mHasARBEnvCombine;
 	BOOL mHasCubeMap;
+	BOOL mHasDebugOutput;
 
 	// Vendor-specific extensions
 	BOOL mIsATI;
@@ -252,7 +254,7 @@ class LLGLState
 	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 +421,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/llglheaders.h b/indra/llrender/llglheaders.h
index 851a75629e184e60767390c843360156d7d8515a..10aad202e17f1357afe2a0137699722e6cf94f50 100644
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -68,6 +68,12 @@ extern PFNGLUNMAPBUFFERARBPROC		glUnmapBufferARB;
 extern PFNGLGETBUFFERPARAMETERIVARBPROC	glGetBufferParameterivARB;
 extern PFNGLGETBUFFERPOINTERVARBPROC	glGetBufferPointervARB;
 
+// GL_ARB_vertex_array_object
+extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
+extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
+extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
+extern PFNGLISVERTEXARRAYPROC glIsVertexArray;
+
 // GL_ARB_sync
 extern PFNGLFENCESYNCPROC				glFenceSync;
 extern PFNGLISSYNCPROC					glIsSync;
@@ -310,6 +316,12 @@ extern PFNGLCLIENTACTIVETEXTUREARBPROC	glClientActiveTextureARB;
 extern PFNGLDRAWRANGEELEMENTSPROC 	glDrawRangeElements;
 #endif // LL_LINUX_NV_GL_HEADERS
 
+// GL_ARB_vertex_array_object
+extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
+extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
+extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
+extern PFNGLISVERTEXARRAYPROC glIsVertexArray;
+
 // GL_ARB_vertex_buffer_object
 extern PFNGLBINDBUFFERARBPROC		glBindBufferARB;
 extern PFNGLDELETEBUFFERSARBPROC	glDeleteBuffersARB;
@@ -531,6 +543,9 @@ extern PFNGLSAMPLEMASKIPROC glSampleMaski;
 #include "GL/glext.h"
 #include "GL/glh_extensions.h"
 
+// WGL_ARB_create_context
+extern PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
+extern PFNGLGETSTRINGIPROC glGetStringi;
 
 // GL_ARB_vertex_buffer_object
 extern PFNGLBINDBUFFERARBPROC		glBindBufferARB;
@@ -545,6 +560,12 @@ extern PFNGLUNMAPBUFFERARBPROC		glUnmapBufferARB;
 extern PFNGLGETBUFFERPARAMETERIVARBPROC	glGetBufferParameterivARB;
 extern PFNGLGETBUFFERPOINTERVARBPROC	glGetBufferPointervARB;
 
+// GL_ARB_vertex_array_object
+extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
+extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
+extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
+extern PFNGLISVERTEXARRAYPROC glIsVertexArray;
+
 // GL_ARB_sync
 extern PFNGLFENCESYNCPROC				glFenceSync;
 extern PFNGLISSYNCPROC					glIsSync;
@@ -735,6 +756,12 @@ extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
 extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
 extern PFNGLSAMPLEMASKIPROC glSampleMaski;
 
+//GL_ARB_debug_output
+extern PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB;
+extern PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB;
+extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
+extern PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB;
+
 #elif LL_DARWIN
 //----------------------------------------------------------------------------
 // LL_DARWIN
@@ -899,6 +926,31 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
 #endif /* GL_GLEXT_FUNCTION_POINTERS */
 #endif
 
+#ifndef GL_ARB_texture_rg
+#define GL_RG                             0x8227
+#define GL_RG_INTEGER                     0x8228
+#define GL_R8                             0x8229
+#define GL_R16                            0x822A
+#define GL_RG8                            0x822B
+#define GL_RG16                           0x822C
+#define GL_R16F                           0x822D
+#define GL_R32F                           0x822E
+#define GL_RG16F                          0x822F
+#define GL_RG32F                          0x8230
+#define GL_R8I                            0x8231
+#define GL_R8UI                           0x8232
+#define GL_R16I                           0x8233
+#define GL_R16UI                          0x8234
+#define GL_R32I                           0x8235
+#define GL_R32UI                          0x8236
+#define GL_RG8I                           0x8237
+#define GL_RG8UI                          0x8238
+#define GL_RG16I                          0x8239
+#define GL_RG16UI                         0x823A
+#define GL_RG32I                          0x823B
+#define GL_RG32UI                         0x823C
+#endif
+
 // May be needed for DARWIN...
 // #ifndef GL_ARB_compressed_tex_image
 // #define GL_ARB_compressed_tex_image 1
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index f51d83abe486442aa2b17e067993b4913e08d525..d6ab5208c6f541859d9f8ee30fb94dc9dc8b368a 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"
@@ -50,6 +51,7 @@ using std::string;
 
 GLhandleARB LLGLSLShader::sCurBoundShader = 0;
 LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL;
+S32 LLGLSLShader::sIndexedTextureChannels = 0;
 bool LLGLSLShader::sNoFixedFunction = false;
 
 //UI shader -- declared here so llui_libtest will link properly
@@ -75,6 +77,7 @@ hasAlphaMask(false)
 LLGLSLShader::LLGLSLShader()
 	: mProgramObject(0), mActiveTextureChannels(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT), mUniformsDirty(FALSE)
 {
+
 }
 
 void LLGLSLShader::unload()
@@ -110,17 +113,19 @@ void LLGLSLShader::unload()
 BOOL LLGLSLShader::createShader(vector<string> * attributes,
 								vector<string> * uniforms)
 {
+	//reloading, reset matrix hash values
+	for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i)
+	{
+		mMatHash[i] = 0xFFFFFFFF;
+	}
+	mLightHash = 0xFFFFFFFF;
+
 	llassert_always(!mShaderFiles.empty());
 	BOOL success = TRUE;
 
 	// Create program
 	mProgramObject = glCreateProgramObjectARB();
 	
-	if (gGLManager.mGLVersion < 3.1f)
-	{ //force indexed texture channels to 1 if GL version is old (performance improvement for drivers with poor branching shader model support)
-		mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1);
-	}
-
 	//compile new source
 	vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
 	for ( ; fileIter != mShaderFiles.end(); fileIter++ )
@@ -235,6 +240,13 @@ void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count)
 
 BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
 {
+	//before linking, make sure reserved attributes always have consistent locations
+	for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
+	{
+		const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str();
+		glBindAttribLocationARB(mProgramObject, i, (const GLcharARB *) name);
+	}
+	
 	//link the program
 	BOOL res = link();
 
@@ -308,7 +320,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
 		for (S32 i = 0; i < (S32) LLShaderMgr::instance()->mReservedUniforms.size(); i++)
 		{
 			if ( (mUniform[i] == -1)
-				&& (LLShaderMgr::instance()->mReservedUniforms[i].compare(0, length, name, LLShaderMgr::instance()->mReservedUniforms[i].length()) == 0))
+				&& (LLShaderMgr::instance()->mReservedUniforms[i] == name))
 			{
 				//found it
 				mUniform[i] = location;
@@ -322,7 +334,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
 			for (U32 i = 0; i < uniforms->size(); i++)
 			{
 				if ( (mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] == -1)
-					&& ((*uniforms)[i].compare(0, length, name, (*uniforms)[i].length()) == 0))
+					&& ((*uniforms)[i] == name))
 				{
 					//found it
 					mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] = location;
@@ -386,6 +398,7 @@ void LLGLSLShader::bind()
 	gGL.flush();
 	if (gGLManager.mHasShaderObjects)
 	{
+		LLVertexBuffer::unbind();
 		glUseProgramObjectARB(mProgramObject);
 		sCurBoundShader = mProgramObject;
 		sCurBoundShaderPtr = this;
@@ -411,6 +424,7 @@ void LLGLSLShader::unbind()
 				stop_glerror();
 			}
 		}
+		LLVertexBuffer::unbind();
 		glUseProgramObjectARB(0);
 		sCurBoundShader = 0;
 		sCurBoundShaderPtr = NULL;
@@ -420,9 +434,13 @@ void LLGLSLShader::unbind()
 
 void LLGLSLShader::bindNoShader(void)
 {
-	glUseProgramObjectARB(0);
-	sCurBoundShader = 0;
-	sCurBoundShaderPtr = NULL;
+	LLVertexBuffer::unbind();
+	if (gGLManager.mHasShaderObjects)
+	{
+		glUseProgramObjectARB(0);
+		sCurBoundShader = 0;
+		sCurBoundShaderPtr = NULL;
+	}
 }
 
 S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
@@ -768,13 +786,17 @@ GLint LLGLSLShader::getUniformLocation(const string& uniform)
 		}
 	}
 
-	/*if (gDebugGL)
+	return ret;
+}
+
+GLint LLGLSLShader::getUniformLocation(U32 index)
+{
+	GLint ret = -1;
+	if (mProgramObject > 0)
 	{
-		if (ret == -1 && ret != glGetUniformLocationARB(mProgramObject, uniform.c_str()))
-		{
-			llerrs << "Uniform map invalid." << llendl;
-		}
-	}*/
+		llassert(index < mUniform.size());
+		return mUniform[index];
+	}
 
 	return ret;
 }
@@ -930,7 +952,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;
 		}
 	}
@@ -987,6 +1011,7 @@ void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v)
 
 void LLGLSLShader::setAlphaRange(F32 minimum, F32 maximum)
 {
+	gGL.flush();
 	uniform1f("minimum_alpha", minimum);
 	uniform1f("maximum_alpha", maximum);
 }
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 558ea66b50f7bd10d6c74377914e893ec62412b2..eb19599ecaaf9bea9618ff080d95dd45f17f4271 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -69,7 +69,7 @@ class LLGLSLShader
 
 	static GLhandleARB sCurBoundShader;
 	static LLGLSLShader* sCurBoundShaderPtr;
-
+	static S32 sIndexedTextureChannels;
 	static bool sNoFixedFunction;
 
 	void unload();
@@ -114,10 +114,11 @@ class LLGLSLShader
 	void vertexAttrib4fv(U32 index, GLfloat* v);
 	
 	GLint getUniformLocation(const std::string& uniform);
+	GLint getUniformLocation(U32 index);
+
 	GLint getAttribLocation(U32 attrib);
 	GLint mapUniformTextureChannel(GLint location, GLenum type);
 	
-
 	//enable/disable texture channel for specified uniform
 	//if given texture uniform is active in the shader, 
 	//the corresponding channel will be active upon return
@@ -132,6 +133,9 @@ class LLGLSLShader
 	// Unbinds any previously bound shader by explicitly binding no shader.
 	static void bindNoShader(void);
 
+	U32 mMatHash[LLRender::NUM_MATRIX_MODES];
+	U32 mLightHash;
+
 	GLhandleARB mProgramObject;
 	std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel
 	std::vector<GLint> mUniform;   //lookup table of uniform enum to uniform location
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 7188b0fa440666cd39e62e0b0c58ae74d8d4ca4d..3d3c94ef3e8221593f66e5d5f35a83acdd2727f8 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -36,7 +36,9 @@
 
 #include "llmath.h"
 #include "llgl.h"
+#include "llglslshader.h"
 #include "llrender.h"
+
 //----------------------------------------------------------------------------
 const F32 MIN_TEXTURE_LIFETIME = 10.f;
 
@@ -725,7 +727,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 		{
 			if (mAutoGenMips)
 			{
-				glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_GENERATE_MIPMAP_SGIS, TRUE);
+				if (!gGLManager.mHasFramebufferObject)
+				{
+					glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_GENERATE_MIPMAP_SGIS, TRUE);
+				}
 				stop_glerror();
 				{
 // 					LLFastTimer t2(FTM_TEMP4);
@@ -754,6 +759,11 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 						stop_glerror();
 					}
 				}
+
+				if (gGLManager.mHasFramebufferObject)
+				{
+					glGenerateMipmap(LLTexUnit::getInternalType(mBindTarget));
+				}
 			}
 			else
 			{
@@ -875,6 +885,9 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 
 BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
 {
+	//not compatible with core GL profile
+	llassert(!LLRender::sGLCoreProfile);
+
 	if (gGLManager.mIsDisabled)
 	{
 		llwarns << "Trying to create a texture while GL is disabled!" << llendl;
@@ -901,29 +914,29 @@ BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
 	{
 		switch (mComponents)
 		{
-		  case 1:
+			case 1:
 			// Use luminance alpha (for fonts)
 			mFormatInternal = GL_LUMINANCE8;
 			mFormatPrimary = GL_LUMINANCE;
 			mFormatType = GL_UNSIGNED_BYTE;
 			break;
-		  case 2:
+			case 2:
 			// Use luminance alpha (for fonts)
 			mFormatInternal = GL_LUMINANCE8_ALPHA8;
 			mFormatPrimary = GL_LUMINANCE_ALPHA;
 			mFormatType = GL_UNSIGNED_BYTE;
 			break;
-		  case 3:
+			case 3:
 			mFormatInternal = GL_RGB8;
 			mFormatPrimary = GL_RGB;
 			mFormatType = GL_UNSIGNED_BYTE;
 			break;
-		  case 4:
+			case 4:
 			mFormatInternal = GL_RGBA8;
 			mFormatPrimary = GL_RGBA;
 			mFormatType = GL_UNSIGNED_BYTE;
 			break;
-		  default:
+			default:
 			llerrs << "Bad number of components for texture: " << (U32)getComponents() << llendl;
 		}
 	}
@@ -1099,8 +1112,75 @@ void LLImageGL::deleteTextures(S32 numTextures, U32 *textures, bool immediate)
 // static
 void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels)
 {
-	glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, pixels);
+	bool use_scratch = false;
+	U32* scratch = NULL;
+	if (LLRender::sGLCoreProfile)
+	{
+		if (intformat == GL_ALPHA8 && pixformat == GL_ALPHA && pixtype == GL_UNSIGNED_BYTE) 
+		{ //GL_ALPHA is deprecated, convert to RGBA
+			use_scratch = true;
+			scratch = new U32[width*height];
+
+			U32 pixel_count = (U32) (width*height);
+			for (U32 i = 0; i < pixel_count; i++)
+			{
+				U8* pix = (U8*) &scratch[i];
+				pix[0] = pix[1] = pix[2] = 0;
+				pix[3] = ((U8*) pixels)[i];
+			}				
+			
+			pixformat = GL_RGBA;
+			intformat = GL_RGBA8;
+		}
+
+		if (intformat == GL_LUMINANCE8_ALPHA8 && pixformat == GL_LUMINANCE_ALPHA && pixtype == GL_UNSIGNED_BYTE) 
+		{ //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA
+			use_scratch = true;
+			scratch = new U32[width*height];
+
+			U32 pixel_count = (U32) (width*height);
+			for (U32 i = 0; i < pixel_count; i++)
+			{
+				U8 lum = ((U8*) pixels)[i*2+0];
+				U8 alpha = ((U8*) pixels)[i*2+1];
+
+				U8* pix = (U8*) &scratch[i];
+				pix[0] = pix[1] = pix[2] = lum;
+				pix[3] = alpha;
+			}				
+			
+			pixformat = GL_RGBA;
+			intformat = GL_RGBA8;
+		}
+
+		if (intformat == GL_LUMINANCE8 && pixformat == GL_LUMINANCE && pixtype == GL_UNSIGNED_BYTE) 
+		{ //GL_LUMINANCE_ALPHA is deprecated, convert to RGB
+			use_scratch = true;
+			scratch = new U32[width*height];
+
+			U32 pixel_count = (U32) (width*height);
+			for (U32 i = 0; i < pixel_count; i++)
+			{
+				U8 lum = ((U8*) pixels)[i];
+				
+				U8* pix = (U8*) &scratch[i];
+				pix[0] = pix[1] = pix[2] = lum;
+				pix[3] = 255;
+			}				
+			
+			pixformat = GL_RGBA;
+			intformat = GL_RGB8;
+		}
+	}
+
 	stop_glerror();
+	glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
+	stop_glerror();
+
+	if (use_scratch)
+	{
+		delete [] scratch;
+	}
 }
 
 //create an empty GL texture: just create a texture name
@@ -1167,29 +1247,29 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
 	{
 		switch (mComponents)
 		{
-		  case 1:
+			case 1:
 			// Use luminance alpha (for fonts)
 			mFormatInternal = GL_LUMINANCE8;
 			mFormatPrimary = GL_LUMINANCE;
 			mFormatType = GL_UNSIGNED_BYTE;
 			break;
-		  case 2:
+			case 2:
 			// Use luminance alpha (for fonts)
 			mFormatInternal = GL_LUMINANCE8_ALPHA8;
 			mFormatPrimary = GL_LUMINANCE_ALPHA;
 			mFormatType = GL_UNSIGNED_BYTE;
 			break;
-		  case 3:
+			case 3:
 			mFormatInternal = GL_RGB8;
 			mFormatPrimary = GL_RGB;
 			mFormatType = GL_UNSIGNED_BYTE;
 			break;
-		  case 4:
+			case 4:
 			mFormatInternal = GL_RGBA8;
 			mFormatPrimary = GL_RGBA;
 			mFormatType = GL_UNSIGNED_BYTE;
 			break;
-		  default:
+			default:
 			llerrs << "Bad number of components for texture: " << (U32)getComponents() << llendl;
 		}
 
@@ -1212,6 +1292,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
 BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename)
 {
 	llassert(data_in);
+	stop_glerror();
 
 	if (discard_level < 0)
 	{
@@ -1240,8 +1321,11 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
 		stop_glerror();
 		{
 			llverify(gGL.getTexUnit(0)->bind(this));
+			stop_glerror();
 			glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0);
+			stop_glerror();
 			glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL,  mMaxDiscardLevel-discard_level);
+			stop_glerror();
 		}
 	}
 	if (!mTexName)
diff --git a/indra/llrender/llpostprocess.cpp b/indra/llrender/llpostprocess.cpp
index d76b2d90048a67b55e4feb03909c40e1bb7de6d2..c0045c80447bd22dd940d9ae39a149c558f8261e 100644
--- a/indra/llrender/llpostprocess.cpp
+++ b/indra/llrender/llpostprocess.cpp
@@ -466,21 +466,21 @@ void LLPostProcess::drawOrthoQuad(unsigned int width, unsigned int height, QuadT
 
 void LLPostProcess::viewOrthogonal(unsigned int width, unsigned int height)
 {
-	glMatrixMode(GL_PROJECTION);
-	glPushMatrix();
-	glLoadIdentity();
-	glOrtho( 0.f, (GLdouble) width , (GLdouble) height , 0.f, -1.f, 1.f );
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
-	glLoadIdentity();
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.pushMatrix();
+	gGL.loadIdentity();
+	gGL.ortho( 0.f, (GLdouble) width , (GLdouble) height , 0.f, -1.f, 1.f );
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.pushMatrix();
+	gGL.loadIdentity();
 }
 
 void LLPostProcess::viewPerspective(void)
 {
-	glMatrixMode( GL_PROJECTION );
-	glPopMatrix();
-	glMatrixMode( GL_MODELVIEW );
-	glPopMatrix();
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.popMatrix();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.popMatrix();
 }
 
 void LLPostProcess::changeOrthogonal(unsigned int width, unsigned int height)
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index edcc47aa1471ab65ddd90506c0c562e3c2c0d1c2..afb19fce55a9d8f53637176669f6ec93513743b5 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -1,4 +1,4 @@
-/** 
+ /** 
  * @file llrender.cpp
  * @brief LLRender implementation
  *
@@ -34,19 +34,21 @@
 #include "llimagegl.h"
 #include "llrendertarget.h"
 #include "lltexture.h"
+#include "llshadermgr.h"
 
 LLRender gGL;
 
 // Handy copies of last good GL matrices
-F64	gGLModelView[16];
-F64	gGLLastModelView[16];
-F64 gGLLastProjection[16];
-F64 gGLProjection[16];
+F32	gGLModelView[16];
+F32	gGLLastModelView[16];
+F32 gGLLastProjection[16];
+F32 gGLProjection[16];
 S32	gGLViewport[4];
 
 U32 LLRender::sUICalls = 0;
 U32 LLRender::sUIVerts = 0;
 U32 LLTexUnit::sWhiteTexture = 0;
+bool LLRender::sGLCoreProfile = false;
 
 static const U32 LL_NUM_TEXTURE_LAYERS = 32; 
 static const U32 LL_NUM_LIGHT_UNITS = 8;
@@ -178,10 +180,13 @@ void LLTexUnit::enable(eTextureType type)
 
 	if ( (mCurrTexType != type || gGL.mDirty) && (type != TT_NONE) )
 	{
+		stop_glerror();
 		activate();
+		stop_glerror();
 		if (mCurrTexType != TT_NONE && !gGL.mDirty)
 		{
 			disable(); // Force a disable of a previous texture type if it's enabled.
+			stop_glerror();
 		}
 		mCurrTexType = type;
 
@@ -190,7 +195,9 @@ void LLTexUnit::enable(eTextureType type)
 			type != LLTexUnit::TT_MULTISAMPLE_TEXTURE &&
 			mIndex < gGLManager.mNumTextureUnits)
 		{
+			stop_glerror();
 			glEnable(sGLTextureType[type]);
+			stop_glerror();
 		}
 	}
 }
@@ -286,26 +293,35 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind)
 		{
 			return bind(LLImageGL::sDefaultGLTexture) ;
 		}
+		stop_glerror();
 		return false ;
 	}
 
 	if ((mCurrTexture != texture->getTexName()) || forceBind)
 	{
 		gGL.flush();
+		stop_glerror();
 		activate();
+		stop_glerror();
 		enable(texture->getTarget());
+		stop_glerror();
 		mCurrTexture = texture->getTexName();
 		glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture);
+		stop_glerror();
 		texture->updateBindStats(texture->mTextureMemory);		
 		mHasMipMaps = texture->mHasMipMaps;
 		if (texture->mTexOptionsDirty)
 		{
+			stop_glerror();
 			texture->mTexOptionsDirty = false;
 			setTextureAddressMode(texture->mAddressMode);
 			setTextureFilteringOption(texture->mFilterOption);
+			stop_glerror();
 		}
 	}
 
+	stop_glerror();
+
 	return true;
 }
 
@@ -814,14 +830,16 @@ LLLightState::LLLightState(S32 index)
 	mAmbient.set(0,0,0,1);
 	mPosition.set(0,0,1,0);
 	mSpotDirection.set(0,0,-1);
-
 }
 
 void LLLightState::enable()
 {
 	if (!mEnabled)
 	{
-		glEnable(GL_LIGHT0+mIndex);
+		if (!LLGLSLShader::sNoFixedFunction)
+		{
+			glEnable(GL_LIGHT0+mIndex);
+		}
 		mEnabled = true;
 	}
 }
@@ -830,7 +848,10 @@ void LLLightState::disable()
 {
 	if (mEnabled)
 	{
-		glDisable(GL_LIGHT0+mIndex);
+		if (!LLGLSLShader::sNoFixedFunction)
+		{
+			glDisable(GL_LIGHT0+mIndex);
+		}
 		mEnabled = false;
 	}
 }
@@ -839,8 +860,12 @@ void LLLightState::setDiffuse(const LLColor4& diffuse)
 {
 	if (mDiffuse != diffuse)
 	{
+		++gGL.mLightHash;
 		mDiffuse = diffuse;
-		glLightfv(GL_LIGHT0+mIndex, GL_DIFFUSE, mDiffuse.mV);
+		if (!LLGLSLShader::sNoFixedFunction)
+		{
+			glLightfv(GL_LIGHT0+mIndex, GL_DIFFUSE, mDiffuse.mV);
+		}
 	}
 }
 
@@ -848,8 +873,12 @@ void LLLightState::setAmbient(const LLColor4& ambient)
 {
 	if (mAmbient != ambient)
 	{
+		++gGL.mLightHash;
 		mAmbient = ambient;
-		glLightfv(GL_LIGHT0+mIndex, GL_AMBIENT, mAmbient.mV);
+		if (!LLGLSLShader::sNoFixedFunction)
+		{
+			glLightfv(GL_LIGHT0+mIndex, GL_AMBIENT, mAmbient.mV);
+		}
 	}
 }
 
@@ -857,16 +886,34 @@ void LLLightState::setSpecular(const LLColor4& specular)
 {
 	if (mSpecular != specular)
 	{
+		++gGL.mLightHash;
 		mSpecular = specular;
-		glLightfv(GL_LIGHT0+mIndex, GL_SPECULAR, mSpecular.mV);
+		if (!LLGLSLShader::sNoFixedFunction)
+		{
+			glLightfv(GL_LIGHT0+mIndex, GL_SPECULAR, mSpecular.mV);
+		}
 	}
 }
 
 void LLLightState::setPosition(const LLVector4& position)
 {
 	//always set position because modelview matrix may have changed
+	++gGL.mLightHash;
 	mPosition = position;
-	glLightfv(GL_LIGHT0+mIndex, GL_POSITION, mPosition.mV);
+	if (!LLGLSLShader::sNoFixedFunction)
+	{
+		glLightfv(GL_LIGHT0+mIndex, GL_POSITION, mPosition.mV);
+	}
+	else
+	{ //transform position by current modelview matrix
+		glh::vec4f pos(position.mV);
+
+		const glh::matrix4f& mat = gGL.getModelviewMatrix();
+		mat.mult_matrix_vec(pos);
+
+		mPosition.set(pos.v);
+	}
+
 }
 
 void LLLightState::setConstantAttenuation(const F32& atten)
@@ -874,7 +921,11 @@ void LLLightState::setConstantAttenuation(const F32& atten)
 	if (mConstantAtten != atten)
 	{
 		mConstantAtten = atten;
-		glLightf(GL_LIGHT0+mIndex, GL_CONSTANT_ATTENUATION, atten);
+		++gGL.mLightHash;
+		if (!LLGLSLShader::sNoFixedFunction)
+		{
+			glLightf(GL_LIGHT0+mIndex, GL_CONSTANT_ATTENUATION, atten);
+		}
 	}
 }
 
@@ -882,8 +933,12 @@ void LLLightState::setLinearAttenuation(const F32& atten)
 {
 	if (mLinearAtten != atten)
 	{
+		++gGL.mLightHash;
 		mLinearAtten = atten;
-		glLightf(GL_LIGHT0+mIndex, GL_LINEAR_ATTENUATION, atten);
+		if (!LLGLSLShader::sNoFixedFunction)
+		{
+			glLightf(GL_LIGHT0+mIndex, GL_LINEAR_ATTENUATION, atten);
+		}
 	}
 }
 
@@ -891,8 +946,12 @@ void LLLightState::setQuadraticAttenuation(const F32& atten)
 {
 	if (mQuadraticAtten != atten)
 	{
+		++gGL.mLightHash;
 		mQuadraticAtten = atten;
-		glLightf(GL_LIGHT0+mIndex, GL_QUADRATIC_ATTENUATION, atten);
+		if (!LLGLSLShader::sNoFixedFunction)
+		{
+			glLightf(GL_LIGHT0+mIndex, GL_QUADRATIC_ATTENUATION, atten);
+		}
 	}
 }
 
@@ -900,8 +959,12 @@ void LLLightState::setSpotExponent(const F32& exponent)
 {
 	if (mSpotExponent != exponent)
 	{
+		++gGL.mLightHash;
 		mSpotExponent = exponent;
-		glLightf(GL_LIGHT0+mIndex, GL_SPOT_EXPONENT, exponent);
+		if (!LLGLSLShader::sNoFixedFunction)
+		{
+			glLightf(GL_LIGHT0+mIndex, GL_SPOT_EXPONENT, exponent);
+		}
 	}
 }
 
@@ -909,21 +972,39 @@ void LLLightState::setSpotCutoff(const F32& cutoff)
 {
 	if (mSpotCutoff != cutoff)
 	{
+		++gGL.mLightHash;
 		mSpotCutoff = cutoff;
-		glLightf(GL_LIGHT0+mIndex, GL_SPOT_CUTOFF, cutoff);
+		if (!LLGLSLShader::sNoFixedFunction)
+		{
+			glLightf(GL_LIGHT0+mIndex, GL_SPOT_CUTOFF, cutoff);
+		}
 	}
 }
 
 void LLLightState::setSpotDirection(const LLVector3& direction)
 {
 	//always set direction because modelview matrix may have changed
+	++gGL.mLightHash;
 	mSpotDirection = direction;
-	glLightfv(GL_LIGHT0+mIndex, GL_SPOT_DIRECTION, direction.mV);
+	if (!LLGLSLShader::sNoFixedFunction)
+	{
+		glLightfv(GL_LIGHT0+mIndex, GL_SPOT_DIRECTION, direction.mV);
+	}
+	else
+	{ //transform direction by current modelview matrix
+		glh::vec3f dir(direction.mV);
+
+		const glh::matrix4f& mat = gGL.getModelviewMatrix();
+		mat.mult_matrix_dir(dir);
+
+		mSpotDirection.set(direction);
+	}
 }
 
 LLRender::LLRender()
   : mDirty(false),
     mCount(0),
+	mQuadCycle(0),
     mMode(LLRender::TRIANGLES),
     mCurrTextureUnitIndex(0),
     mMaxAnisotropy(0.f) 
@@ -951,6 +1032,17 @@ LLRender::LLRender()
 	mCurrBlendAlphaSFactor = BF_UNDEF;
 	mCurrBlendColorDFactor = BF_UNDEF;
 	mCurrBlendAlphaDFactor = BF_UNDEF;
+
+	mMatrixMode = LLRender::MM_MODELVIEW;
+	
+	for (U32 i = 0; i < NUM_MATRIX_MODES; ++i)
+	{
+		mMatIdx[i] = 0;
+		mMatHash[i] = 0;
+		mCurMatHash[i] = 0xFFFFFFFF;
+	}
+
+	mLightHash = 0;
 }
 
 LLRender::~LLRender()
@@ -961,12 +1053,13 @@ LLRender::~LLRender()
 void LLRender::init()
 {
 	llassert_always(mBuffer.isNull()) ;
-
+	stop_glerror();
 	mBuffer = new LLVertexBuffer(immediate_mask, 0);
 	mBuffer->allocateBuffer(4096, 0, TRUE);
 	mBuffer->getVertexStrider(mVerticesp);
 	mBuffer->getTexCoord0Strider(mTexcoordsp);
 	mBuffer->getColorStrider(mColorsp);
+	stop_glerror();
 }
 
 void LLRender::shutdown()
@@ -1007,28 +1100,348 @@ void LLRender::refreshState(void)
 	mDirty = false;
 }
 
+void LLRender::syncLightState()
+{
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+
+	if (!shader)
+	{
+		return;
+	}
+
+	if (shader->mLightHash != mLightHash)
+	{
+		shader->mLightHash = mLightHash;
+
+		LLVector4 position[8];
+		LLVector3 direction[8];
+		LLVector3 attenuation[8];
+		LLVector3 diffuse[8];
+
+		for (U32 i = 0; i < 8; i++)
+		{
+			LLLightState* light = mLightState[i];
+
+			position[i] = light->mPosition;
+			direction[i] = light->mSpotDirection;
+			attenuation[i].set(light->mLinearAtten, light->mQuadraticAtten, light->mSpecular.mV[3]);
+			diffuse[i].set(light->mDiffuse.mV);
+		}
+
+		shader->uniform4fv(LLShaderMgr::LIGHT_POSITION, 8, position[0].mV);
+		shader->uniform3fv(LLShaderMgr::LIGHT_DIRECTION, 8, direction[0].mV);
+		shader->uniform3fv(LLShaderMgr::LIGHT_ATTENUATION, 8, attenuation[0].mV);
+		shader->uniform3fv(LLShaderMgr::LIGHT_DIFFUSE, 8, diffuse[0].mV);
+		shader->uniform4fv(LLShaderMgr::LIGHT_AMBIENT, 1, mAmbientLightColor.mV);
+		//HACK -- duplicate sunlight color for compatibility with drivers that can't deal with multiple shader objects referencing the same uniform
+		shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, 1, diffuse[0].mV);
+	}
+}
+
+void LLRender::syncMatrices()
+{
+	stop_glerror();
+
+	GLenum mode[] = 
+	{
+		GL_MODELVIEW,
+		GL_PROJECTION,
+		GL_TEXTURE,
+		GL_TEXTURE,
+		GL_TEXTURE,
+		GL_TEXTURE,
+	};
+
+	U32 name[] = 
+	{
+		LLShaderMgr::MODELVIEW_MATRIX,
+		LLShaderMgr::PROJECTION_MATRIX,
+		LLShaderMgr::TEXTURE_MATRIX0,
+		LLShaderMgr::TEXTURE_MATRIX1,
+		LLShaderMgr::TEXTURE_MATRIX2,
+		LLShaderMgr::TEXTURE_MATRIX3,
+	};
+
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+
+	static glh::matrix4f cached_mvp;
+	static U32 cached_mvp_mdv_hash = 0xFFFFFFFF;
+	static U32 cached_mvp_proj_hash = 0xFFFFFFFF;
+	
+	static glh::matrix4f cached_normal;
+	static U32 cached_normal_hash = 0xFFFFFFFF;
+
+	if (shader)
+	{
+		llassert(shader);
+
+		bool mvp_done = false;
+
+		U32 i = MM_MODELVIEW;
+		if (mMatHash[i] != shader->mMatHash[i])
+		{ //update modelview, normal, and MVP
+			glh::matrix4f& mat = mMatrix[i][mMatIdx[i]];
+
+			shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mat.m);
+			shader->mMatHash[i] = mMatHash[i];
+
+			//update normal matrix
+			S32 loc = shader->getUniformLocation(LLShaderMgr::NORMAL_MATRIX);
+			if (loc > -1)
+			{
+				if (cached_normal_hash != mMatHash[i])
+				{
+					cached_normal = mat.inverse().transpose();
+					cached_normal_hash = mMatHash[i];
+				}
+
+				glh::matrix4f& norm = cached_normal;
+
+				F32 norm_mat[] = 
+				{
+					norm.m[0], norm.m[1], norm.m[2],
+					norm.m[4], norm.m[5], norm.m[6],
+					norm.m[8], norm.m[9], norm.m[10] 
+				};
+
+				shader->uniformMatrix3fv(LLShaderMgr::NORMAL_MATRIX, 1, GL_FALSE, norm_mat);
+			}
+
+			//update MVP matrix
+			mvp_done = true;
+			loc = shader->getUniformLocation(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX);
+			if (loc > -1)
+			{
+				U32 proj = MM_PROJECTION;
+
+				if (cached_mvp_mdv_hash != mMatHash[i] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION])
+				{
+					cached_mvp = mat;
+					cached_mvp.mult_left(mMatrix[proj][mMatIdx[proj]]);
+					cached_mvp_mdv_hash = mMatHash[i];
+					cached_mvp_proj_hash = mMatHash[MM_PROJECTION];
+				}
+
+				shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.m);
+			}
+		}
+
+
+		i = MM_PROJECTION;
+		if (mMatHash[i] != shader->mMatHash[i])
+		{ //update projection matrix, normal, and MVP
+			glh::matrix4f& mat = mMatrix[i][mMatIdx[i]];
+
+			shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mat.m);
+			shader->mMatHash[i] = mMatHash[i];
+
+			if (!mvp_done)
+			{
+				//update MVP matrix
+				S32 loc = shader->getUniformLocation(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX);
+				if (loc > -1)
+				{
+					if (cached_mvp_mdv_hash != mMatHash[i] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION])
+					{
+						U32 mdv = MM_MODELVIEW;
+						cached_mvp = mat;
+						cached_mvp.mult_right(mMatrix[mdv][mMatIdx[mdv]]);
+						cached_mvp_mdv_hash = mMatHash[MM_MODELVIEW];
+						cached_mvp_proj_hash = mMatHash[MM_PROJECTION];
+					}
+									
+					shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.m);
+				}
+			}
+		}
+
+		for (i = MM_TEXTURE0; i < NUM_MATRIX_MODES; ++i)
+		{
+			if (mMatHash[i] != shader->mMatHash[i])
+			{
+				shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mMatrix[i][mMatIdx[i]].m);
+				shader->mMatHash[i] = mMatHash[i];
+			}
+		}
+
+
+		if (shader->mFeatures.hasLighting || shader->mFeatures.calculatesLighting)
+		{ //also sync light state
+			syncLightState();
+		}
+	}
+	else if (!LLGLSLShader::sNoFixedFunction)
+	{
+		for (U32 i = 0; i < 2; ++i)
+		{
+			if (mMatHash[i] != mCurMatHash[i])
+			{
+				glMatrixMode(mode[i]);
+				glLoadMatrixf(mMatrix[i][mMatIdx[i]].m);
+				mCurMatHash[i] = mMatHash[i];
+			}
+		}
+
+		for (U32 i = 2; i < NUM_MATRIX_MODES; ++i)
+		{
+			if (mMatHash[i] != mCurMatHash[i])
+			{
+				gGL.getTexUnit(i-2)->activate();
+				glMatrixMode(mode[i]);
+				glLoadMatrixf(mMatrix[i][mMatIdx[i]].m);
+				mCurMatHash[i] = mMatHash[i];
+			}
+		}
+	}
+
+	stop_glerror();
+}
+
 void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
 {
 	flush();
-	glTranslatef(x,y,z);
+
+	{
+		glh::matrix4f trans_mat(1,0,0,x,
+								0,1,0,y,
+								0,0,1,z,
+								0,0,0,1);
+	
+		mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(trans_mat);
+		mMatHash[mMatrixMode]++;
+	}
 }
 
 void LLRender::scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
 {
 	flush();
-	glScalef(x,y,z);
+	
+	{
+		glh::matrix4f scale_mat(x,0,0,0,
+								0,y,0,0,
+								0,0,z,0,
+								0,0,0,1);
+	
+		mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(scale_mat);
+		mMatHash[mMatrixMode]++;
+	}
+}
+
+void LLRender::ortho(F32 left, F32 right, F32 bottom, F32 top, F32 zNear, F32 zFar)
+{
+	flush();
+
+	{
+
+		glh::matrix4f ortho_mat(2.f/(right-left),0,0,	-(right+left)/(right-left),
+								0,2.f/(top-bottom),0,	-(top+bottom)/(top-bottom),
+								0,0,-2.f/(zFar-zNear),	-(zFar+zNear)/(zFar-zNear),
+								0,0,0,1);
+	
+		mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(ortho_mat);
+		mMatHash[mMatrixMode]++;
+	}
+}
+
+void LLRender::rotatef(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z)
+{
+	flush();
+
+	{
+		F32 r = a * DEG_TO_RAD;
+
+		F32 c = cosf(r);
+		F32 s = sinf(r);
+
+		F32 ic = 1.f-c;
+
+		glh::matrix4f rot_mat(x*x*ic+c,		x*y*ic-z*s,		x*z*ic+y*s,		0,
+							  x*y*ic+z*s,	y*y*ic+c,		y*z*ic-x*s,		0,
+							  x*z*ic-y*s,	y*z*ic+x*s,		z*z*ic+c,		0,
+							  0,0,0,1);
+	
+		mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(rot_mat);
+		mMatHash[mMatrixMode]++;
+	}
 }
 
 void LLRender::pushMatrix()
 {
 	flush();
-	glPushMatrix();
+	
+	{
+		if (mMatIdx[mMatrixMode] < LL_MATRIX_STACK_DEPTH-1)
+		{
+			mMatrix[mMatrixMode][mMatIdx[mMatrixMode]+1] = mMatrix[mMatrixMode][mMatIdx[mMatrixMode]];
+			++mMatIdx[mMatrixMode];
+		}
+		else
+		{
+			llwarns << "Matrix stack overflow." << llendl;
+		}
+	}
 }
 
 void LLRender::popMatrix()
 {
 	flush();
-	glPopMatrix();
+	{
+		if (mMatIdx[mMatrixMode] > 0)
+		{
+			--mMatIdx[mMatrixMode];
+			mMatHash[mMatrixMode]++;
+		}
+		else
+		{
+			llwarns << "Matrix stack underflow." << llendl;
+		}
+	}
+}
+
+void LLRender::loadMatrix(const GLfloat* m)
+{
+	flush();
+	{
+		mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].set_value((GLfloat*) m);
+		mMatHash[mMatrixMode]++;
+	}
+}
+
+void LLRender::multMatrix(const GLfloat* m)
+{
+	flush();
+	{
+		glh::matrix4f mat((GLfloat*) m);
+	
+		mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(mat);
+		mMatHash[mMatrixMode]++;
+	}
+}
+
+void LLRender::matrixMode(U32 mode)
+{
+	if (mode == MM_TEXTURE)
+	{
+		mode = MM_TEXTURE0 + gGL.getCurrentTexUnitIndex();
+	}
+
+	llassert(mode < NUM_MATRIX_MODES);
+	mMatrixMode = mode;
+}
+
+void LLRender::loadIdentity()
+{
+	flush();
+
+	{
+		mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].make_identity();
+		mMatHash[mMatrixMode]++;
+	}
+}
+
+const glh::matrix4f& LLRender::getModelviewMatrix()
+{
+	return mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]];
 }
 
 void LLRender::translateUI(F32 x, F32 y, F32 z)
@@ -1284,6 +1697,19 @@ LLLightState* LLRender::getLight(U32 index)
 	return NULL;
 }
 
+void LLRender::setAmbientLightColor(const LLColor4& color)
+{
+	if (color != mAmbientLightColor)
+	{
+		++mLightHash;
+		mAmbientLightColor = color;
+		if (!LLGLSLShader::sNoFixedFunction)
+		{
+			glLightModelfv(GL_LIGHT_MODEL_AMBIENT, color.mV);
+		}
+	}
+}
+
 bool LLRender::verifyTexUnitActive(U32 unitToVerify)
 {
 	if (mCurrTextureUnitIndex == unitToVerify)
@@ -1309,6 +1735,11 @@ void LLRender::begin(const GLuint& mode)
 {
 	if (mode != mMode)
 	{
+		if (mode == LLRender::QUADS)
+		{
+			mQuadCycle = 1;
+		}
+
 		if (mMode == LLRender::QUADS ||
 			mMode == LLRender::LINES ||
 			mMode == LLRender::TRIANGLES ||
@@ -1396,7 +1827,7 @@ void LLRender::flush()
 		
 		if (gDebugGL)
 		{
-			if (mMode == LLRender::QUADS)
+			if (mMode == LLRender::QUADS && !sGLCoreProfile)
 			{
 				if (mCount%4 != 0)
 				{
@@ -1421,12 +1852,34 @@ void LLRender::flush()
 			}
 		}
 
+		//store mCount in a local variable to avoid re-entrance (drawArrays may call flush)
+		U32 count = mCount;
+		mCount = 0;
+
+		if (mBuffer->useVBOs() && !mBuffer->isLocked())
+		{ //hack to only flush the part of the buffer that was updated (relies on stream draw using buffersubdata)
+			mBuffer->getVertexStrider(mVerticesp, 0, count);
+			mBuffer->getTexCoord0Strider(mTexcoordsp, 0, count);
+			mBuffer->getColorStrider(mColorsp, 0, count);
+		}
+		
+		mBuffer->flush();
 		mBuffer->setBuffer(immediate_mask);
-		mBuffer->drawArrays(mMode, 0, mCount);
+
+		if (mMode == LLRender::QUADS && sGLCoreProfile)
+		{
+			mBuffer->drawArrays(LLRender::TRIANGLES, 0, count);
+			mQuadCycle = 1;
+		}
+		else
+		{
+			mBuffer->drawArrays(mMode, 0, count);
+		}
+		
+		mVerticesp[0] = mVerticesp[count];
+		mTexcoordsp[0] = mTexcoordsp[count];
+		mColorsp[0] = mColorsp[count];
 		
-		mVerticesp[0] = mVerticesp[mCount];
-		mTexcoordsp[0] = mTexcoordsp[mCount];
-		mColorsp[0] = mColorsp[mCount];
 		mCount = 0;
 	}
 }
@@ -1450,10 +1903,29 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
 		mVerticesp[mCount] = vert;
 	}
 
+	if (mMode == LLRender::QUADS && LLRender::sGLCoreProfile)
+	{
+		mQuadCycle++;
+		if (mQuadCycle == 4)
+		{ //copy two vertices so fourth quad element will add a triangle
+			mQuadCycle = 0;
+	
+			mCount++;
+			mVerticesp[mCount] = mVerticesp[mCount-3];
+			mColorsp[mCount] = mColorsp[mCount-3];
+			mTexcoordsp[mCount] = mTexcoordsp[mCount-3];
+
+			mCount++;
+			mVerticesp[mCount] = mVerticesp[mCount-2];
+			mColorsp[mCount] = mColorsp[mCount-2];
+			mTexcoordsp[mCount] = mTexcoordsp[mCount-2];
+		}
+	}
+
 	mCount++;
 	mVerticesp[mCount] = mVerticesp[mCount-1];
 	mColorsp[mCount] = mColorsp[mCount-1];
-	mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+	mTexcoordsp[mCount] = mTexcoordsp[mCount-1];	
 }
 
 void LLRender::vertexBatchPreTransformed(LLVector3* verts, S32 vert_count)
@@ -1464,13 +1936,50 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, S32 vert_count)
 		return;
 	}
 
-	for (S32 i = 0; i < vert_count; i++)
+	if (sGLCoreProfile && mMode == LLRender::QUADS)
+	{ //quads are deprecated, convert to triangle list
+		S32 i = 0;
+		
+		while (i < vert_count)
+		{
+			//read first three
+			mVerticesp[mCount++] = verts[i++];
+			mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+			mColorsp[mCount] = mColorsp[mCount-1];
+
+			mVerticesp[mCount++] = verts[i++];
+			mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+			mColorsp[mCount] = mColorsp[mCount-1];
+
+			mVerticesp[mCount++] = verts[i++];
+			mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+			mColorsp[mCount] = mColorsp[mCount-1];
+
+			//copy two
+			mVerticesp[mCount++] = verts[i-3];
+			mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+			mColorsp[mCount] = mColorsp[mCount-1];
+
+			mVerticesp[mCount++] = verts[i-1];
+			mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+			mColorsp[mCount] = mColorsp[mCount-1];
+			
+			//copy last one
+			mVerticesp[mCount++] = verts[i++];
+			mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+			mColorsp[mCount] = mColorsp[mCount-1];
+		}
+	}
+	else
 	{
-		mVerticesp[mCount] = verts[i];
+		for (S32 i = 0; i < vert_count; i++)
+		{
+			mVerticesp[mCount] = verts[i];
 
-		mCount++;
-		mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
-		mColorsp[mCount] = mColorsp[mCount-1];
+			mCount++;
+			mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+			mColorsp[mCount] = mColorsp[mCount-1];
+		}
 	}
 
 	mVerticesp[mCount] = mVerticesp[mCount-1];
@@ -1484,13 +1993,50 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 v
 		return;
 	}
 
-	for (S32 i = 0; i < vert_count; i++)
+	if (sGLCoreProfile && mMode == LLRender::QUADS)
+	{ //quads are deprecated, convert to triangle list
+		S32 i = 0;
+
+		while (i < vert_count)
+		{
+			//read first three
+			mVerticesp[mCount] = verts[i];
+			mTexcoordsp[mCount++] = uvs[i++];
+			mColorsp[mCount] = mColorsp[mCount-1];
+
+			mVerticesp[mCount] = verts[i];
+			mTexcoordsp[mCount++] = uvs[i++];
+			mColorsp[mCount] = mColorsp[mCount-1];
+
+			mVerticesp[mCount] = verts[i];
+			mTexcoordsp[mCount++] = uvs[i++];
+			mColorsp[mCount] = mColorsp[mCount-1];
+
+			//copy last two
+			mVerticesp[mCount] = verts[i-3];
+			mTexcoordsp[mCount++] = uvs[i-3];
+			mColorsp[mCount] = mColorsp[mCount-1];
+
+			mVerticesp[mCount] = verts[i-1];
+			mTexcoordsp[mCount++] = uvs[i-1];
+			mColorsp[mCount] = mColorsp[mCount-1];
+
+			//copy last one
+			mVerticesp[mCount] = verts[i];
+			mTexcoordsp[mCount++] = uvs[i++];
+			mColorsp[mCount] = mColorsp[mCount-1];
+		}
+	}
+	else
 	{
-		mVerticesp[mCount] = verts[i];
-		mTexcoordsp[mCount] = uvs[i];
+		for (S32 i = 0; i < vert_count; i++)
+		{
+			mVerticesp[mCount] = verts[i];
+			mTexcoordsp[mCount] = uvs[i];
 
-		mCount++;
-		mColorsp[mCount] = mColorsp[mCount-1];
+			mCount++;
+			mColorsp[mCount] = mColorsp[mCount-1];
+		}
 	}
 
 	mVerticesp[mCount] = mVerticesp[mCount-1];
@@ -1505,13 +2051,51 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLCol
 		return;
 	}
 
-	for (S32 i = 0; i < vert_count; i++)
+	
+	if (sGLCoreProfile && mMode == LLRender::QUADS)
+	{ //quads are deprecated, convert to triangle list
+		S32 i = 0;
+
+		while (i < vert_count)
+		{
+			//read first three
+			mVerticesp[mCount] = verts[i];
+			mTexcoordsp[mCount] = uvs[i];
+			mColorsp[mCount++] = colors[i++];
+
+			mVerticesp[mCount] = verts[i];
+			mTexcoordsp[mCount] = uvs[i];
+			mColorsp[mCount++] = colors[i++];
+
+			mVerticesp[mCount] = verts[i];
+			mTexcoordsp[mCount] = uvs[i];
+			mColorsp[mCount++] = colors[i++];
+
+			//copy last two
+			mVerticesp[mCount] = verts[i-3];
+			mTexcoordsp[mCount] = uvs[i-3];
+			mColorsp[mCount++] = colors[i-3];
+
+			mVerticesp[mCount] = verts[i-1];
+			mTexcoordsp[mCount] = uvs[i-1];
+			mColorsp[mCount++] = colors[i-1];
+
+			//copy last one
+			mVerticesp[mCount] = verts[i];
+			mTexcoordsp[mCount] = uvs[i];
+			mColorsp[mCount++] = colors[i++];
+		}
+	}
+	else
 	{
-		mVerticesp[mCount] = verts[i];
-		mTexcoordsp[mCount] = uvs[i];
-		mColorsp[mCount] = colors[i];
+		for (S32 i = 0; i < vert_count; i++)
+		{
+			mVerticesp[mCount] = verts[i];
+			mTexcoordsp[mCount] = uvs[i];
+			mColorsp[mCount] = colors[i];
 
-		mCount++;
+			mCount++;
+		}
 	}
 
 	mVerticesp[mCount] = mVerticesp[mCount-1];
@@ -1586,6 +2170,81 @@ 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;
+	llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
+
+	if (shader)
+	{
+		shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r,g,b,1.f);
+	}
+	else
+	{
+		glColor3f(r,g,b);
+	}
+}
+
+void LLRender::diffuseColor3fv(const F32* c)
+{
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+	llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
+
+	if (shader)
+	{
+		shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, c[0], c[1], c[2], 1.f);
+	}
+	else
+	{
+		glColor3fv(c);
+	}
+}
+
+void LLRender::diffuseColor4f(F32 r, F32 g, F32 b, F32 a)
+{
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+	llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
+
+	if (shader)
+	{
+		shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r,g,b,a);
+	}
+	else
+	{
+		glColor4f(r,g,b,a);
+	}
+}
+
+void LLRender::diffuseColor4fv(const F32* c)
+{
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+	llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
+
+	if (shader)
+	{
+		shader->uniform4fv(LLShaderMgr::DIFFUSE_COLOR, 1, c);
+	}
+	else
+	{
+		glColor4fv(c);
+	}
+}
+
+void LLRender::diffuseColor4ubv(const U8* c)
+{
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+	llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
+
+	if (shader)
+	{
+		shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, c[0]/255.f, c[1]/255.f, c[2]/255.f, c[3]/255.f);
+	}
+	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 8f7ee30d87e53f704387e232be8dd9ca731a556d..7581b9f9086044b19cdc63f03043e3e3ddbd5c83 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -41,6 +41,8 @@
 #include "llstrider.h"
 #include "llpointer.h"
 #include "llglheaders.h"
+#include "llmatrix4a.h"
+#include "glh/glh_linear.h"
 
 class LLVertexBuffer;
 class LLCubeMap;
@@ -48,6 +50,8 @@ class LLImageGL;
 class LLRenderTarget;
 class LLTexture ;
 
+#define LL_MATRIX_STACK_DEPTH 32
+
 class LLTexUnit
 {
 	friend class LLRender;
@@ -235,6 +239,8 @@ class LLLightState
 	void setSpotDirection(const LLVector3& direction);
 
 protected:
+	friend class LLRender;
+
 	S32 mIndex;
 	bool mEnabled;
 	LLColor4 mDiffuse;
@@ -308,6 +314,18 @@ class LLRender
 		BF_UNDEF
 	} eBlendFactor;
 
+	typedef enum
+	{
+		MM_MODELVIEW = 0,
+		MM_PROJECTION,
+		MM_TEXTURE0,
+		MM_TEXTURE1,
+		MM_TEXTURE2,
+		MM_TEXTURE3,
+		NUM_MATRIX_MODES,
+		MM_TEXTURE
+	} eMatrixMode;
+
 	LLRender();
 	~LLRender();
 	void init() ;
@@ -319,8 +337,20 @@ class LLRender
 
 	void translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
 	void scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
+	void rotatef(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z);
+	void ortho(F32 left, F32 right, F32 bottom, F32 top, F32 zNear, F32 zFar);
+
 	void pushMatrix();
 	void popMatrix();
+	void loadMatrix(const GLfloat* m);
+	void loadIdentity();
+	void multMatrix(const GLfloat* m);
+	void matrixMode(U32 mode);	
+
+	const glh::matrix4f& getModelviewMatrix();
+
+	void syncMatrices();
+	void syncLightState();
 
 	void translateUI(F32 x, F32 y, F32 z);
 	void scaleUI(F32 x, F32 y, F32 z);
@@ -351,6 +381,12 @@ class LLRender
 	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);
@@ -368,7 +404,8 @@ class LLRender
 		       eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor);
 
 	LLLightState* getLight(U32 index);
-
+	void setAmbientLightColor(const LLColor4& color);
+	
 	LLTexUnit* getTexUnit(U32 index);
 
 	U32	getCurrentTexUnitIndex(void) const { return mCurrTextureUnitIndex; }
@@ -389,9 +426,21 @@ class LLRender
 public:
 	static U32 sUICalls;
 	static U32 sUIVerts;
+	static bool sGLCoreProfile;
 	
 private:
-	bool				mDirty;
+	friend class LLLightState;
+
+	U32 mMatrixMode;
+	U32 mMatIdx[NUM_MATRIX_MODES];
+	U32 mMatHash[NUM_MATRIX_MODES];
+	glh::matrix4f mMatrix[NUM_MATRIX_MODES][LL_MATRIX_STACK_DEPTH];
+	U32 mCurMatHash[NUM_MATRIX_MODES];
+	U32 mLightHash;
+	LLColor4 mAmbientLightColor;
+	
+	bool			mDirty;
+	U32				mQuadCycle;
 	U32				mCount;
 	U32				mMode;
 	U32				mCurrTextureUnitIndex;
@@ -419,10 +468,10 @@ class LLRender
 
 };
 
-extern F64 gGLModelView[16];
-extern F64 gGLLastModelView[16];
-extern F64 gGLLastProjection[16];
-extern F64 gGLProjection[16];
+extern F32 gGLModelView[16];
+extern F32 gGLLastModelView[16];
+extern F32 gGLLastProjection[16];
+extern F32 gGLProjection[16];
 extern S32 gGLViewport[4];
 
 extern LLRender gGL;
diff --git a/indra/llrender/llrendersphere.cpp b/indra/llrender/llrendersphere.cpp
index a5cd70445f64efb597f0d1f18da11e24a20588ce..26bfe036e88037c8576930c9e93989f0bada344b 100644
--- a/indra/llrender/llrendersphere.cpp
+++ b/indra/llrender/llrendersphere.cpp
@@ -35,106 +35,12 @@
 
 #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();
+	gGL.flush();
 }
 
 inline LLVector3 polar_to_cart(F32 latitude, F32 longitude)
diff --git a/indra/llrender/llrendersphere.h b/indra/llrender/llrendersphere.h
index 96a6bec80c7f708aaea5343f99d57865f8e3998f..f8e9e86e7f7b58bbbd6b6deda191ed8188623eb3 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/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 8c0d3592df9fde28330dbc706d6a70bdf5d5595a..1aa12614ea1415d257f94b6fcda1a53616b8c0f5 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -31,8 +31,7 @@
 #include "llgl.h"
 
 LLRenderTarget* LLRenderTarget::sBoundTarget = NULL;
-
-
+U32 LLRenderTarget::sBytesAllocated = 0;
 
 void check_framebuffer_status()
 {
@@ -62,8 +61,7 @@ LLRenderTarget::LLRenderTarget() :
 	mStencil(0),
 	mUseDepth(false),
 	mRenderDepth(false),
-	mUsage(LLTexUnit::TT_TEXTURE),
-	mSamples(0)
+	mUsage(LLTexUnit::TT_TEXTURE)
 {
 }
 
@@ -84,20 +82,6 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
 	mStencil = stencil;
 	mUsage = usage;
 	mUseDepth = depth;
-	mSamples = samples;
-
-	mSamples = gGLManager.getNumFBOFSAASamples(mSamples);
-	
-	if (mSamples > 1 && gGLManager.mHasTextureMultisample)
-	{
-		mUsage = LLTexUnit::TT_MULTISAMPLE_TEXTURE;
-		//no support for multisampled stencil targets yet
-		mStencil = false;
-	}
-	else
-	{
-		mSamples = 0;
-	}
 
 	if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
 	{
@@ -157,21 +141,6 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
 	stop_glerror();
 
 
-#ifdef GL_ARB_texture_multisample
-	if (mSamples > 1)
-	{
-		clear_glerror();
-		glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, color_fmt, mResX, mResY, GL_TRUE);
-		if (glGetError() != GL_NO_ERROR)
-		{
-			llwarns << "Could not allocate multisample color buffer for render target." << llendl;
-			return false;
-		}
-	}
-	else
-#else
-	llassert_always(mSamples <= 1);
-#endif
 	{
 		clear_glerror();
 		LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
@@ -182,32 +151,32 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
 		}
 	}
 	
+	sBytesAllocated += mResX*mResY*4;
+
 	stop_glerror();
 
-	if (mSamples == 0)
-	{ 
-		if (offset == 0)
-		{ //use bilinear filtering on single texture render targets that aren't multisampled
-			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
-			stop_glerror();
-		}
-		else
-		{ //don't filter data attachments
-			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
-			stop_glerror();
-		}
+	
+	if (offset == 0)
+	{ //use bilinear filtering on single texture render targets that aren't multisampled
+		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
+		stop_glerror();
+	}
+	else
+	{ //don't filter data attachments
+		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+		stop_glerror();
+	}
 
-		if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
-		{
-			gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR);
-			stop_glerror();
-		}
-		else
-		{
-			// ATI doesn't support mirrored repeat for rectangular textures.
-			gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
-			stop_glerror();
-		}
+	if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
+	{
+		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR);
+		stop_glerror();
+	}
+	else
+	{
+		// ATI doesn't support mirrored repeat for rectangular textures.
+		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+		stop_glerror();
 	}
 		
 	if (mFBO)
@@ -250,26 +219,16 @@ bool LLRenderTarget::allocateDepth()
 	{
 		LLImageGL::generateTextures(1, &mDepth);
 		gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
-		if (mSamples == 0)
-		{
-			U32 internal_type = LLTexUnit::getInternalType(mUsage);
-			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
-			stop_glerror();
-			clear_glerror();
-			LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT32, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
-		}
-#ifdef GL_ARB_texture_multisample
-		else
-		{
-			stop_glerror();
-			clear_glerror();
-			glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, GL_DEPTH_COMPONENT32, mResX, mResY, GL_TRUE);
-		}
-#else
-		llassert_always(mSamples <= 1);
-#endif
+		
+		U32 internal_type = LLTexUnit::getInternalType(mUsage);
+		stop_glerror();
+		clear_glerror();
+		LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
+		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
 	}
 
+	sBytesAllocated += mResX*mResY*4;
+
 	if (glGetError() != GL_NO_ERROR)
 	{
 		llwarns << "Unable to allocate depth buffer for render target." << llendl;
@@ -339,14 +298,16 @@ void LLRenderTarget::release()
 			stop_glerror();
 		}
 		mDepth = 0;
+
+		sBytesAllocated -= mResX*mResY*4;
 	}
 	else if (mUseDepth && mFBO)
 	{ //detach shared depth buffer
 		glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
 		if (mStencil)
 		{ //attached as a renderbuffer
-			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
 			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
+			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
 			mStencil = false;
 		}
 		else
@@ -364,6 +325,7 @@ void LLRenderTarget::release()
 
 	if (mTex.size() > 0)
 	{
+		sBytesAllocated -= mResX*mResY*4*mTex.size();
 		LLImageGL::deleteTextures(mTex.size(), &mTex[0], true);
 		mTex.clear();
 	}
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index dea1de12d80953a2f519e337a62b4805bb1fc068..2735ab21c560d2c676f8c2ce1bb28d46f859a40f 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -64,6 +64,7 @@ class LLRenderTarget
 public:
 	//whether or not to use FBO implementation
 	static bool sUseFBO; 
+	static U32 sBytesAllocated;
 
 	LLRenderTarget();
 	~LLRenderTarget();
@@ -147,7 +148,6 @@ class LLRenderTarget
 	bool mUseDepth;
 	bool mRenderDepth;
 	LLTexUnit::eTextureType mUsage;
-	U32 mSamples;
 	
 	static LLRenderTarget* sBoundTarget;
 };
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 986c1f2774dde1f23c6416cad1313d11157e6de7..326c938e8e2d6dad2579e11888e5208a271ad9e5 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -81,7 +81,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 	// NOTE order of shader object attaching is VERY IMPORTANT!!!
 	if (features->calculatesAtmospherics)
 	{
-		if (!shader->attachObject("windlight/atmosphericsVarsV.glsl"))
+		if (features->hasWaterFog)
+		{
+			if (!shader->attachObject("windlight/atmosphericsVarsWaterV.glsl"))
+			{
+				return FALSE;
+			}
+		}
+		else if (!shader->attachObject("windlight/atmosphericsVarsV.glsl"))
 		{
 			return FALSE;
 		}
@@ -161,7 +168,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 
 	if(features->calculatesAtmospherics)
 	{
-		if (!shader->attachObject("windlight/atmosphericsVarsF.glsl"))
+		if (features->hasWaterFog)
+		{
+			if (!shader->attachObject("windlight/atmosphericsVarsWaterF.glsl"))
+			{
+				return FALSE;
+			}
+		}
+		else if (!shader->attachObject("windlight/atmosphericsVarsF.glsl"))
 		{
 			return FALSE;
 		}
@@ -241,7 +255,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 						return FALSE;
 					}
 				}
-				shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
+				shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 			}
 		}
 		
@@ -280,7 +294,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 						return FALSE;
 					}
 				}
-				shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
+				shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 			}
 		}		
 	}
@@ -304,7 +318,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 				{
 					return FALSE;
 				}
-				shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
+				shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 			}
 		}
 		else if (features->hasWaterFog)
@@ -336,7 +350,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 				{
 					return FALSE;
 				}
-				shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
+				shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 			}
 		}
 		
@@ -355,7 +369,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 				{
 					return FALSE;
 				}
-				shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
+				shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 			}
 		}
 		
@@ -395,7 +409,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 						return FALSE;
 					}
 				}
-				shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
+				shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 			}
 		}
 	}
@@ -419,7 +433,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 				{
 					return FALSE;
 				}
-				shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
+				shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 			}
 		}
 		
@@ -438,10 +452,26 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 				{
 					return FALSE;
 				}
-				shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
+				shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 			}
 		}
 	}
+
+	if (features->mIndexedTextureChannels <= 1)
+	{
+		if (!shader->attachObject("objects/nonindexedTextureV.glsl"))
+		{
+			return FALSE;
+		}
+	}
+	else
+	{
+		if (!shader->attachObject("objects/indexedTextureV.glsl"))
+		{
+			return FALSE;
+		}
+	}
+
 	return TRUE;
 }
 
@@ -477,7 +507,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
 		}
 		else
 		{
-			LL_DEBUGS("ShaderLoading") << log << LL_ENDL;
+			LL_INFOS("ShaderLoading") << log << LL_ENDL;
 		}
 	}
  }
@@ -531,23 +561,64 @@ 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)
+	F32 version = gGLManager.mGLVersion;
+
+//hack to never use GLSL > 1.20 on OSX
+#if LL_DARWIN
+	version = llmin(version, 2.9f);
+#endif
+
+	if (version < 2.1f)
 	{
 		text[count++] = strdup("#version 110\n");
+		text[count++] = strdup("#define ATTRIBUTE attribute\n");
+		text[count++] = strdup("#define VARYING varying\n");
 	}
-	else if (gGLManager.mGLVersion < 3.f)
+	else if (version < 3.f)
 	{
 		//set version to 1.20
 		text[count++] = strdup("#version 120\n");
+		text[count++] = strdup("#define FXAA_GLSL_120 1\n");
+		text[count++] = strdup("#define FXAA_FAST_PIXEL_OFFSET 0\n");
+		text[count++] = strdup("#define ATTRIBUTE attribute\n");
+		text[count++] = strdup("#define VARYING varying\n");
 	}
 	else
-	{  //set version to 1.30
-		text[count++] = strdup("#version 130\n");
+	{  
+		if (version < 4.f)
+		{
+			//set version to 1.30
+			text[count++] = strdup("#version 130\n");
+		}
+		else
+		{ //set version to 400
+			text[count++] = strdup("#version 400\n");
+		}
+
+		text[count++] = strdup("#define DEFINE_GL_FRAGCOLOR 1\n");
+		text[count++] = strdup("#define FXAA_GLSL_130 1\n");
+
+		text[count++] = strdup("#define ATTRIBUTE in\n");
+
+		if (type == GL_VERTEX_SHADER_ARB)
+		{ //"varying" state is "out" in a vertex program, "in" in a fragment program 
+			// ("varying" is deprecated after version 1.20)
+			text[count++] = strdup("#define VARYING out\n");
+		}
+		else
+		{
+			text[count++] = strdup("#define VARYING in\n");
+		}
+
+		//backwards compatibility with legacy texture lookup syntax
+		text[count++] = strdup("#define textureCube texture\n");
+		text[count++] = strdup("#define texture2DLod textureLod\n");
+		text[count++] = strdup("#define	shadow2D texture\n");
 	}
 
 	//copy preprocessor definitions into buffer
@@ -571,7 +642,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 		.
 		uniform sampler2D texN;
 		
-		varying float vary_texture_index;
+		VARYING float vary_texture_index;
 
 		vec4 diffuseLookup(vec2 texcoord)
 		{
@@ -597,7 +668,11 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 			text[count++] = strdup(decl.c_str());
 		}
 
-		text[count++] = strdup("varying float vary_texture_index;\n");
+		if (texture_index_channels > 1)
+		{
+			text[count++] = strdup("VARYING float vary_texture_index;\n");
+		}
+
 		text[count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n");
 		text[count++] = strdup("{\n");
 		
@@ -649,7 +724,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); 
 	}
@@ -704,14 +779,24 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 				LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL;
 				dumpObjectLog(ret);
 
+#if LL_WINDOWS
 				std::stringstream ostr;
 				//dump shader source for debugging
 				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;
+#endif // LL_WINDOWS
 
 				ret = 0;
 			}
@@ -819,3 +904,177 @@ BOOL LLShaderMgr::validateProgramObject(GLhandleARB obj)
 	return success;
 }
 
+//virtual
+void LLShaderMgr::initAttribsAndUniforms()
+{
+	//MUST match order of enum in LLVertexBuffer.h
+	mReservedAttribs.push_back("position");
+	mReservedAttribs.push_back("normal");
+	mReservedAttribs.push_back("texcoord0");
+	mReservedAttribs.push_back("texcoord1");
+	mReservedAttribs.push_back("texcoord2");
+	mReservedAttribs.push_back("texcoord3");
+	mReservedAttribs.push_back("diffuse_color");
+	mReservedAttribs.push_back("emissive");
+	mReservedAttribs.push_back("binormal");
+	mReservedAttribs.push_back("weight");
+	mReservedAttribs.push_back("weight4");
+	mReservedAttribs.push_back("clothing");
+	mReservedAttribs.push_back("texture_index");
+	
+	//matrix state
+	mReservedUniforms.push_back("modelview_matrix");
+	mReservedUniforms.push_back("projection_matrix");
+	mReservedUniforms.push_back("inv_proj");
+	mReservedUniforms.push_back("modelview_projection_matrix");
+	mReservedUniforms.push_back("normal_matrix");
+	mReservedUniforms.push_back("texture_matrix0");
+	mReservedUniforms.push_back("texture_matrix1");
+	mReservedUniforms.push_back("texture_matrix2");
+	mReservedUniforms.push_back("texture_matrix3");
+	llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_MATRIX3+1);
+
+	mReservedUniforms.push_back("viewport");
+
+	mReservedUniforms.push_back("light_position");
+	mReservedUniforms.push_back("light_direction");
+	mReservedUniforms.push_back("light_attenuation");
+	mReservedUniforms.push_back("light_diffuse");
+	mReservedUniforms.push_back("light_ambient");
+	mReservedUniforms.push_back("light_count");
+	mReservedUniforms.push_back("light");
+	mReservedUniforms.push_back("light_col");
+	mReservedUniforms.push_back("far_z");
+
+	llassert(mReservedUniforms.size() == LLShaderMgr::MULTI_LIGHT_FAR_Z+1);
+
+
+	mReservedUniforms.push_back("proj_mat");
+	mReservedUniforms.push_back("proj_near");
+	mReservedUniforms.push_back("proj_p");
+	mReservedUniforms.push_back("proj_n");
+	mReservedUniforms.push_back("proj_origin");
+	mReservedUniforms.push_back("proj_range");
+	mReservedUniforms.push_back("proj_ambiance");
+	mReservedUniforms.push_back("proj_shadow_idx");
+	mReservedUniforms.push_back("shadow_fade");
+	mReservedUniforms.push_back("proj_focus");
+	mReservedUniforms.push_back("proj_lod");
+	mReservedUniforms.push_back("proj_ambient_lod");
+
+	llassert(mReservedUniforms.size() == LLShaderMgr::PROJECTOR_AMBIENT_LOD+1);
+
+	mReservedUniforms.push_back("color");
+	mReservedUniforms.push_back("highlight_color");
+	
+	mReservedUniforms.push_back("diffuseMap");
+	mReservedUniforms.push_back("specularMap");
+	mReservedUniforms.push_back("bumpMap");
+	mReservedUniforms.push_back("environmentMap");
+	mReservedUniforms.push_back("cloude_noise_texture");
+	mReservedUniforms.push_back("fullbright");
+	mReservedUniforms.push_back("lightnorm");
+	mReservedUniforms.push_back("sunlight_color");
+	mReservedUniforms.push_back("ambient");
+	mReservedUniforms.push_back("blue_horizon");
+	mReservedUniforms.push_back("blue_density");
+	mReservedUniforms.push_back("haze_horizon");
+	mReservedUniforms.push_back("haze_density");
+	mReservedUniforms.push_back("cloud_shadow");
+	mReservedUniforms.push_back("density_multiplier");
+	mReservedUniforms.push_back("distance_multiplier");
+	mReservedUniforms.push_back("max_y");
+	mReservedUniforms.push_back("glow");
+	mReservedUniforms.push_back("cloud_color");
+	mReservedUniforms.push_back("cloud_pos_density1");
+	mReservedUniforms.push_back("cloud_pos_density2");
+	mReservedUniforms.push_back("cloud_scale");
+	mReservedUniforms.push_back("gamma");
+	mReservedUniforms.push_back("scene_light_strength");
+
+	llassert(mReservedUniforms.size() == LLShaderMgr::SCENE_LIGHT_STRENGTH+1);
+
+	mReservedUniforms.push_back("center");
+	mReservedUniforms.push_back("size");
+	mReservedUniforms.push_back("falloff");
+
+
+	mReservedUniforms.push_back("minLuminance");
+	mReservedUniforms.push_back("maxExtractAlpha");
+	mReservedUniforms.push_back("lumWeights");
+	mReservedUniforms.push_back("warmthWeights");
+	mReservedUniforms.push_back("warmthAmount");
+	mReservedUniforms.push_back("glowStrength");
+	mReservedUniforms.push_back("glowDelta");
+
+	llassert(mReservedUniforms.size() == LLShaderMgr::GLOW_DELTA+1);
+
+	mReservedUniforms.push_back("shadow_matrix");
+	mReservedUniforms.push_back("env_mat");
+	mReservedUniforms.push_back("shadow_clip");
+	mReservedUniforms.push_back("sun_wash");
+	mReservedUniforms.push_back("shadow_noise");
+	mReservedUniforms.push_back("blur_size");
+	mReservedUniforms.push_back("ssao_radius");
+	mReservedUniforms.push_back("ssao_max_radius");
+	mReservedUniforms.push_back("ssao_factor");
+	mReservedUniforms.push_back("ssao_factor_inv");
+	mReservedUniforms.push_back("ssao_effect_mat");
+	mReservedUniforms.push_back("screen_res");
+	mReservedUniforms.push_back("near_clip");
+	mReservedUniforms.push_back("shadow_offset");
+	mReservedUniforms.push_back("shadow_bias");
+	mReservedUniforms.push_back("spot_shadow_bias");
+	mReservedUniforms.push_back("spot_shadow_offset");
+	mReservedUniforms.push_back("sun_dir");
+	mReservedUniforms.push_back("shadow_res");
+	mReservedUniforms.push_back("proj_shadow_res");
+	mReservedUniforms.push_back("depth_cutoff");
+	mReservedUniforms.push_back("norm_cutoff");
+	
+	llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_NORM_CUTOFF+1);
+
+	mReservedUniforms.push_back("tc_scale");
+	mReservedUniforms.push_back("rcp_screen_res");
+	mReservedUniforms.push_back("rcp_frame_opt");
+	mReservedUniforms.push_back("rcp_frame_opt2");
+	
+	mReservedUniforms.push_back("focal_distance");
+	mReservedUniforms.push_back("blur_constant");
+	mReservedUniforms.push_back("tan_pixel_angle");
+	mReservedUniforms.push_back("magnification");
+
+	mReservedUniforms.push_back("depthMap");
+	mReservedUniforms.push_back("shadowMap0");
+	mReservedUniforms.push_back("shadowMap1");
+	mReservedUniforms.push_back("shadowMap2");
+	mReservedUniforms.push_back("shadowMap3");
+	mReservedUniforms.push_back("shadowMap4");
+	mReservedUniforms.push_back("shadowMap5");
+
+	llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_SHADOW5+1);
+
+	mReservedUniforms.push_back("normalMap");
+	mReservedUniforms.push_back("positionMap");
+	mReservedUniforms.push_back("diffuseRect");
+	mReservedUniforms.push_back("specularRect");
+	mReservedUniforms.push_back("noiseMap");
+	mReservedUniforms.push_back("lightFunc");
+	mReservedUniforms.push_back("lightMap");
+	mReservedUniforms.push_back("bloomMap");
+	mReservedUniforms.push_back("projectionMap");
+
+	llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
+
+	std::set<std::string> dupe_check;
+
+	for (U32 i = 0; i < mReservedUniforms.size(); ++i)
+	{
+		if (dupe_check.find(mReservedUniforms[i]) != dupe_check.end())
+		{
+			llerrs << "Duplicate reserved uniform name found: " << mReservedUniforms[i] << llendl;
+		}
+		dupe_check.insert(mReservedUniforms[i]);
+	}
+}
+
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 2f3010381127f281d78f3bdf5c2739865a9ba65c..9cc2f1bd7f90b83f554b6bf6372c2b7b0afc9ed7 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -36,9 +36,134 @@ class LLShaderMgr
 	LLShaderMgr();
 	virtual ~LLShaderMgr();
 
+	typedef enum
+	{
+		MODELVIEW_MATRIX = 0,
+		PROJECTION_MATRIX,
+		INVERSE_PROJECTION_MATRIX,
+		MODELVIEW_PROJECTION_MATRIX,
+		NORMAL_MATRIX,
+		TEXTURE_MATRIX0,
+		TEXTURE_MATRIX1,
+		TEXTURE_MATRIX2,
+		TEXTURE_MATRIX3,
+		VIEWPORT,
+		LIGHT_POSITION,
+		LIGHT_DIRECTION,
+		LIGHT_ATTENUATION,
+		LIGHT_DIFFUSE,
+		LIGHT_AMBIENT,
+		MULTI_LIGHT_COUNT,
+		MULTI_LIGHT,
+		MULTI_LIGHT_COL,
+		MULTI_LIGHT_FAR_Z,
+		PROJECTOR_MATRIX,
+		PROJECTOR_NEAR,
+		PROJECTOR_P,
+		PROJECTOR_N,
+		PROJECTOR_ORIGIN,
+		PROJECTOR_RANGE,
+		PROJECTOR_AMBIANCE,
+		PROJECTOR_SHADOW_INDEX,
+		PROJECTOR_SHADOW_FADE,
+		PROJECTOR_FOCUS,
+		PROJECTOR_LOD,
+		PROJECTOR_AMBIENT_LOD,
+		DIFFUSE_COLOR,
+		HIGHLIGHT_COLOR,
+		DIFFUSE_MAP,
+		SPECULAR_MAP,
+		BUMP_MAP,
+		ENVIRONMENT_MAP,
+		CLOUD_NOISE_MAP,
+		FULLBRIGHT,
+		LIGHTNORM,
+		SUNLIGHT_COLOR,
+		AMBIENT,
+		BLUE_HORIZON,
+		BLUE_DENSITY,
+		HAZE_HORIZON,
+		HAZE_DENSITY,
+		CLOUD_SHADOW,
+		DENSITY_MULTIPLIER,
+		DISTANCE_MULTIPLIER,
+		MAX_Y,
+		GLOW,
+		CLOUD_COLOR,
+		CLOUD_POS_DENSITY1,
+		CLOUD_POS_DENSITY2,
+		CLOUD_SCALE,
+		GAMMA,
+		SCENE_LIGHT_STRENGTH,
+		LIGHT_CENTER,
+		LIGHT_SIZE,
+		LIGHT_FALLOFF,
+
+		GLOW_MIN_LUMINANCE,
+		GLOW_MAX_EXTRACT_ALPHA,
+		GLOW_LUM_WEIGHTS,
+		GLOW_WARMTH_WEIGHTS,
+		GLOW_WARMTH_AMOUNT,
+		GLOW_STRENGTH,
+		GLOW_DELTA,
+
+		DEFERRED_SHADOW_MATRIX,
+		DEFERRED_ENV_MAT,
+		DEFERRED_SHADOW_CLIP,
+		DEFERRED_SUN_WASH,
+		DEFERRED_SHADOW_NOISE,
+		DEFERRED_BLUR_SIZE,
+		DEFERRED_SSAO_RADIUS,
+		DEFERRED_SSAO_MAX_RADIUS,
+		DEFERRED_SSAO_FACTOR,
+		DEFERRED_SSAO_FACTOR_INV,
+		DEFERRED_SSAO_EFFECT_MAT,
+		DEFERRED_SCREEN_RES,
+		DEFERRED_NEAR_CLIP,
+		DEFERRED_SHADOW_OFFSET,
+		DEFERRED_SHADOW_BIAS,
+		DEFERRED_SPOT_SHADOW_BIAS,
+		DEFERRED_SPOT_SHADOW_OFFSET,
+		DEFERRED_SUN_DIR,
+		DEFERRED_SHADOW_RES,
+		DEFERRED_PROJ_SHADOW_RES,
+		DEFERRED_DEPTH_CUTOFF,
+		DEFERRED_NORM_CUTOFF,
+
+		FXAA_TC_SCALE,
+		FXAA_RCP_SCREEN_RES,
+		FXAA_RCP_FRAME_OPT,
+		FXAA_RCP_FRAME_OPT2,
+
+		DOF_FOCAL_DISTANCE,
+		DOF_BLUR_CONSTANT,
+		DOF_TAN_PIXEL_ANGLE,
+		DOF_MAGNIFICATION,
+
+		DEFERRED_DEPTH,
+		DEFERRED_SHADOW0,
+		DEFERRED_SHADOW1,
+		DEFERRED_SHADOW2,
+		DEFERRED_SHADOW3,
+		DEFERRED_SHADOW4,
+		DEFERRED_SHADOW5,
+		DEFERRED_NORMAL,
+		DEFERRED_POSITION,
+		DEFERRED_DIFFUSE,
+		DEFERRED_SPECULAR,
+		DEFERRED_NOISE,
+		DEFERRED_LIGHTFUNC,
+		DEFERRED_LIGHT,
+		DEFERRED_BLOOM,
+		DEFERRED_PROJECTION,
+		END_RESERVED_UNIFORMS
+	} eGLSLReservedUniforms;
+
 	// singleton pattern implementation
 	static LLShaderMgr * instance();
 
+	virtual void initAttribsAndUniforms(void);
+
 	BOOL attachShaderFeatures(LLGLSLShader * shader);
 	void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE);
 	BOOL	linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 8fd11937801b8eba7f68933bd5692a82e19ef3cf..7f7397701032295026e7e9762b12ed72f22ee9f8 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -34,9 +34,21 @@
 #include "llmemtype.h"
 #include "llrender.h"
 #include "llvector4a.h"
+#include "llshadermgr.h"
 #include "llglslshader.h"
 #include "llmemory.h"
 
+//Next Highest Power Of Two
+//helper function, returns first number > v that is a power of 2, or v if v is already a power of 2
+U32 nhpo2(U32 v)
+{
+	U32 r = 1;
+	while (r < v) {
+		r *= 2;
+	}
+	return r;
+}
+
 
 //============================================================================
 
@@ -45,6 +57,7 @@ LLVBOPool LLVertexBuffer::sStreamVBOPool;
 LLVBOPool LLVertexBuffer::sDynamicVBOPool;
 LLVBOPool LLVertexBuffer::sStreamIBOPool;
 LLVBOPool LLVertexBuffer::sDynamicIBOPool;
+U32 LLVBOPool::sBytesPooled = 0;
 
 LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL ;
 U32 LLVertexBuffer::sBindCount = 0;
@@ -55,6 +68,7 @@ S32 LLVertexBuffer::sMappedCount = 0;
 BOOL LLVertexBuffer::sDisableVBOMapping = FALSE ;
 BOOL LLVertexBuffer::sEnableVBOs = TRUE;
 U32 LLVertexBuffer::sGLRenderBuffer = 0;
+U32 LLVertexBuffer::sGLRenderArray = 0;
 U32 LLVertexBuffer::sGLRenderIndices = 0;
 U32 LLVertexBuffer::sLastMask = 0;
 BOOL LLVertexBuffer::sVBOActive = FALSE;
@@ -62,11 +76,8 @@ BOOL LLVertexBuffer::sIBOActive = FALSE;
 U32 LLVertexBuffer::sAllocatedBytes = 0;
 BOOL LLVertexBuffer::sMapped = FALSE;
 BOOL LLVertexBuffer::sUseStreamDraw = TRUE;
+BOOL LLVertexBuffer::sUseVAO = FALSE;
 BOOL LLVertexBuffer::sPreferStreamDraw = FALSE;
-S32	LLVertexBuffer::sWeight4Loc = -1;
-
-std::vector<U32> LLVertexBuffer::sDeleteList;
-
 
 const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000;  //1 ms
 
@@ -122,6 +133,109 @@ class LLGLSyncFence : public LLGLFence
 
 };
 
+
+//which power of 2 is i?
+//assumes i is a power of 2 > 0
+U32 wpo2(U32 i)
+{
+	llassert(i > 0);
+	llassert(nhpo2(i) == i);
+
+	U32 r = 0;
+
+	while (i >>= 1) ++r;
+
+	return r;
+}
+
+U8* LLVBOPool::allocate(U32& name, U32 size)
+{
+	llassert(nhpo2(size) == size);
+
+	U32 i = wpo2(size);
+
+	if (mFreeList.size() <= i)
+	{
+		mFreeList.resize(i+1);
+	}
+
+	U8* ret = NULL;
+
+	if (mFreeList[i].empty())
+	{
+		//make a new buffer
+		glGenBuffersARB(1, &name);
+		glBindBufferARB(mType, name);
+		glBufferDataARB(mType, size, 0, mUsage);
+		LLVertexBuffer::sAllocatedBytes += size;
+
+		if (LLVertexBuffer::sDisableVBOMapping)
+		{
+			ret = (U8*) ll_aligned_malloc_16(size);
+		}
+		glBindBufferARB(mType, 0);
+	}
+	else
+	{
+		name = mFreeList[i].front().mGLName;
+		ret = mFreeList[i].front().mClientData;
+
+		sBytesPooled -= size;
+
+		mFreeList[i].pop_front();
+	}
+
+	return ret;
+}
+
+void LLVBOPool::release(U32 name, U8* buffer, U32 size)
+{
+	llassert(nhpo2(size) == size);
+
+	U32 i = wpo2(size);
+
+	llassert(mFreeList.size() > i);
+
+	Record rec;
+	rec.mGLName = name;
+	rec.mClientData = buffer;
+
+	sBytesPooled += size;
+
+	mFreeList[i].push_back(rec);
+}
+
+void LLVBOPool::cleanup()
+{
+	U32 size = 1;
+
+	for (U32 i = 0; i < mFreeList.size(); ++i)
+	{
+		record_list_t& l = mFreeList[i];
+
+		while (!l.empty())
+		{
+			Record& r = l.front();
+
+			glDeleteBuffersARB(1, &r.mGLName);
+
+			if (r.mClientData)
+			{
+				ll_aligned_free_16(r.mClientData);
+			}
+
+			l.pop_front();
+
+			LLVertexBuffer::sAllocatedBytes -= size;
+			sBytesPooled -= size;
+		}
+
+		size *= 2;
+	}
+}
+
+
+//NOTE: each component must be AT LEAST 4 bytes in size to avoid a performance penalty on AMD hardware
 S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
 {
 	sizeof(LLVector4), // TYPE_VERTEX,
@@ -131,10 +245,12 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
 	sizeof(LLVector2), // TYPE_TEXCOORD2,
 	sizeof(LLVector2), // TYPE_TEXCOORD3,
 	sizeof(LLColor4U), // TYPE_COLOR,
+	sizeof(LLColor4U), // TYPE_EMISSIVE, only alpha is used currently
 	sizeof(LLVector4), // TYPE_BINORMAL,
 	sizeof(F32),	   // TYPE_WEIGHT,
 	sizeof(LLVector4), // TYPE_WEIGHT4,
 	sizeof(LLVector4), // TYPE_CLOTHWEIGHT,
+	sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes
 };
 
 U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = 
@@ -149,146 +265,147 @@ U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
 	GL_LINE_LOOP,
 };
 
+
 //static
 void LLVertexBuffer::setupClientArrays(U32 data_mask)
 {
-	/*if (LLGLImmediate::sStarted)
-	{
-		llerrs << "Cannot use LLGLImmediate and LLVertexBuffer simultaneously!" << llendl;
-	}*/
-
 	if (sLastMask != data_mask)
 	{
-		U32 mask[] =
+		BOOL error = FALSE;
+
+		if (LLGLSLShader::sNoFixedFunction)
 		{
-			MAP_VERTEX,
-			MAP_NORMAL,
-			MAP_TEXCOORD0,
-			MAP_COLOR,
-		};
-		
-		GLenum array[] =
+			for (U32 i = 0; i < TYPE_MAX; ++i)
+			{
+				S32 loc = i;
+										
+				U32 mask = 1 << i;
+
+				if (sLastMask & (1 << i))
+				{ //was enabled
+					if (!(data_mask & mask))
+					{ //needs to be disabled
+						glDisableVertexAttribArrayARB(loc);
+					}
+				}
+				else 
+				{	//was disabled
+					if (data_mask & mask)
+					{ //needs to be enabled
+						glEnableVertexAttribArrayARB(loc);
+					}
+				}
+			}
+		}
+		else
 		{
-			GL_VERTEX_ARRAY,
-			GL_NORMAL_ARRAY,
-			GL_TEXTURE_COORD_ARRAY,
-			GL_COLOR_ARRAY,
-		};
 
-		BOOL error = FALSE;
-		for (U32 i = 0; i < 4; ++i)
-		{
-			if (sLastMask & mask[i])
-			{ //was enabled
-				if (!(data_mask & mask[i]) && i > 0)
-				{ //needs to be disabled
-					glDisableClientState(array[i]);
+			GLenum array[] =
+			{
+				GL_VERTEX_ARRAY,
+				GL_NORMAL_ARRAY,
+				GL_TEXTURE_COORD_ARRAY,
+				GL_COLOR_ARRAY,
+			};
+
+			GLenum mask[] = 
+			{
+				MAP_VERTEX,
+				MAP_NORMAL,
+				MAP_TEXCOORD0,
+				MAP_COLOR
+			};
+
+
+
+			for (U32 i = 0; i < 4; ++i)
+			{
+				if (sLastMask & mask[i])
+				{ //was enabled
+					if (!(data_mask & mask[i]))
+					{ //needs to be disabled
+						glDisableClientState(array[i]);
+					}
+					else if (gDebugGL)
+					{ //needs to be enabled, make sure it was (DEBUG)
+						if (!glIsEnabled(array[i]))
+						{
+							if (gDebugSession)
+							{
+								error = TRUE;
+								gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;
+							}
+							else
+							{
+								llerrs << "Bad client state! " << array[i] << " disabled." << llendl;
+							}
+						}
+					}
 				}
-				else if (gDebugGL)
-				{ //needs to be enabled, make sure it was (DEBUG TEMPORARY)
-					if (i > 0 && !glIsEnabled(array[i]))
-					{
+				else 
+				{	//was disabled
+					if (data_mask & mask[i])
+					{ //needs to be enabled
+						glEnableClientState(array[i]);
+					}
+					else if (gDebugGL && glIsEnabled(array[i]))
+					{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)
 						if (gDebugSession)
 						{
 							error = TRUE;
-							gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;
+							gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;
 						}
 						else
 						{
-							llerrs << "Bad client state! " << array[i] << " disabled." << llendl;
+							llerrs << "Bad client state! " << array[i] << " enabled." << llendl;
 						}
 					}
 				}
 			}
-			else 
-			{	//was disabled
-				if (data_mask & mask[i] && i > 0)
-				{ //needs to be enabled
-					glEnableClientState(array[i]);
-				}
-				else if (gDebugGL && i > 0 && glIsEnabled(array[i]))
-				{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)
-					if (gDebugSession)
-					{
-						error = TRUE;
-						gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;
-					}
-					else
-					{
-						llerrs << "Bad client state! " << array[i] << " enabled." << llendl;
+		
+			U32 map_tc[] = 
+			{
+				MAP_TEXCOORD1,
+				MAP_TEXCOORD2,
+				MAP_TEXCOORD3
+			};
+
+			for (U32 i = 0; i < 3; i++)
+			{
+				if (sLastMask & map_tc[i])
+				{
+					if (!(data_mask & map_tc[i]))
+					{ //disable
+						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 (error)
-		{
-			ll_fail("LLVertexBuffer::setupClientArrays failed");
-		}
-
-		U32 map_tc[] = 
-		{
-			MAP_TEXCOORD1,
-			MAP_TEXCOORD2,
-			MAP_TEXCOORD3
-		};
 
-		for (U32 i = 0; i < 3; i++)
-		{
-			if (sLastMask & map_tc[i])
+			if (sLastMask & MAP_BINORMAL)
 			{
-				if (!(data_mask & map_tc[i]))
+				if (!(data_mask & MAP_BINORMAL))
 				{
-					glClientActiveTextureARB(GL_TEXTURE1_ARB+i);
+					glClientActiveTextureARB(GL_TEXTURE2_ARB);
 					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 (sLastMask & MAP_BINORMAL)
-		{
-			if (!(data_mask & MAP_BINORMAL))
+			else if (data_mask & MAP_BINORMAL)
 			{
 				glClientActiveTextureARB(GL_TEXTURE2_ARB);
-				glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+				glEnableClientState(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)
-			{
-				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);
-			}
-		}
 				
-
 		sLastMask = data_mask;
 	}
 }
@@ -296,6 +413,9 @@ 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);
+	gGL.syncMatrices();
+
 	U32 count = pos.size();
 	llassert_always(norm.size() >= pos.size());
 	llassert_always(count > 0) ;
@@ -304,24 +424,79 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con
 	
 	setupClientArrays(MAP_VERTEX | MAP_NORMAL);
 
-	glVertexPointer(3, GL_FLOAT, 0, pos[0].mV);
-	glNormalPointer(GL_FLOAT, 0, norm[0].mV);
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+
+	if (shader)
+	{
+		S32 loc = LLVertexBuffer::TYPE_VERTEX;
+		if (loc > -1)
+		{
+			glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 0, pos[0].mV);
+		}
+		loc = LLVertexBuffer::TYPE_NORMAL;
+		if (loc > -1)
+		{
+			glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 0, norm[0].mV);
+		}
+	}
+	else
+	{
+		glVertexPointer(3, GL_FLOAT, 0, pos[0].mV);
+		glNormalPointer(GL_FLOAT, 0, norm[0].mV);
+	}
 
 	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);
+
+	gGL.syncMatrices();
+
+	U32 mask = LLVertexBuffer::MAP_VERTEX;
+	if (tc)
+	{
+		mask = mask | LLVertexBuffer::MAP_TEXCOORD0;
+	}
+
+	unbind();
+	
+	setupClientArrays(mask);
+
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		S32 loc = LLVertexBuffer::TYPE_VERTEX;
+		glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 16, pos);
+
+		if (tc)
+		{
+			loc = LLVertexBuffer::TYPE_TEXCOORD0;
+			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 ||
-	    end >= (U32) mRequestedNumVerts)
+	if (start >= (U32) mNumVerts ||
+	    end >= (U32) mNumVerts)
 	{
-		llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "] vs " << mRequestedNumVerts << llendl;
+		llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "] vs " << mNumVerts << llendl;
 	}
 
-	llassert(mRequestedNumIndices >= 0);
+	llassert(mNumIndices >= 0);
 
-	if (indices_offset >= (U32) mRequestedNumIndices ||
-	    indices_offset + count > (U32) mRequestedNumIndices)
+	if (indices_offset >= (U32) mNumIndices ||
+	    indices_offset + count > (U32) mNumIndices)
 	{
 		llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl;
 	}
@@ -343,16 +518,40 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
 {
 	validateRange(start, end, count, indices_offset);
 
-	llassert(mRequestedNumVerts >= 0);
+	gGL.syncMatrices();
+
+	llassert(mNumVerts >= 0);
+	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
 
-	if (mGLIndices != sGLRenderIndices)
+	if (mGLArray)
+	{
+		if (mGLArray != sGLRenderArray)
+		{
+			llerrs << "Wrong vertex array bound." << llendl;
+		}
+	}
+	else
 	{
-		llerrs << "Wrong index buffer bound." << llendl;
+		if (mGLIndices != sGLRenderIndices)
+		{
+			llerrs << "Wrong index buffer bound." << llendl;
+		}
+
+		if (mGLBuffer != sGLRenderBuffer)
+		{
+			llerrs << "Wrong vertex buffer bound." << llendl;
+		}
 	}
 
-	if (mGLBuffer != sGLRenderBuffer)
+	if (gDebugGL && !mGLArray && useVBOs())
 	{
-		llerrs << "Wrong vertex buffer bound." << llendl;
+		GLint elem = 0;
+		glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem);
+
+		if (elem != mGLIndices)
+		{
+			llerrs << "Wrong index buffer bound!" << llendl;
+		}
 	}
 
 	if (mode >= LLRender::NUM_MODES)
@@ -372,21 +571,35 @@ 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(mRequestedNumIndices >= 0);
-	if (indices_offset >= (U32) mRequestedNumIndices ||
-	    indices_offset + count > (U32) mRequestedNumIndices)
+	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
+
+	gGL.syncMatrices();
+
+	llassert(mNumIndices >= 0);
+	if (indices_offset >= (U32) mNumIndices ||
+	    indices_offset + count > (U32) mNumIndices)
 	{
 		llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl;
 	}
 
-	if (mGLIndices != sGLRenderIndices)
+	if (mGLArray)
 	{
-		llerrs << "Wrong index buffer bound." << llendl;
+		if (mGLArray != sGLRenderArray)
+		{
+			llerrs << "Wrong vertex array bound." << llendl;
+		}
 	}
-
-	if (mGLBuffer != sGLRenderBuffer)
+	else
 	{
-		llerrs << "Wrong vertex buffer bound." << llendl;
+		if (mGLIndices != sGLRenderIndices)
+		{
+			llerrs << "Wrong index buffer bound." << llendl;
+		}
+
+		if (mGLBuffer != sGLRenderBuffer)
+		{
+			llerrs << "Wrong vertex buffer bound." << llendl;
+		}
 	}
 
 	if (mode >= LLRender::NUM_MODES)
@@ -404,16 +617,30 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
 
 void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
 {
-	llassert(mRequestedNumVerts >= 0);
-	if (first >= (U32) mRequestedNumVerts ||
-	    first + count > (U32) mRequestedNumVerts)
+	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
+	
+	gGL.syncMatrices();
+	
+	llassert(mNumVerts >= 0);
+	if (first >= (U32) mNumVerts ||
+	    first + count > (U32) mNumVerts)
 	{
 		llerrs << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl;
 	}
 
-	if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive)
+	if (mGLArray)
+	{
+		if (mGLArray != sGLRenderArray)
+		{
+			llerrs << "Wrong vertex array bound." << llendl;
+		}
+	}
+	else
 	{
-		llerrs << "Wrong vertex buffer bound." << llendl;
+		if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive)
+		{
+			llerrs << "Wrong vertex buffer bound." << llendl;
+		}
 	}
 
 	if (mode >= LLRender::NUM_MODES)
@@ -432,28 +659,37 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
 void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
 {
 	sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject ;
-	if(sEnableVBOs)
-	{
-		//llassert_always(glBindBufferARB) ; //double check the extention for VBO is loaded.
-
-		llinfos << "VBO is enabled." << llendl ;
-	}
-	else
-	{
-		llinfos << "VBO is disabled." << llendl ;
-	}
-
 	sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ;
 
 	if(!sPrivatePoolp)
-	{
+	{ 
 		sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC) ;
 	}
+
+	sStreamVBOPool.mType = GL_ARRAY_BUFFER_ARB;
+	sStreamVBOPool.mUsage= GL_STREAM_DRAW_ARB;
+	sStreamIBOPool.mType = GL_ELEMENT_ARRAY_BUFFER_ARB;
+	sStreamIBOPool.mUsage= GL_STREAM_DRAW_ARB;
+
+	sDynamicVBOPool.mType = GL_ARRAY_BUFFER_ARB;
+	sDynamicVBOPool.mUsage= GL_DYNAMIC_DRAW_ARB;
+	sDynamicIBOPool.mType = GL_ELEMENT_ARRAY_BUFFER_ARB;
+	sDynamicIBOPool.mUsage= GL_DYNAMIC_DRAW_ARB;
 }
 
 //static 
 void LLVertexBuffer::unbind()
 {
+	if (sGLRenderArray)
+	{
+#if GL_ARB_vertex_array_object
+		glBindVertexArray(0);
+#endif
+		sGLRenderArray = 0;
+		sGLRenderIndices = 0;
+		sIBOActive = FALSE;
+	}
+
 	if (sVBOActive)
 	{
 		glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
@@ -476,7 +712,11 @@ void LLVertexBuffer::cleanupClass()
 {
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_CLEANUP_CLASS);
 	unbind();
-	clientCopy(); // deletes GL buffers
+	
+	sStreamIBOPool.cleanup();
+	sDynamicIBOPool.cleanup();
+	sStreamVBOPool.cleanup();
+	sDynamicVBOPool.cleanup();
 
 	if(sPrivatePoolp)
 	{
@@ -485,15 +725,6 @@ void LLVertexBuffer::cleanupClass()
 	}
 }
 
-void LLVertexBuffer::clientCopy(F64 max_time)
-{
-	if (!sDeleteList.empty())
-	{
-		glDeleteBuffersARB(sDeleteList.size(), (GLuint*) &(sDeleteList[0]));
-		sDeleteList.clear();
-	}
-}
-
 //----------------------------------------------------------------------------
 
 LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
@@ -501,20 +732,16 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
 
 	mNumVerts(0),
 	mNumIndices(0),
-	mRequestedNumVerts(-1),
-	mRequestedNumIndices(-1),
 	mUsage(usage),
 	mGLBuffer(0),
+	mGLArray(0),
 	mGLIndices(0), 
 	mMappedData(NULL),
 	mMappedIndexData(NULL), 
 	mVertexLocked(FALSE),
 	mIndexLocked(FALSE),
 	mFinal(FALSE),
-	mFilthy(FALSE),
 	mEmpty(TRUE),
-	mResized(FALSE),
-	mDynamicSize(FALSE),
 	mFence(NULL)
 {
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR);
@@ -534,6 +761,16 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
 		mUsage = GL_STREAM_DRAW_ARB;
 	}
 
+	if (mUsage == 0 && LLRender::sGLCoreProfile)
+	{ //MUST use VBOs for all rendering
+		mUsage = GL_STREAM_DRAW_ARB;
+	}
+
+	if (mUsage && mUsage != GL_STREAM_DRAW_ARB)
+	{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default
+		mUsage = GL_DYNAMIC_DRAW_ARB;
+	}
+		
 	//zero out offsets
 	for (U32 i = 0; i < TYPE_MAX; i++)
 	{
@@ -542,6 +779,7 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
 
 	mTypeMask = typemask;
 	mSize = 0;
+	mIndicesSize = 0;
 	mAlignedOffset = 0;
 	mAlignedIndexOffset = 0;
 
@@ -552,12 +790,12 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
 S32 LLVertexBuffer::calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices)
 {
 	S32 offset = 0;
-	for (S32 i=0; i<TYPE_MAX; i++)
+	for (S32 i=0; i<TYPE_TEXTURE_INDEX; i++)
 	{
 		U32 mask = 1<<i;
 		if (typemask & mask)
 		{
-			if (offsets)
+			if (offsets && LLVertexBuffer::sTypeSize[i])
 			{
 				offsets[i] = offset;
 				offset += LLVertexBuffer::sTypeSize[i]*num_vertices;
@@ -566,6 +804,8 @@ S32 LLVertexBuffer::calcOffsets(const U32& typemask, S32* offsets, S32 num_verti
 		}
 	}
 
+	offsets[TYPE_TEXTURE_INDEX] = offsets[TYPE_VERTEX] + 12;
+	
 	return offset+16;
 }
 
@@ -573,7 +813,7 @@ S32 LLVertexBuffer::calcOffsets(const U32& typemask, S32* offsets, S32 num_verti
 S32 LLVertexBuffer::calcVertexSize(const U32& typemask)
 {
 	S32 size = 0;
-	for (S32 i = 0; i < TYPE_MAX; i++)
+	for (S32 i = 0; i < TYPE_TEXTURE_INDEX; i++)
 	{
 		U32 mask = 1<<i;
 		if (typemask & mask)
@@ -597,6 +837,14 @@ LLVertexBuffer::~LLVertexBuffer()
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTRUCTOR);
 	destroyGLBuffer();
 	destroyGLIndices();
+
+	if (mGLArray)
+	{
+#if GL_ARB_vertex_array_object
+		glDeleteVertexArrays(1, &mGLArray);
+#endif
+	}
+
 	sCount--;
 
 	if (mFence)
@@ -635,39 +883,35 @@ void LLVertexBuffer::waitFence() const
 
 //----------------------------------------------------------------------------
 
-void LLVertexBuffer::genBuffer()
+void LLVertexBuffer::genBuffer(U32 size)
 {
+	mSize = nhpo2(size);
+
 	if (mUsage == GL_STREAM_DRAW_ARB)
 	{
-		mGLBuffer = sStreamVBOPool.allocate();
-	}
-	else if (mUsage == GL_DYNAMIC_DRAW_ARB)
-	{
-		mGLBuffer = sDynamicVBOPool.allocate();
+		mMappedData = sStreamVBOPool.allocate(mGLBuffer, mSize);
 	}
 	else
 	{
-		BOOST_STATIC_ASSERT(sizeof(mGLBuffer) == sizeof(GLuint));
-		glGenBuffersARB(1, (GLuint*)&mGLBuffer);
+		mMappedData = sDynamicVBOPool.allocate(mGLBuffer, mSize);
 	}
+	
 	sGLCount++;
 }
 
-void LLVertexBuffer::genIndices()
+void LLVertexBuffer::genIndices(U32 size)
 {
+	mIndicesSize = nhpo2(size);
+
 	if (mUsage == GL_STREAM_DRAW_ARB)
 	{
-		mGLIndices = sStreamIBOPool.allocate();
-	}
-	else if (mUsage == GL_DYNAMIC_DRAW_ARB)
-	{
-		mGLIndices = sDynamicIBOPool.allocate();
+		mMappedIndexData = sStreamIBOPool.allocate(mGLIndices, mIndicesSize);
 	}
 	else
 	{
-		BOOST_STATIC_ASSERT(sizeof(mGLBuffer) == sizeof(GLuint));
-		glGenBuffersARB(1, (GLuint*)&mGLIndices);
+		mMappedIndexData = sDynamicIBOPool.allocate(mGLIndices, mIndicesSize);
 	}
+	
 	sGLCount++;
 }
 
@@ -675,16 +919,16 @@ void LLVertexBuffer::releaseBuffer()
 {
 	if (mUsage == GL_STREAM_DRAW_ARB)
 	{
-		sStreamVBOPool.release(mGLBuffer);
-	}
-	else if (mUsage == GL_DYNAMIC_DRAW_ARB)
-	{
-		sDynamicVBOPool.release(mGLBuffer);
+		sStreamVBOPool.release(mGLBuffer, mMappedData, mSize);
 	}
 	else
 	{
-		sDeleteList.push_back(mGLBuffer);
+		sDynamicVBOPool.release(mGLBuffer, mMappedData, mSize);
 	}
+	
+	mGLBuffer = 0;
+	mMappedData = NULL;
+
 	sGLCount--;
 }
 
@@ -692,24 +936,23 @@ void LLVertexBuffer::releaseIndices()
 {
 	if (mUsage == GL_STREAM_DRAW_ARB)
 	{
-		sStreamIBOPool.release(mGLIndices);
+		sStreamIBOPool.release(mGLIndices, mMappedIndexData, mIndicesSize);
 	}
 	else if (mUsage == GL_DYNAMIC_DRAW_ARB)
 	{
-		sDynamicIBOPool.release(mGLIndices);
-	}
-	else
-	{
-		sDeleteList.push_back(mGLIndices);
+		sDynamicIBOPool.release(mGLIndices, mMappedIndexData, mIndicesSize);
 	}
+
+	mGLIndices = 0;
+	mMappedIndexData = NULL;
+	
 	sGLCount--;
 }
 
-void LLVertexBuffer::createGLBuffer()
+void LLVertexBuffer::createGLBuffer(U32 size)
 {
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_VERTICES);
 	
-	U32 size = getSize();
 	if (mGLBuffer)
 	{
 		destroyGLBuffer();
@@ -724,23 +967,21 @@ void LLVertexBuffer::createGLBuffer()
 
 	if (useVBOs())
 	{
-		mMappedData = NULL;
-		genBuffer();
-		mResized = TRUE;
+		genBuffer(size);
 	}
 	else
 	{
 		static int gl_buffer_idx = 0;
 		mGLBuffer = ++gl_buffer_idx;
 		mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
+		mSize = size;
 	}
 }
 
-void LLVertexBuffer::createGLIndices()
+void LLVertexBuffer::createGLIndices(U32 size)
 {
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_INDICES);
-	U32 size = getIndicesSize();
-
+	
 	if (mGLIndices)
 	{
 		destroyGLIndices();
@@ -760,15 +1001,14 @@ void LLVertexBuffer::createGLIndices()
 	{
 		//pad by another 16 bytes for VBO pointer adjustment
 		size += 16;
-		mMappedIndexData = NULL;
-		genIndices();
-		mResized = TRUE;
+		genIndices(size);
 	}
 	else
 	{
 		mMappedIndexData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
 		static int gl_buffer_idx = 0;
 		mGLIndices = ++gl_buffer_idx;
+		mIndicesSize = size;
 	}
 }
 
@@ -779,12 +1019,6 @@ void LLVertexBuffer::destroyGLBuffer()
 	{
 		if (useVBOs())
 		{
-			freeClientBuffer() ;
-
-			if (mMappedData || mMappedIndexData)
-			{
-				llerrs << "Vertex buffer destroyed while mapped!" << llendl;
-			}
 			releaseBuffer();
 		}
 		else
@@ -793,8 +1027,6 @@ void LLVertexBuffer::destroyGLBuffer()
 			mMappedData = NULL;
 			mEmpty = TRUE;
 		}
-
-		sAllocatedBytes -= getSize();
 	}
 	
 	mGLBuffer = 0;
@@ -808,12 +1040,6 @@ void LLVertexBuffer::destroyGLIndices()
 	{
 		if (useVBOs())
 		{
-			freeClientBuffer() ;
-
-			if (mMappedData || mMappedIndexData)
-			{
-				llerrs << "Vertex buffer destroyed while mapped." << llendl;
-			}
 			releaseIndices();
 		}
 		else
@@ -822,8 +1048,6 @@ void LLVertexBuffer::destroyGLIndices()
 			mMappedIndexData = NULL;
 			mEmpty = TRUE;
 		}
-
-		sAllocatedBytes -= getIndicesSize();
 	}
 
 	mGLIndices = 0;
@@ -842,23 +1066,14 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
 		nverts = 65535;
 	}
 
-	mRequestedNumVerts = nverts;
+	U32 needed_size = calcOffsets(mTypeMask, mOffsets, nverts);
 
-	if (!mDynamicSize)
+	if (needed_size > mSize || needed_size <= mSize/2)
 	{
-		mNumVerts = nverts;
+		createGLBuffer(needed_size);
 	}
-	else if (mUsage == GL_STATIC_DRAW_ARB ||
-		nverts > mNumVerts ||
-		nverts < mNumVerts/2)
-	{
-		if (mUsage != GL_STATIC_DRAW_ARB && nverts + nverts/4 <= 65535)
-		{
-			nverts += nverts/4;
-		}
-		mNumVerts = nverts;
-	}
-	mSize = calcOffsets(mTypeMask, mOffsets, mNumVerts);
+
+	mNumVerts = nverts;
 }
 
 void LLVertexBuffer::updateNumIndices(S32 nindices)
@@ -867,28 +1082,22 @@ void LLVertexBuffer::updateNumIndices(S32 nindices)
 
 	llassert(nindices >= 0);
 
-	mRequestedNumIndices = nindices;
-	if (!mDynamicSize)
+	U32 needed_size = sizeof(U16) * nindices;
+
+	if (needed_size > mIndicesSize || needed_size <= mIndicesSize/2)
 	{
-		mNumIndices = nindices;
+		createGLIndices(needed_size);
 	}
-	else if (mUsage == GL_STATIC_DRAW_ARB ||
-		nindices > mNumIndices ||
-		nindices < mNumIndices/2)
-	{
-		if (mUsage != GL_STATIC_DRAW_ARB)
-		{
-			nindices += nindices/4;
-		}
 
-		mNumIndices = nindices;
-	}
+	mNumIndices = nindices;
 }
 
 void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
 {
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_ALLOCATE_BUFFER);
-		
+	
+	stop_glerror();
+
 	if (nverts < 0 || nindices < 0 ||
 		nverts > 65536)
 	{
@@ -898,96 +1107,121 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
 	updateNumVerts(nverts);
 	updateNumIndices(nindices);
 	
-	if (mMappedData)
-	{
-		llerrs << "LLVertexBuffer::allocateBuffer() called redundantly." << llendl;
-	}
 	if (create && (nverts || nindices))
 	{
-		createGLBuffer();
-		createGLIndices();
+		//actually allocate space for the vertex buffer if using VBO mapping
+		flush();
+
+		if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO))
+		{
+#if GL_ARB_vertex_array_object
+			glGenVertexArrays(1, &mGLArray);
+#endif
+			setupVertexArray();
+		}
 	}
-	
-	sAllocatedBytes += getSize() + getIndicesSize();
 }
 
-void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
+void LLVertexBuffer::setupVertexArray()
 {
-	llassert(newnverts >= 0);
-	llassert(newnindices >= 0);
-
-	mRequestedNumVerts = newnverts;
-	mRequestedNumIndices = newnindices;
-
-	LLMemType mt2(LLMemType::MTYPE_VERTEX_RESIZE_BUFFER);
-	mDynamicSize = TRUE;
-	if (mUsage == GL_STATIC_DRAW_ARB)
-	{ //always delete/allocate static buffers on resize
-		destroyGLBuffer();
-		destroyGLIndices();
-		allocateBuffer(newnverts, newnindices, TRUE);
-		mFinal = FALSE;
-	}
-	else if (newnverts > mNumVerts || newnindices > mNumIndices ||
-			 newnverts < mNumVerts/2 || newnindices < mNumIndices/2)
+	if (!mGLArray)
 	{
-		sAllocatedBytes -= getSize() + getIndicesSize();
-		
-		updateNumVerts(newnverts);		
-		updateNumIndices(newnindices);
-		
-		S32 newsize = getSize();
-		S32 new_index_size = getIndicesSize();
-
-		sAllocatedBytes += newsize + new_index_size;
+		return;
+	}
 
-		if (newsize)
-		{
-			if (!mGLBuffer)
-			{ //no buffer exists, create a new one
-				createGLBuffer();
-			}
-			else
-			{
-				if (!useVBOs())
-				{
-					FREE_MEM(sPrivatePoolp, mMappedData);
-					mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, newsize);
-				}
-				mResized = TRUE;
-			}
-		}
-		else if (mGLBuffer)
-		{
-			destroyGLBuffer();
-		}
-		
-		if (new_index_size)
+#if GL_ARB_vertex_array_object
+	glBindVertexArray(mGLArray);
+#endif
+	sGLRenderArray = mGLArray;
+
+	U32 attrib_size[] = 
+	{
+		3, //TYPE_VERTEX,
+		3, //TYPE_NORMAL,
+		2, //TYPE_TEXCOORD0,
+		2, //TYPE_TEXCOORD1,
+		2, //TYPE_TEXCOORD2,
+		2, //TYPE_TEXCOORD3,
+		4, //TYPE_COLOR,
+		4, //TYPE_EMISSIVE,
+		3, //TYPE_BINORMAL,
+		1, //TYPE_WEIGHT,
+		4, //TYPE_WEIGHT4,
+		4, //TYPE_CLOTHWEIGHT,
+		1, //TYPE_TEXTURE_INDEX
+	};
+
+	U32 attrib_type[] =
+	{
+		GL_FLOAT, //TYPE_VERTEX,
+		GL_FLOAT, //TYPE_NORMAL,
+		GL_FLOAT, //TYPE_TEXCOORD0,
+		GL_FLOAT, //TYPE_TEXCOORD1,
+		GL_FLOAT, //TYPE_TEXCOORD2,
+		GL_FLOAT, //TYPE_TEXCOORD3,
+		GL_UNSIGNED_BYTE, //TYPE_COLOR,
+		GL_UNSIGNED_BYTE, //TYPE_EMISSIVE,
+		GL_FLOAT,   //TYPE_BINORMAL,
+		GL_FLOAT, //TYPE_WEIGHT,
+		GL_FLOAT, //TYPE_WEIGHT4,
+		GL_FLOAT, //TYPE_CLOTHWEIGHT,
+		GL_FLOAT, //TYPE_TEXTURE_INDEX
+	};
+
+	U32 attrib_normalized[] =
+	{
+		GL_FALSE, //TYPE_VERTEX,
+		GL_FALSE, //TYPE_NORMAL,
+		GL_FALSE, //TYPE_TEXCOORD0,
+		GL_FALSE, //TYPE_TEXCOORD1,
+		GL_FALSE, //TYPE_TEXCOORD2,
+		GL_FALSE, //TYPE_TEXCOORD3,
+		GL_TRUE, //TYPE_COLOR,
+		GL_TRUE, //TYPE_EMISSIVE,
+		GL_FALSE,   //TYPE_BINORMAL,
+		GL_FALSE, //TYPE_WEIGHT,
+		GL_FALSE, //TYPE_WEIGHT4,
+		GL_FALSE, //TYPE_CLOTHWEIGHT,
+		GL_FALSE, //TYPE_TEXTURE_INDEX
+	};
+
+	bindGLBuffer(true);
+	bindGLIndices(true);
+
+	for (U32 i = 0; i < TYPE_MAX; ++i)
+	{
+		if (mTypeMask & (1 << i))
 		{
-			if (!mGLIndices)
-			{
-				createGLIndices();
-			}
-			else
-			{
-				if (!useVBOs())
-				{
-					FREE_MEM(sPrivatePoolp, mMappedIndexData) ;
-					mMappedIndexData = (U8*)ALLOCATE_MEM(sPrivatePoolp, new_index_size);
-				}
-				mResized = TRUE;
-			}
+			glEnableVertexAttribArrayARB(i);
+			glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i], attrib_normalized[i], sTypeSize[i], (void*) mOffsets[i]); 
 		}
-		else if (mGLIndices)
+		else
 		{
-			destroyGLIndices();
+			glDisableVertexAttribArrayARB(i);
 		}
 	}
 
-	if (mResized && useVBOs())
+	unbind();
+}
+
+void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
+{
+	llassert(newnverts >= 0);
+	llassert(newnindices >= 0);
+
+	LLMemType mt2(LLMemType::MTYPE_VERTEX_RESIZE_BUFFER);
+	
+	updateNumVerts(newnverts);		
+	updateNumIndices(newnindices);
+	
+	if (useVBOs())
 	{
-		freeClientBuffer() ;
-		setBuffer(0);
+		flush();
+
+		if (mGLArray)
+		{ //if size changed, offsets changed
+			setupVertexArray();
+		}
 	}
 }
 
@@ -1004,32 +1238,6 @@ BOOL LLVertexBuffer::useVBOs() const
 }
 
 //----------------------------------------------------------------------------
-void LLVertexBuffer::freeClientBuffer()
-{
-	if(useVBOs() && sDisableVBOMapping && (mMappedData || mMappedIndexData))
-	{
-		FREE_MEM(sPrivatePoolp, mMappedData) ;
-		FREE_MEM(sPrivatePoolp, mMappedIndexData) ;
-		mMappedData = NULL ;
-		mMappedIndexData = NULL ;
-	}
-}
-
-void LLVertexBuffer::allocateClientVertexBuffer()
-{
-	if(!mMappedData)
-	{
-		mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, getSize());
-	}
-}
-
-void LLVertexBuffer::allocateClientIndexBuffer()
-{
-	if(!mMappedIndexData)
-	{
-		mMappedIndexData = (U8*)ALLOCATE_MEM(sPrivatePoolp, getIndicesSize());		
-	}
-}
 
 bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
 {
@@ -1052,6 +1260,7 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
 // Map for data access
 U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)
 {
+	bindGLBuffer(true);
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
 	if (mFinal)
 	{
@@ -1102,7 +1311,6 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
 		if (!mVertexLocked)
 		{
 			LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES);
-			setBuffer(0, type);
 			mVertexLocked = TRUE;
 			sMappedCount++;
 			stop_glerror();	
@@ -1110,7 +1318,6 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
 			if(sDisableVBOMapping)
 			{
 				map_range = false;
-				allocateClientVertexBuffer() ;
 			}
 			else
 			{
@@ -1132,6 +1339,18 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
 					else
 					{
 #ifdef GL_ARB_map_buffer_range
+
+						if (gDebugGL)
+						{
+							GLint size = 0;
+							glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size);
+
+							if (size < mSize)
+							{
+								llerrs << "Invalid buffer size." << llendl;
+							}
+						}
+
 						src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize, 
 							GL_MAP_WRITE_BIT | 
 							GL_MAP_FLUSH_EXPLICIT_BIT);
@@ -1217,6 +1436,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
 U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
 {
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
+	bindGLIndices(true);
 	if (mFinal)
 	{
 		llerrs << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << llendl;
@@ -1264,15 +1484,24 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
 		{
 			LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);
 
-			setBuffer(0, TYPE_INDEX);
 			mIndexLocked = TRUE;
 			sMappedCount++;
 			stop_glerror();	
 
+			if (gDebugGL && useVBOs())
+			{
+				GLint elem = 0;
+				glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem);
+
+				if (elem != mGLIndices)
+				{
+					llerrs << "Wrong index buffer bound!" << llendl;
+				}
+			}
+
 			if(sDisableVBOMapping)
 			{
 				map_range = false;
-				allocateClientIndexBuffer() ;
 			}
 			else
 			{
@@ -1365,19 +1594,20 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
 	}
 }
 
-void LLVertexBuffer::unmapBuffer(S32 type)
+void LLVertexBuffer::unmapBuffer()
 {
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER);
-	if (!useVBOs() || type == -2)
+	if (!useVBOs())
 	{
 		return ; //nothing to unmap
 	}
 
 	bool updated_all = false ;
 
-	if (mMappedData && mVertexLocked && type != TYPE_INDEX)
+	if (mMappedData && mVertexLocked)
 	{
-		updated_all = (mIndexLocked && type < 0) ; //both vertex and index buffers done updating
+		bindGLBuffer(true);
+		updated_all = mIndexLocked; //both vertex and index buffers done updating
 
 		if(sDisableVBOMapping)
 		{
@@ -1441,8 +1671,9 @@ void LLVertexBuffer::unmapBuffer(S32 type)
 		sMappedCount--;
 	}
 	
-	if (mMappedIndexData && mIndexLocked && (type < 0 || type == TYPE_INDEX))
+	if (mMappedIndexData && mIndexLocked)
 	{
+		bindGLIndices();
 		if(sDisableVBOMapping)
 		{
 			if (!mMappedIndexRegions.empty())
@@ -1507,21 +1738,7 @@ void LLVertexBuffer::unmapBuffer(S32 type)
 
 	if(updated_all)
 	{
-		if(mUsage == GL_STATIC_DRAW_ARB)
-		{
-			//static draw buffers can only be mapped a single time
-			//throw out client data (we won't be using it again)
-			mEmpty = TRUE;
-			mFinal = TRUE;
-			if(sDisableVBOMapping)
-			{
-				freeClientBuffer() ;
-			}
-		}
-		else
-		{
-			mEmpty = FALSE;
-		}
+		mEmpty = FALSE;
 	}
 }
 
@@ -1576,6 +1793,10 @@ bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector3>& strider, S32 index,
 {
 	return VertexBufferStrider<LLVector3,TYPE_VERTEX>::get(*this, strider, index, count, map_range);
 }
+bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector4a>& strider, S32 index, S32 count, bool map_range)
+{
+	return VertexBufferStrider<LLVector4a,TYPE_VERTEX>::get(*this, strider, index, count, map_range);
+}
 bool LLVertexBuffer::getIndexStrider(LLStrider<U16>& strider, S32 index, S32 count, bool map_range)
 {
 	return VertexBufferStrider<U16,TYPE_INDEX>::get(*this, strider, index, count, map_range);
@@ -1601,6 +1822,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<LLColor4U>& strider, S32 index, S32 count, bool map_range)
+{
+	return VertexBufferStrider<LLColor4U,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);
@@ -1618,43 +1843,141 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 in
 
 //----------------------------------------------------------------------------
 
+bool LLVertexBuffer::bindGLArray()
+{
+	if (mGLArray && sGLRenderArray != mGLArray)
+	{
+#if GL_ARB_vertex_array_object
+		glBindVertexArray(mGLArray);
+#endif
+		sGLRenderArray = mGLArray;
+
+		//really shouldn't be necessary, but some drivers don't properly restore the
+		//state of GL_ELEMENT_ARRAY_BUFFER_BINDING
+		bindGLIndices();
+		
+		return true;
+	}
+		
+	return false;
+}
+
+bool LLVertexBuffer::bindGLBuffer(bool force_bind)
+{
+	bindGLArray();
+
+	bool ret = false;
+
+	if (useVBOs() && (force_bind || (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive))))
+	{
+		/*if (sMapped)
+		{
+			llerrs << "VBO bound while another VBO mapped!" << llendl;
+		}*/
+		glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
+		sGLRenderBuffer = mGLBuffer;
+		sBindCount++;
+		sVBOActive = TRUE;
+
+		if (mGLArray)
+		{
+			llassert(sGLRenderArray == mGLArray);
+			//mCachedRenderBuffer = mGLBuffer;
+		}
+
+		ret = true;
+	}
+
+	return ret;
+}
+
+bool LLVertexBuffer::bindGLIndices(bool force_bind)
+{
+	bindGLArray();
+
+	bool ret = false;
+	if (useVBOs() && (force_bind || (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive))))
+	{
+		/*if (sMapped)
+		{
+			llerrs << "VBO bound while another VBO mapped!" << llendl;
+		}*/
+		glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices);
+		sGLRenderIndices = mGLIndices;
+		stop_glerror();
+		sBindCount++;
+		sIBOActive = TRUE;
+		ret = true;
+	}
+
+	return ret;
+}
+
+void LLVertexBuffer::flush()
+{
+	if (useVBOs())
+	{
+		unmapBuffer();
+	}
+}
+
 // Set for rendering
-void LLVertexBuffer::setBuffer(U32 data_mask, S32 type)
+void LLVertexBuffer::setBuffer(U32 data_mask)
 {
+	flush();
+
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_BUFFER);
 	//set up pointers if the data mask is different ...
 	BOOL setup = (sLastMask != data_mask);
 
+	if (gDebugGL && data_mask != 0)
+	{ //make sure data requirements are fulfilled
+		LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+		if (shader)
+		{
+			U32 required_mask = 0;
+			for (U32 i = 0; i < LLVertexBuffer::TYPE_TEXTURE_INDEX; ++i)
+			{
+				if (shader->getAttribLocation(i) > -1)
+				{
+					U32 required = 1 << i;
+					if ((data_mask & required) == 0)
+					{
+						llwarns << "Missing attribute: " << LLShaderMgr::instance()->mReservedAttribs[i] << llendl;
+					}
+
+					required_mask |= required;
+				}
+			}
+
+			if ((data_mask & required_mask) != required_mask)
+			{
+				llerrs << "Shader consumption mismatches data provision." << llendl;
+			}
+		}
+	}
+
 	if (useVBOs())
 	{
-		if (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive))
+		if (mGLArray)
 		{
-			/*if (sMapped)
-			{
-				llerrs << "VBO bound while another VBO mapped!" << llendl;
-			}*/
-			stop_glerror();
-			glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
-			stop_glerror();
-			sBindCount++;
-			sVBOActive = TRUE;
-			setup = TRUE; // ... or the bound buffer changed
+			bindGLArray();
+			setup = FALSE; //do NOT perform pointer setup if using VAO
 		}
-		if (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive))
+		else
 		{
-			/*if (sMapped)
+			if (bindGLBuffer())
 			{
-				llerrs << "VBO bound while another VBO mapped!" << llendl;
-			}*/
-			stop_glerror();
-			glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices);
-			stop_glerror();
-			sBindCount++;
-			sIBOActive = TRUE;
+				setup = TRUE;
+			}
+			if (bindGLIndices())
+			{
+				setup = TRUE;
+			}
 		}
-		
+
 		BOOL error = FALSE;
-		if (gDebugGL)
+		if (gDebugGL && !mGLArray)
 		{
 			GLint buff;
 			glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
@@ -1689,81 +2012,20 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type)
 			}
 		}
 
-		if (mResized)
+		
+	}
+	else
+	{	
+		if (sGLRenderArray)
 		{
-			if (gDebugGL)
-			{
-				GLint buff;
-				glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
-				if ((GLuint)buff != mGLBuffer)
-				{
-					if (gDebugSession)
-					{
-						error = TRUE;
-						gFailLog << "Invalid GL vertex buffer bound: " << std::endl;
-					}
-					else
-					{
-						llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
-					}
-				}
-
-				if (mGLIndices != 0)
-				{
-					glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
-					if ((GLuint)buff != mGLIndices)
-					{
-						if (gDebugSession)
-						{
-							error = TRUE;
-							gFailLog << "Invalid GL index buffer bound: "<< std::endl;
-						}
-						else
-						{
-							llerrs << "Invalid GL index buffer bound: " << buff << llendl;
-						}
-					}
-				}
-			}
-
-			if (mGLBuffer)
-			{
-				stop_glerror();
-				glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), NULL, mUsage);
-				stop_glerror();
-			}
-			if (mGLIndices)
-			{
-				stop_glerror();
-				glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), NULL, mUsage);
-				stop_glerror();
-			}
-
-			mEmpty = TRUE;
-			mResized = FALSE;
-
-			if (data_mask != 0)
-			{
-				if (gDebugSession)
-				{
-					error = TRUE;
-					gFailLog << "Buffer set for rendering before being filled after resize." << std::endl;
-				}
-				else
-				{
-					llerrs << "Buffer set for rendering before being filled after resize." << llendl;
-				}
-			}
+#if GL_ARB_vertex_array_object
+			glBindVertexArray(0);
+#endif
+			sGLRenderArray = 0;
+			sGLRenderIndices = 0;
+			sIBOActive = FALSE;
 		}
 
-		if (error)
-		{
-			ll_fail("LLVertexBuffer::mapBuffer failed");
-		}
-		unmapBuffer(type);
-	}
-	else
-	{		
 		if (mGLBuffer)
 		{
 			if (sVBOActive)
@@ -1775,30 +2037,30 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type)
 			}
 			if (sGLRenderBuffer != mGLBuffer)
 			{
+				sGLRenderBuffer = mGLBuffer;
 				setup = TRUE; // ... or a client memory pointer changed
 			}
 		}
-		if (mGLIndices && sIBOActive)
+		if (mGLIndices)
 		{
-			/*if (sMapped)
+			if (sIBOActive)
 			{
-				llerrs << "VBO unbound while potentially mapped!" << llendl;
-			}*/
-			glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
-			sBindCount++;
-			sIBOActive = FALSE;
+				glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+				sBindCount++;
+				sIBOActive = FALSE;
+			}
+			
+			sGLRenderIndices = mGLIndices;
 		}
 	}
 
-	setupClientArrays(data_mask);
-	
-	if (mGLIndices)
+	if (!mGLArray)
 	{
-		sGLRenderIndices = mGLIndices;
+		setupClientArrays(data_mask);
 	}
+			
 	if (mGLBuffer)
 	{
-		sGLRenderBuffer = mGLBuffer;
 		if (data_mask && setup)
 		{
 			setupVertexBuffer(data_mask); // subclass specific setup (virtual function)
@@ -1808,80 +2070,150 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type)
 }
 
 // virtual (default)
-void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
+void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
 {
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_SETUP_VERTEX_BUFFER);
 	stop_glerror();
 	U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
 
-	if ((data_mask & mTypeMask) != data_mask)
+	/*if ((data_mask & mTypeMask) != data_mask)
 	{
 		llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;
-	}
-
-	if (data_mask & MAP_NORMAL)
-	{
-		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);
-	}
-	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);
-	}
-	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);
-	}
-	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);
-	}
-	if (data_mask & MAP_TEXCOORD0)
-	{
-		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]));
-	}
-	
-	if (data_mask & MAP_WEIGHT)
-	{
-		glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], (void*)(base + mOffsets[TYPE_WEIGHT]));
-	}
-
-	if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1)
-	{
-		glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], (void*)(base+mOffsets[TYPE_WEIGHT4]));
-	}
+	}*/
 
-	if (data_mask & MAP_CLOTHWEIGHT)
-	{
-		glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE,  LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]));
-	}
-	if (data_mask & MAP_VERTEX)
+	if (LLGLSLShader::sNoFixedFunction)
 	{
+		if (data_mask & MAP_NORMAL)
+		{
+			S32 loc = TYPE_NORMAL;
+			void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]);
+			glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr);
+		}
+		if (data_mask & MAP_TEXCOORD3)
+		{
+			S32 loc = TYPE_TEXCOORD3;
+			void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]);
+			glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr);
+		}
+		if (data_mask & MAP_TEXCOORD2)
+		{
+			S32 loc = TYPE_TEXCOORD2;
+			void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]);
+			glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr);
+		}
+		if (data_mask & MAP_TEXCOORD1)
+		{
+			S32 loc = TYPE_TEXCOORD1;
+			void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]);
+			glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);
+		}
+		if (data_mask & MAP_BINORMAL)
+		{
+			S32 loc = TYPE_BINORMAL;
+			void* ptr = (void*)(base + mOffsets[TYPE_BINORMAL]);
+			glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], ptr);
+		}
+		if (data_mask & MAP_TEXCOORD0)
+		{
+			S32 loc = TYPE_TEXCOORD0;
+			void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]);
+			glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr);
+		}
+		if (data_mask & MAP_COLOR)
+		{
+			S32 loc = TYPE_COLOR;
+			void* ptr = (void*)(base + mOffsets[TYPE_COLOR]);
+			glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr);
+		}
+		if (data_mask & MAP_EMISSIVE)
+		{
+			S32 loc = TYPE_EMISSIVE;
+			void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]);
+			glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
+		}
+		if (data_mask & MAP_WEIGHT)
+		{
+			S32 loc = TYPE_WEIGHT;
+			void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]);
+			glVertexAttribPointerARB(loc, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr);
+		}
+		if (data_mask & MAP_WEIGHT4)
+		{
+			S32 loc = TYPE_WEIGHT4;
+			void* ptr = (void*)(base+mOffsets[TYPE_WEIGHT4]);
+			glVertexAttribPointerARB(loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr);
+		}
+		if (data_mask & MAP_CLOTHWEIGHT)
+		{
+			S32 loc = TYPE_CLOTHWEIGHT;
+			void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]);
+			glVertexAttribPointerARB(loc, 4, GL_FLOAT, TRUE,  LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
+		}
 		if (data_mask & MAP_TEXTURE_INDEX)
 		{
-			glVertexPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
+			S32 loc = TYPE_TEXTURE_INDEX;
+			void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12);
+			glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
 		}
-		else
+		if (data_mask & MAP_VERTEX)
 		{
-			glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
+			S32 loc = TYPE_VERTEX;
+			void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]);
+			glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
+		}	
+	}	
+	else
+	{
+		if (data_mask & MAP_NORMAL)
+		{
+			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);
+		}
+		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);
+		}
+		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);
+		}
+		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);
 		}
+		if (data_mask & MAP_TEXCOORD0)
+		{
+			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]));
+		}
+		if (data_mask & MAP_VERTEX)
+		{
+			glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
+		}	
 	}
 
 	llglassertok();
 }
 
+LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count)
+: mType(type), mIndex(index), mCount(count)
+{ 
+	llassert(mType == LLVertexBuffer::TYPE_INDEX || 
+			mType < LLVertexBuffer::TYPE_TEXTURE_INDEX);
+}	
+
+
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index 578cec38859c6d88d4eda6964fad47efa7cf9f0e..3e6f6a959aeeda4e66935af2608d56d13c86a4c3 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -38,6 +38,8 @@
 #include <vector>
 #include <list>
 
+#define LL_MAX_VERTEX_ATTRIB_LOCATION 64
+
 //============================================================================
 // NOTES
 // Threading:
@@ -49,25 +51,32 @@
 
 //============================================================================
 // gl name pools for dynamic and streaming buffers
-
-class LLVBOPool : public LLGLNamePool
+class LLVBOPool
 {
-protected:
-	virtual GLuint allocateName()
-	{
-		GLuint name;
-		stop_glerror();
-		glGenBuffersARB(1, &name);
-		stop_glerror();
-		return name;
-	}
+public:
+	static U32 sBytesPooled;
+
+	U32 mUsage;
+	U32 mType;
 
-	virtual void releaseName(GLuint name)
+	//size MUST be a power of 2
+	U8* allocate(U32& name, U32 size);
+	
+	//size MUST be the size provided to allocate that returned the given name
+	void release(U32 name, U8* buffer, U32 size);
+	
+	//destroy all records in mFreeList
+	void cleanup();
+
+	class Record
 	{
-		stop_glerror();
-		glDeleteBuffersARB(1, &name);
-		stop_glerror();
-	}
+	public:
+		U32 mGLName;
+		U8* mClientData;
+	};
+
+	typedef std::list<Record> record_list_t;
+	std::vector<record_list_t> mFreeList;
 };
 
 class LLGLFence
@@ -90,9 +99,7 @@ class LLVertexBuffer : public LLRefCount
 		S32 mIndex;
 		S32 mCount;
 		
-		MappedRegion(S32 type, S32 index, S32 count)
-			: mType(type), mIndex(index), mCount(count)
-		{ }	
+		MappedRegion(S32 type, S32 index, S32 count);
 	};
 
 	LLVertexBuffer(const LLVertexBuffer& rhs)
@@ -111,18 +118,17 @@ class LLVertexBuffer : public LLRefCount
 	static LLVBOPool sStreamIBOPool;
 	static LLVBOPool sDynamicIBOPool;
 
-	static S32	sWeight4Loc;
-
 	static BOOL	sUseStreamDraw;
+	static BOOL sUseVAO;
 	static BOOL	sPreferStreamDraw;
 
 	static void initClass(bool use_vbo, bool no_vbo_mapping);
 	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
+ 	static void unbind(); //unbind any bound vertex buffer
 
 	//get the size of a vertex with the given typemask
 	static S32 calcVertexSize(const U32& typemask);
@@ -133,24 +139,29 @@ class LLVertexBuffer : public LLRefCount
 	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
+	// 6 - update LLVertexBuffer::setupVertexArray
 	enum {
-		TYPE_VERTEX,
+		TYPE_VERTEX = 0,
 		TYPE_NORMAL,
 		TYPE_TEXCOORD0,
 		TYPE_TEXCOORD1,
 		TYPE_TEXCOORD2,
 		TYPE_TEXCOORD3,
 		TYPE_COLOR,
-		// These use VertexAttribPointer and should possibly be made generic
+		TYPE_EMISSIVE,
 		TYPE_BINORMAL,
 		TYPE_WEIGHT,
 		TYPE_WEIGHT4,
 		TYPE_CLOTHWEIGHT,
-		TYPE_MAX,
-		TYPE_INDEX,
-		
-		//no actual additional data, but indicates position.w is texture index
 		TYPE_TEXTURE_INDEX,
+		TYPE_MAX,
+		TYPE_INDEX,		
 	};
 	enum {
 		MAP_VERTEX = (1<<TYPE_VERTEX),
@@ -160,6 +171,7 @@ class LLVertexBuffer : public LLRefCount
 		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),
@@ -173,24 +185,25 @@ class LLVertexBuffer : public LLRefCount
 
 	virtual ~LLVertexBuffer(); // use unref()
 
-	virtual void setupVertexBuffer(U32 data_mask) const; // pure virtual, called from mapBuffer()
+	virtual void setupVertexBuffer(U32 data_mask); // pure virtual, called from mapBuffer()
+	void setupVertexArray();
 	
-	void	genBuffer();
-	void	genIndices();
+	void	genBuffer(U32 size);
+	void	genIndices(U32 size);
+	bool	bindGLBuffer(bool force_bind = false);
+	bool	bindGLIndices(bool force_bind = false);
+	bool	bindGLArray();
 	void	releaseBuffer();
 	void	releaseIndices();
-	void	createGLBuffer();
-	void	createGLIndices();
+	void	createGLBuffer(U32 size);
+	void	createGLIndices(U32 size);
 	void 	destroyGLBuffer();
 	void 	destroyGLIndices();
 	void	updateNumVerts(S32 nverts);
 	void	updateNumIndices(S32 nindices); 
 	virtual BOOL	useVBOs() const;
-	void	unmapBuffer(S32 type);
-	void freeClientBuffer() ;
-	void allocateClientVertexBuffer() ;
-	void allocateClientIndexBuffer() ;
-
+	void	unmapBuffer();
+		
 public:
 	LLVertexBuffer(U32 typemask, S32 usage);
 	
@@ -199,7 +212,8 @@ class LLVertexBuffer : public LLRefCount
 	U8*		mapIndexBuffer(S32 index, S32 count, bool map_range);
 
 	// set for rendering
-	virtual void	setBuffer(U32 data_mask, S32 type = -1); 	// calls  setupVertexBuffer() if data_mask is not 0
+	virtual void	setBuffer(U32 data_mask); 	// calls  setupVertexBuffer() if data_mask is not 0
+	void flush(); //flush pending data to GL memory
 	// allocate buffer
 	void	allocateBuffer(S32 nverts, S32 nindices, bool create);
 	virtual void resizeBuffer(S32 newnverts, S32 newnindices);
@@ -212,29 +226,30 @@ class LLVertexBuffer : public LLRefCount
 	//   setVertsNorms(verts, norms);
 	//   vb->unmapBuffer();
 	bool getVertexStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
+	bool getVertexStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false);
 	bool getIndexStrider(LLStrider<U16>& strider, S32 index=0, S32 count = -1, bool map_range = false);
 	bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
 	bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
 	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<LLColor4U>& 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; }
 	S32 getNumIndices() const				{ return mNumIndices; }
-	S32 getRequestedVerts() const			{ return mRequestedNumVerts; }
-	S32 getRequestedIndices() const			{ return mRequestedNumIndices; }
-
+	
 	U8* getIndicesPointer() const			{ return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }
 	U8* getVerticesPointer() const			{ return useVBOs() ? (U8*) mAlignedOffset : mMappedData; }
 	U32 getTypeMask() const					{ return mTypeMask; }
 	bool hasDataType(S32 type) const		{ return ((1 << type) & getTypeMask()); }
 	S32 getSize() const;
-	S32 getIndicesSize() const				{ return mNumIndices * sizeof(U16); }
+	S32 getIndicesSize() const				{ return mIndicesSize; }
 	U8* getMappedData() const				{ return mMappedData; }
 	U8* getMappedIndices() const			{ return mMappedIndexData; }
 	S32 getOffset(S32 type) const			{ return mOffsets[type]; }
@@ -252,25 +267,23 @@ class LLVertexBuffer : public LLRefCount
 protected:	
 	S32		mNumVerts;		// Number of vertices allocated
 	S32		mNumIndices;	// Number of indices allocated
-	S32		mRequestedNumVerts;  // Number of vertices requested
-	S32		mRequestedNumIndices;  // Number of indices requested
-
+	
 	ptrdiff_t mAlignedOffset;
 	ptrdiff_t mAlignedIndexOffset;
 	S32		mSize;
+	S32		mIndicesSize;
 	U32		mTypeMask;
 	S32		mUsage;			// GL usage
 	U32		mGLBuffer;		// GL VBO handle
 	U32		mGLIndices;		// GL IBO handle
+	U32		mGLArray;		// GL VAO handle
+	
 	U8*		mMappedData;	// pointer to currently mapped data (NULL if unmapped)
 	U8*		mMappedIndexData;	// pointer to currently mapped indices (NULL if unmapped)
 	BOOL	mVertexLocked;			// if TRUE, vertex buffer is being or has been written to in client memory
 	BOOL	mIndexLocked;			// if TRUE, index buffer is being or has been written to in client memory
 	BOOL	mFinal;			// if TRUE, buffer can not be mapped again
-	BOOL	mFilthy;		// if TRUE, entire buffer must be copied (used to prevent redundant dirty flags)
 	BOOL	mEmpty;			// if TRUE, client buffer is empty (or NULL). Old values have been discarded.	
-	BOOL	mResized;		// if TRUE, client buffer has been resized and GL buffer has not
-	BOOL	mDynamicSize;	// if TRUE, buffer has been resized at least once (and should be padded)
 	S32		mOffsets[TYPE_MAX];
 
 	std::vector<MappedRegion> mMappedVertexRegions;
@@ -290,7 +303,6 @@ class LLVertexBuffer : public LLRefCount
 	static S32 sGLCount;
 	static S32 sMappedCount;
 	static BOOL sMapped;
-	static std::vector<U32> sDeleteList;
 	typedef std::list<LLVertexBuffer*> buffer_list_t;
 		
 	static BOOL sDisableVBOMapping; //disable glMapBufferARB
@@ -298,6 +310,7 @@ class LLVertexBuffer : public LLRefCount
 	static S32 sTypeSize[TYPE_MAX];
 	static U32 sGLMode[LLRender::NUM_MODES];
 	static U32 sGLRenderBuffer;
+	static U32 sGLRenderArray;
 	static U32 sGLRenderIndices;
 	static BOOL sVBOActive;
 	static BOOL sIBOActive;
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index 4b0b7c561da6858175798772dfcc4257c9ffce0f..7a5f9f9fd6c924686d7ef14e8331f42058ff9e3a 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -973,7 +973,7 @@ void LLAccordionCtrlTab::drawChild(const LLRect& root_rect,LLView* child)
 		
 		if ( root_rect.overlaps(screen_rect)  && LLUI::sDirtyRect.overlaps(screen_rect))
 		{
-			glMatrixMode(GL_MODELVIEW);
+			gGL.matrixMode(LLRender::MM_MODELVIEW);
 			LLUI::pushMatrix();
 			{
 				LLUI::translate((F32)child->getRect().mLeft, (F32)child->getRect().mBottom, 0.f);
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 8f7025a9a66b72a1a26e2ba6b7e7475725140fdd..d232e27ef230afe3deaa0757f9149f6a4cb181fe 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1624,7 +1624,7 @@ LLNotificationPtr LLNotifications::find(LLUUID uuid)
 	LLNotificationSet::iterator it=mItems.find(target);
 	if (it == mItems.end())
 	{
-		llwarns << "Tried to dereference uuid '" << uuid << "' as a notification key but didn't find it." << llendl;
+		LL_DEBUGS("Notifications") << "Tried to dereference uuid '" << uuid << "' as a notification key but didn't find it." << llendl;
 		return LLNotificationPtr((LLNotification*)NULL);
 	}
 	else
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 79ad99a7704303214c9048cbf8f695b728c226f1..c6f7e28027745de7ea5ecbc908c5383d2ae507af 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -153,11 +153,11 @@ void gl_state_for_2d(S32 width, S32 height)
 	F32 window_width = (F32) width;//gViewerWindow->getWindowWidth();
 	F32 window_height = (F32) height;//gViewerWindow->getWindowHeight();
 
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	glOrtho(0.0f, llmax(window_width, 1.f), 0.0f, llmax(window_height,1.f), -1.0f, 1.0f);
-	glMatrixMode(GL_MODELVIEW);
-	glLoadIdentity();
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.loadIdentity();
+	gGL.ortho(0.0f, llmax(window_width, 1.f), 0.0f, llmax(window_height,1.f), -1.0f, 1.0f);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.loadIdentity();
 	stop_glerror();
 }
 
@@ -537,7 +537,7 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
 		}
 	}
 
-	gGL.getTexUnit(0)->bind(image);
+	gGL.getTexUnit(0)->bind(image, true);
 
 	gGL.color4fv(color.mV);
 	
@@ -735,7 +735,7 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
 	LLGLSUIDefault gls_ui;
 
 
-	gGL.getTexUnit(0)->bind(image);
+	gGL.getTexUnit(0)->bind(image, true);
 
 	gGL.color4fv(color.mV);
 
@@ -788,7 +788,7 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
 
 		LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD);
 		
-		gGL.getTexUnit(0)->bind(image);
+		gGL.getTexUnit(0)->bind(image, true);
 
 		gGL.color4fv(color.mV);
 		
@@ -995,10 +995,18 @@ void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha)
 	// ...gray squares
 	gGL.color4f( .7f, .7f, .7f, alpha );
 	gGL.flush();
-	glPolygonStipple( checkerboard );
 
-	LLGLEnable polygon_stipple(GL_POLYGON_STIPPLE);
-	gl_rect_2d(rect);
+	if (!LLGLSLShader::sNoFixedFunction)
+	{ //polygon stipple is deprecated
+		glPolygonStipple( checkerboard );
+
+		LLGLEnable polygon_stipple(GL_POLYGON_STIPPLE);
+		gl_rect_2d(rect);
+	}
+	else
+	{
+		gl_rect_2d(rect);
+	}
 	gGL.flush();
 }
 
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 3fd7e48428915cc6b02f39226b0f7012673369ce..1644f53978d183458d4dc99ac7c8572a0c679b56 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -1215,7 +1215,7 @@ void LLView::drawChild(LLView* childp, S32 x_offset, S32 y_offset, BOOL force_dr
 		if ((childp->getVisible() && childp->getRect().isValid()) 
 			|| force_draw)
 		{
-			glMatrixMode(GL_MODELVIEW);
+			gGL.matrixMode(LLRender::MM_MODELVIEW);
 			LLUI::pushMatrix();
 			{
 				LLUI::translate((F32)childp->getRect().mLeft + x_offset, (F32)childp->getRect().mBottom + y_offset, 0.f);
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 4dd11541b98de87a8107963877e36a93692790d1..cb2abc5bc0442a53b594f862fa90ac62f5271edb 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -1266,7 +1266,6 @@ BOOL LLWindowMacOSX::setSize(const LLCoordScreen size)
 
 void LLWindowMacOSX::swapBuffers()
 {
-	glFinish();
 	aglSwapBuffers(mContext);
 }
 
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index e41aa9820f8af37a14268901ed4409357baa8041..91689f54fdff5844c1f4e0c99b4d72aef0e7fe92 100644
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -985,7 +985,6 @@ void LLWindowSDL::swapBuffers()
 {
 	if (mWindow)
 	{	
-		glFinish();
 		SDL_GL_SwapBuffers();
 	}
 }
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 121c7880df8dd98d49910ffc608ef62ab85125f8..bac23279cc1482c4863f7d0cf926c586403cbdcf 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -41,6 +41,7 @@
 #include "llgl.h"
 #include "llstring.h"
 #include "lldir.h"
+#include "llglslshader.h"
 
 // System includes
 #include <commdlg.h>
@@ -1121,7 +1122,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
 	}
 
 	gGLManager.initWGL();
-
+	
 	if (wglChoosePixelFormatARB)
 	{
 		// OK, at this point, use the ARB wglChoosePixelFormatsARB function to see if we
@@ -1378,7 +1379,35 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
 		return FALSE;
 	}
 
-	if (!(mhRC = wglCreateContext(mhDC)))
+	mhRC = 0;
+	if (wglCreateContextAttribsARB)
+	{ //attempt to create a non-compatibility profile context
+		S32 attribs[] = 
+		{
+			WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
+			WGL_CONTEXT_MINOR_VERSION_ARB, 0,
+			WGL_CONTEXT_PROFILE_MASK_ARB,  LLRender::sGLCoreProfile ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
+			WGL_CONTEXT_FLAGS_ARB, gDebugGL ? WGL_CONTEXT_DEBUG_BIT_ARB : 0,
+			0
+		};
+
+		mhRC = wglCreateContextAttribsARB(mhDC, mhRC, attribs);
+
+		if (!mhRC)
+		{
+			attribs[1] = 3;
+			attribs[3] = 3;
+
+			mhRC = wglCreateContextAttribsARB(mhDC, mhRC, attribs);
+		}
+
+		if (mhRC)
+		{ //success, disable fixed function calls
+			LLGLSLShader::sNoFixedFunction = true;
+		}
+	}
+
+	if (!mhRC && !(mhRC = wglCreateContext(mhDC)))
 	{
 		close();
 		OSMessageBox(mCallbacks->translateString("MBGLContextErr"), mCallbacks->translateString("MBError"), OSMB_OK);
@@ -1398,7 +1427,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
 		OSMessageBox(mCallbacks->translateString("MBVideoDrvErr"), mCallbacks->translateString("MBError"), OSMB_OK);
 		return FALSE;
 	}
-
+	
 	// Disable vertical sync for swap
 	if (disable_vsync && wglSwapIntervalEXT)
 	{
@@ -2896,7 +2925,6 @@ BOOL LLWindowWin32::resetDisplayResolution()
 
 void LLWindowWin32::swapBuffers()
 {
-	glFinish();
 	SwapBuffers(mhDC);
 }
 
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 7288bf6933889f1e9c984b8102c9c822d0919fc9..37838447e19093fb48dcc53aaa86d9881bf7f5dd 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -589,7 +589,6 @@ set(viewer_SOURCE_FILES
     llvopartgroup.cpp
     llvosky.cpp
     llvosurfacepatch.cpp
-    llvotextbubble.cpp
     llvotree.cpp
     llvovolume.cpp
     llvowater.cpp
@@ -1148,7 +1147,6 @@ set(viewer_HEADER_FILES
     llvopartgroup.h
     llvosky.h
     llvosurfacepatch.h
-    llvotextbubble.h
     llvotree.h
     llvotreenew.h
     llvovolume.h
diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml
index ae72dee9002f13939ae85e7e919eb40a7749c614..a76eb3cd372d9dcf1875b042b0200ff0bae9b7db 100644
--- a/indra/newview/app_settings/logcontrol.xml
+++ b/indra/newview/app_settings/logcontrol.xml
@@ -43,7 +43,7 @@
 					<key>tags</key>
 						<array>
 							<!-- sample entry for debugging a specific item	-->
-<!--						<string>Voice</string>							-->
+<!--						<string>Voice</string>		-->
 						</array>
 				</map>
 			</array>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 3c53a9d44c3767aec23e9de601a076bdc165eb26..0acc1ba3d85dd1a3d33ced05c730f7161a199b6d 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -3137,17 +3137,6 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
-    <key>EnableRippleWater</key>
-    <map>
-      <key>Comment</key>
-      <string>Whether to use ripple water shader or not</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>1</integer>
-    </map>
     <key>EnableTextureAtlas</key>
     <map>
       <key>Comment</key>
@@ -7807,7 +7796,7 @@
     <key>Type</key>
     <string>U32</string>
     <key>Value</key>
-    <integer>6</integer>
+    <integer>16</integer>
   </map>
     <key>RenderDebugTextureBind</key>
     <map>
@@ -7879,151 +7868,7 @@
     <key>Value</key>
     <integer>0</integer>
   </map>
-
-  <key>RenderGIRange</key>
-  <map>
-    <key>Comment</key>
-    <string>Distance to cut off GI effect.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>96</real>
-  </map>
-
-  <key>RenderGILuminance</key>
-  <map>
-    <key>Comment</key>
-    <string>Luminance factor of global illumination contribution.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>0.075</real>
-  </map>
   
-  <key>RenderGIBrightness</key>
-  <map>
-    <key>Comment</key>
-    <string>Brightness factor of global illumination contribution.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>0.3</real>
-  </map>
-
-  <key>RenderGINoise</key>
-  <map>
-    <key>Comment</key>
-    <string>Noise of position sampling for GI photon mapping.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>0.7</real>
-  </map>
-
-  <key>RenderGIAttenuation</key>
-  <map>
-    <key>Comment</key>
-    <string>Distance attenuation factor for indirect lighting.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>0.1</real>
-  </map>
-
-  <key>RenderGIBlurBrightness</key>
-  <map>
-    <key>Comment</key>
-    <string>Brightness factor of global illumination blur effect.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>1.025</real>
-  </map>
-
-  <key>RenderGIBlurEdgeWeight</key>
-  <map>
-    <key>Comment</key>
-    <string>Edge weight for GI soften filter (sharpness).</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>0.8</real>
-  </map>
-
-  <key>RenderGIBlurIncrement</key>
-  <map>
-    <key>Comment</key>
-    <string>Increment of scale for each pass of global illumination blur effect.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>0.8</real>
-  </map>
-
-  <key>RenderLuminanceScale</key>
-  <map>
-    <key>Comment</key>
-    <string>Luminance value scalar for darkening effect.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>1.0</real>
-  </map>
-
-  <key>RenderSunLuminanceScale</key>
-  <map>
-    <key>Comment</key>
-    <string>Sun Luminance value scalar for darkening effect.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>1.0</real>
-  </map>
-
-  <key>RenderSunLuminanceOffset</key>
-  <map>
-    <key>Comment</key>
-    <string>Sun Luminance value offset for darkening effect.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>0</real>
-  </map>
-
-  <key>RenderLuminanceDetail</key>
-  <map>
-    <key>Comment</key>
-    <string>Mipmap level to use for luminance</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>16.0</real>
-   </map>
-
   <key>RenderMinimumLODTriangleCount</key>
   <map>
     <key>Comment</key>
@@ -8344,18 +8189,6 @@
     <integer>0</integer>
   </map>
 
-  <key>RenderDeferredGI</key>
-  <map>
-    <key>Comment</key>
-    <string>Enable GI in deferred renderer.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>Boolean</string>
-    <key>Value</key>
-    <integer>0</integer>
-  </map>
-
   <key>RenderDeferredSun</key>
   <map>
     <key>Comment</key>
@@ -8499,92 +8332,6 @@
     <real>0</real>
   </map>
 
-  <key>RenderGIAmbiance</key>
-  <map>
-    <key>Comment</key>
-    <string>Ambiance factor of global illumination contribution.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>0.5</real>
-  </map>
-
-  <key>RenderGIMinRenderSize</key>
-  <map>
-    <key>Comment</key>
-    <string>Minimum size of objects to put into GI source map.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>0.5</real>
-  </map>
-
-  <key>RenderGIBlurColorCurve</key>
-  <map>
-    <key>Comment</key>
-    <string>Color curve for GI softening kernel</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>Vector3</string>
-    <key>Value</key>
-    <array>
-      <real>1.0</real>
-      <real>0.6</real>
-      <real>0.02</real>
-    </array>
-  </map>
-
-  <key>RenderGIBlurPasses</key>
-  <map>
-    <key>Comment</key>
-    <string>Scale of GI softening kernel.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>U32</string>
-    <key>Value</key>
-    <real>4</real>
-  </map>
-
-  <key>RenderGIBlurSize</key>
-  <map>
-    <key>Comment</key>
-    <string>Scale of GI softening kernel.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>4.0</real>
-  </map>
-  <key>RenderGIBlurSamples</key>
-  <map>
-    <key>Comment</key>
-    <string>Number of samples to take for each pass of GI blur (value range 1-16).  Actual number of samples is value * 2 - 1.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>U32</string>
-    <key>Value</key>
-    <real>16</real>
-  </map>
-  <key>RenderGIBlurDistFactor</key>
-  <map>
-    <key>Comment</key>
-    <string>Distance scaler for GI blur.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>0.0</real>
-  </map>
-
   <key>RenderDynamicLOD</key>
     <map>
       <key>Comment</key>
@@ -8627,7 +8374,7 @@
       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
-      <integer>0</integer>
+      <integer>1</integer>
     </map>
     <key>RenderAutoMaskAlphaDeferred</key>
     <map>
@@ -8684,6 +8431,17 @@
       <key>Value</key>
       <real>1.0</real>
     </map>
+    <key>RenderGLCoreProfile</key>
+    <map>
+      <key>Comment</key>
+      <string>Don't use a compatibility profile OpenGL context.  Requires restart.  Basic shaders MUST be enabled.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>RenderGlow</key>
     <map>
       <key>Comment</key>
@@ -9287,6 +9045,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>RenderUseVAO</key>
+    <map>
+      <key>Comment</key>
+      <string>Use GL Vertex Array Objects</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
     <key>RenderVBOMappingDisable</key>
     <map>
       <key>Comment</key>
@@ -9296,7 +9065,7 @@
       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
-      <integer>0</integer>
+      <integer>1</integer>
     </map>
   <key>RenderUseStreamVBO</key>
   <map>
@@ -12883,10 +12652,10 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
-    <key>WindowFullScreen</key>
+    <key>FullScreen</key>
     <map>
       <key>Comment</key>
-      <string>SL viewer window full screen</string>
+      <string>run a fullscreen session</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
index c72da8d75824c92d59dfa0594e4ff9f90e6f1401..bc63d07d726ccda9dee47a148166cd0592cea4be 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
@@ -24,8 +24,7 @@
  */
  
 
-
-attribute vec4 weight;  //1
+ATTRIBUTE vec4 weight;
 
 uniform vec4 matrixPalette[45];
 
diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl
index c2fe60ddaf8daf8d7200fe369a830c41ea7cec7a..2901e18db8e68cb73ff17bbd1b4bf3bd34996343 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl
@@ -22,7 +22,15 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+uniform mat4 projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 
 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
@@ -31,32 +39,30 @@ void calcAtmospherics(vec3 inPositionEye);
 
 void main()
 {
-	gl_TexCoord[0] = gl_MultiTexCoord0;
+	vary_texcoord0 = texcoord0;
 				
 	vec4 pos;
 	vec3 norm;
 	
+	vec4 pos_in = vec4(position.xyz, 1.0);
+
 	mat4 trans = getSkinnedTransform();
-	pos.x = dot(trans[0], gl_Vertex);
-	pos.y = dot(trans[1], gl_Vertex);
-	pos.z = dot(trans[2], gl_Vertex);
+	pos.x = dot(trans[0], pos_in);
+	pos.y = dot(trans[1], pos_in);
+	pos.z = dot(trans[2], pos_in);
 	pos.w = 1.0;
 	
-	norm.x = dot(trans[0].xyz, gl_Normal);
-	norm.y = dot(trans[1].xyz, gl_Normal);
-	norm.z = dot(trans[2].xyz, gl_Normal);
+	norm.x = dot(trans[0].xyz, normal);
+	norm.y = dot(trans[1].xyz, normal);
+	norm.z = dot(trans[2].xyz, normal);
 	norm = normalize(norm);
 		
-	gl_Position = gl_ProjectionMatrix * pos;
-	
-	//gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+	gl_Position = projection_matrix * pos;
 	
-	gl_FogFragCoord = length(pos.xyz);
-
 	calcAtmospherics(pos.xyz);
 
-	vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0,0,0,0));
-	gl_FrontColor = color; 
+	vec4 color = calcLighting(pos.xyz, norm, vec4(1,1,1,1), vec4(0,0,0,0));
+	vertex_color = color; 
 
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl b/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl
index 1a0866be0a8c8292cbcd1ed16ef2b22caae068e7..82db15c3aeb0e6116a2c7d2a13c73ac6e429854c 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl
@@ -22,8 +22,19 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol);
 void calcAtmospherics(vec3 inPositionEye);
@@ -31,17 +42,18 @@ void calcAtmospherics(vec3 inPositionEye);
 void main()
 {
 	//transform vertex
-	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+	vec3 pos = (modelview_matrix * vec4(position.xyz, 1.0)).xyz;
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+	
 	
-	vec3 pos = (gl_ModelViewMatrix * gl_Vertex).xyz;
-	vec3 norm = normalize(gl_NormalMatrix * gl_Normal);
+	vec3 norm = normalize(normal_matrix * normal);
 		
 	calcAtmospherics(pos.xyz);
 
 	vec4 specular = vec4(1.0);
-	vec4 color = calcLightingSpecular(pos, norm, gl_Color, specular, vec4(0.0));	
-	gl_FrontColor = color;
+	vec4 color = calcLightingSpecular(pos, norm, diffuse_color, specular, vec4(0.0));	
+	vertex_color = color;
 
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
index 09688b2be2260f948654f25c067c519a3dc1df78..43ed41a2050c11affab3e55a044787fa7be14bf3 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
@@ -24,7 +24,7 @@
 
 
 
-attribute vec4 object_weight;  
+ATTRIBUTE vec4 weight4;  
 
 uniform mat4 matrixPalette[32];
 
@@ -32,8 +32,8 @@ mat4 getObjectSkinnedTransform()
 {
 	int i; 
 	
-	vec4 w = fract(object_weight);
-	vec4 index = floor(object_weight);
+	vec4 w = fract(weight4);
+	vec4 index = floor(weight4);
 	
 	float scale = 1.0/(w.x+w.y+w.z+w.w);
 	w *= scale;
diff --git a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl
index 374808c091121226134a1b57585437cf1e6c5a49..3e4d438ed374533d289820cf49be76e7fba43fd4 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl
@@ -22,12 +22,17 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 uniform sampler2D diffuseMap;
 
 void main() 
 {
-	gl_FragColor = vec4(gl_Color.rgb, texture2D(diffuseMap, gl_TexCoord[0].xy).a);
+	gl_FragColor = vec4(vertex_color.rgb, texture2D(diffuseMap, vary_texcoord0.xy).a);
 }
diff --git a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl
index e25d84a594c2b9bae5eb32fd3285588f4dc182b2..78b5328c9a3a16a839375ab3caa9765a1b0fd7cf 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl
@@ -22,22 +22,29 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 mat4 getSkinnedTransform();
 
 void main()
 {
 	vec4 pos;
-		
+	vec4 pos_in = vec4(position, 1.0);
 	mat4 trans = getSkinnedTransform();
-	pos.x = dot(trans[0], gl_Vertex);
-	pos.y = dot(trans[1], gl_Vertex);
-	pos.z = dot(trans[2], gl_Vertex);
+	pos.x = dot(trans[0], pos_in);
+	pos.y = dot(trans[1], pos_in);
+	pos.z = dot(trans[2], pos_in);
 	pos.w = 1.0;
 			
-	gl_FrontColor = gl_Color;
-	gl_TexCoord[0] = gl_MultiTexCoord0;
-	gl_Position = gl_ProjectionMatrix * pos;
+	vertex_color = diffuse_color;
+	vary_texcoord0 = texcoord0;
+	gl_Position = projection_matrix * pos;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
index 19de0c0b39f3048fb14552e1cd3894011c8a7369..4cca2873560e7b4fe681550b7205268ad8020c3f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
@@ -23,10 +23,12 @@
  * $/LicenseInfo$
  */
  
-
-
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform sampler2DRect depthMap;
 
 vec4 diffuseLookup(vec2 texcoord);
@@ -38,11 +40,14 @@ uniform vec2 screen_res;
 vec3 atmosLighting(vec3 light);
 vec3 scaleSoftClip(vec3 light);
 
-varying vec3 vary_ambient;
-varying vec3 vary_directional;
-varying vec3 vary_fragcoord;
-varying vec3 vary_position;
-varying vec3 vary_pointlight_col;
+VARYING vec3 vary_ambient;
+VARYING vec3 vary_directional;
+VARYING vec3 vary_fragcoord;
+VARYING vec3 vary_position;
+VARYING vec3 vary_pointlight_col;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 uniform mat4 inv_proj;
 
@@ -66,9 +71,9 @@ void main()
 	
 	vec4 pos = vec4(vary_position, 1.0);
 	
-	vec4 diff= diffuseLookup(gl_TexCoord[0].xy);
+	vec4 diff= diffuseLookup(vary_texcoord0.xy);
 
-	vec4 col = vec4(vary_ambient + vary_directional.rgb, gl_Color.a);
+	vec4 col = vec4(vary_ambient + vary_directional.rgb, vertex_color.a);
 	vec4 color = diff * col;
 	
 	color.rgb = atmosLighting(color.rgb);
@@ -78,8 +83,5 @@ void main()
 	color.rgb += diff.rgb * vary_pointlight_col.rgb;
 
 	gl_FragColor = color;
-	//gl_FragColor = vec4(1,0,1,1);
-	//gl_FragColor = vec4(1,0,1,1)*shadow;
-	
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl
index d4f56896cfa6f75bca10c07d91d626cd6092cfee..86418277775dbdc3486a9308747feeac2ca13896 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl
@@ -23,10 +23,12 @@
  * $/LicenseInfo$
  */
  
-
-
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform sampler2DRect depthMap;
 uniform sampler2D diffuseMap;
 
@@ -38,11 +40,13 @@ uniform vec2 screen_res;
 vec3 atmosLighting(vec3 light);
 vec3 scaleSoftClip(vec3 light);
 
-varying vec3 vary_ambient;
-varying vec3 vary_directional;
-varying vec3 vary_fragcoord;
-varying vec3 vary_position;
-varying vec3 vary_pointlight_col;
+VARYING vec3 vary_ambient;
+VARYING vec3 vary_directional;
+VARYING vec3 vary_fragcoord;
+VARYING vec3 vary_position;
+VARYING vec3 vary_pointlight_col;
+VARYING vec2 vary_texcoord0;
+VARYING vec4 vertex_color;
 
 uniform mat4 inv_proj;
 
@@ -66,9 +70,9 @@ void main()
 	
 	vec4 pos = vec4(vary_position, 1.0);
 	
-	vec4 diff= texture2D(diffuseMap,gl_TexCoord[0].xy);
+	vec4 diff= texture2D(diffuseMap,vary_texcoord0.xy);
 
-	vec4 col = vec4(vary_ambient + vary_directional.rgb, gl_Color.a);
+	vec4 col = vec4(vary_ambient + vary_directional.rgb, vertex_color.a);
 	vec4 color = diff * col;
 	
 	color.rgb = atmosLighting(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..c13ea702dba52be01c00a73481f3925b8fc11de5
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl
@@ -0,0 +1,84 @@
+/** 
+ * @file alphaNonIndexedNoColorF.glsl
+ *
+ * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2005, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+ 
+#extension GL_ARB_texture_rectangle : enable
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
+uniform sampler2DRect depthMap;
+uniform sampler2D diffuseMap;
+
+uniform mat4 shadow_matrix[6];
+uniform vec4 shadow_clip;
+uniform vec2 screen_res;
+
+vec3 atmosLighting(vec3 light);
+vec3 scaleSoftClip(vec3 light);
+
+VARYING vec3 vary_ambient;
+VARYING vec3 vary_directional;
+VARYING vec3 vary_fragcoord;
+VARYING vec3 vary_position;
+VARYING vec3 vary_pointlight_col;
+VARYING vec2 vary_texcoord0;
+
+uniform mat4 inv_proj;
+
+vec4 getPosition(vec2 pos_screen)
+{
+	float depth = texture2DRect(depthMap, pos_screen.xy).a;
+	vec2 sc = pos_screen.xy*2.0;
+	sc /= screen_res;
+	sc -= vec2(1.0,1.0);
+	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
+	vec4 pos = inv_proj * ndc;
+	pos /= pos.w;
+	pos.w = 1.0;
+	return pos;
+}
+
+void main() 
+{
+	vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
+	frag *= screen_res;
+	
+	vec4 pos = vec4(vary_position, 1.0);
+	
+	vec4 diff= texture2D(diffuseMap,vary_texcoord0.xy);
+
+	vec4 col = vec4(vary_ambient + vary_directional.rgb, 1.0);
+	vec4 color = diff * col;
+	
+	color.rgb = atmosLighting(color.rgb);
+
+	color.rgb = scaleSoftClip(color.rgb);
+
+	color.rgb += diff.rgb * vary_pointlight_col.rgb;
+
+	gl_FragColor = color;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl
index d57b8f8525e9c15b28e549d168caf21dcc6d59cb..b09441f7eb92e27222fa46f7647f7e42c2ff339f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl
@@ -21,8 +21,14 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 projection_matrix;
+uniform mat4 modelview_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
 
 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
 mat4 getObjectSkinnedTransform();
@@ -35,15 +41,23 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);
 vec3 scaleDownLight(vec3 light);
 vec3 scaleUpLight(vec3 light);
 
-varying vec3 vary_position;
-varying vec3 vary_ambient;
-varying vec3 vary_directional;
-varying vec3 vary_normal;
-varying vec3 vary_fragcoord;
-varying vec3 vary_pointlight_col;
+VARYING vec3 vary_position;
+VARYING vec3 vary_ambient;
+VARYING vec3 vary_directional;
+VARYING vec3 vary_normal;
+VARYING vec3 vary_fragcoord;
+VARYING vec3 vary_pointlight_col;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
 
 uniform float near_clip;
 
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec3 light_attenuation[8]; 
+uniform vec3 light_diffuse[8];
+
 float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
 {
 	//get light vector
@@ -76,20 +90,20 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
 
 void main()
 {
-	gl_TexCoord[0] = gl_MultiTexCoord0;
+	vary_texcoord0 = texcoord0;
 				
 	vec4 pos;
 	vec3 norm;
 	
 	mat4 trans = getObjectSkinnedTransform();
-	trans = gl_ModelViewMatrix * trans;
+	trans = modelview_matrix * trans;
 	
-	pos = trans * gl_Vertex;
+	pos = trans * vec4(position.xyz, 1.0);
 	
-	norm = gl_Vertex.xyz + gl_Normal.xyz;
+	norm = position.xyz + normal.xyz;
 	norm = normalize(( trans*vec4(norm, 1.0) ).xyz-pos.xyz);
 	
-	vec4 frag_pos = gl_ProjectionMatrix * pos;
+	vec4 frag_pos = projection_matrix * pos;
 	gl_Position = frag_pos;
 	
 	vary_position = pos.xyz;
@@ -97,31 +111,31 @@ void main()
 	
 	calcAtmospherics(pos.xyz);
 
-	vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);
+	vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
 
 	// Collect normal lights
-	col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation, gl_LightSource[2].specular.a);
-	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation ,gl_LightSource[3].specular.a);
-	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation, gl_LightSource[4].specular.a);
-	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].quadraticAttenuation, gl_LightSource[5].specular.a);
-	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].quadraticAttenuation, gl_LightSource[6].specular.a);
-	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].quadraticAttenuation, gl_LightSource[7].specular.a);
-	
-	vary_pointlight_col = col.rgb*gl_Color.rgb;
+	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
+	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
+	col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
+	col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
+	col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
+	col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
+
+	vary_pointlight_col = col.rgb*diffuse_color.rgb;
 
 	col.rgb = vec3(0,0,0);
 
 	// Add windlight lights
 	col.rgb = atmosAmbient(vec3(0.));
 	
-	vary_ambient = col.rgb*gl_Color.rgb;
-	vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a)));
+	vary_ambient = col.rgb*diffuse_color.rgb;
+	vary_directional = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
 	
-	col.rgb = min(col.rgb*gl_Color.rgb, 1.0);
+	col.rgb = min(col.rgb*diffuse_color.rgb, 1.0);
 	
-	gl_FrontColor = col;
+	vertex_color = col;
 
-	gl_FogFragCoord = pos.z;
+	
 	
 	vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
index f6a280462e133464eec35bd1d1e63ac7e3858478..93b1a114db1148970743dda57f4c39e8368e6f17 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
@@ -23,7 +23,16 @@
  * $/LicenseInfo$
  */
 
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
 
+ATTRIBUTE vec3 position;
+void passTextureIndex();
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
 
 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
 void calcAtmospherics(vec3 inPositionEye);
@@ -35,18 +44,26 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);
 vec3 scaleDownLight(vec3 light);
 vec3 scaleUpLight(vec3 light);
 
-varying vec3 vary_ambient;
-varying vec3 vary_directional;
-varying vec3 vary_fragcoord;
-varying vec3 vary_position;
-varying vec3 vary_light;
-varying vec3 vary_pointlight_col;
-varying float vary_texture_index;
+VARYING vec3 vary_ambient;
+VARYING vec3 vary_directional;
+VARYING vec3 vary_fragcoord;
+VARYING vec3 vary_position;
+VARYING vec3 vary_light;
+VARYING vec3 vary_pointlight_col;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
 
 uniform float near_clip;
 uniform float shadow_offset;
 uniform float shadow_bias;
 
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec3 light_attenuation[8]; 
+uniform vec3 light_diffuse[8];
+
 float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
 {
 	//get light vector
@@ -80,50 +97,50 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
 void main()
 {
 	//transform vertex
-	vec4 vert = vec4(gl_Vertex.xyz, 1.0);
-	vary_texture_index = gl_Vertex.w;
-	gl_Position = gl_ModelViewProjectionMatrix * vert; 
+	vec4 vert = vec4(position.xyz, 1.0);
+	passTextureIndex();
+	vec4 pos = (modelview_matrix * vert);
+	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
 	
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 	
-	vec4 pos = (gl_ModelViewMatrix * vert);
-	vec3 norm = normalize(gl_NormalMatrix * gl_Normal);
+	vec3 norm = normalize(normal_matrix * normal);
 	
-	float dp_directional_light = max(0.0, dot(norm, gl_LightSource[0].position.xyz));
-	vary_position = pos.xyz + gl_LightSource[0].position.xyz * (1.0-dp_directional_light)*shadow_offset;
+	float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));
+	vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset;
 		
 	calcAtmospherics(pos.xyz);
 
-	//vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.));
-	vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);
+	//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
+	vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
 
 	// Collect normal lights
-	col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation, gl_LightSource[2].specular.a);
-	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation ,gl_LightSource[3].specular.a);
-	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation, gl_LightSource[4].specular.a);
-	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].quadraticAttenuation, gl_LightSource[5].specular.a);
-	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].quadraticAttenuation, gl_LightSource[6].specular.a);
-	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].quadraticAttenuation, gl_LightSource[7].specular.a);
+	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
+	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
+	col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
+	col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
+	col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
+	col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
 	
-	vary_pointlight_col = col.rgb*gl_Color.rgb;
+	vary_pointlight_col = col.rgb*diffuse_color.rgb;
 
 	col.rgb = vec3(0,0,0);
 
 	// Add windlight lights
 	col.rgb = atmosAmbient(vec3(0.));
 	
-	vary_light = gl_LightSource[0].position.xyz;
+	vary_light = light_position[0].xyz;
 	
-	vary_ambient = col.rgb*gl_Color.rgb;
-	vary_directional.rgb = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a)));
+	vary_ambient = col.rgb*diffuse_color.rgb;
+	vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
 	
-	col.rgb = col.rgb*gl_Color.rgb;
+	col.rgb = col.rgb*diffuse_color.rgb;
 	
-	gl_FrontColor = col;
+	vertex_color = col;
 
-	gl_FogFragCoord = pos.z;
 	
-	pos = gl_ModelViewProjectionMatrix * vert;
+	
+	pos = modelview_projection_matrix * vert;
 	vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
 	
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl
index 0c930848e58e09f3ad8074acdad57caa489f589e..402f681631061aad16d10457d7d1316bd19d6cce 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl
@@ -22,14 +22,18 @@
  * $/LicenseInfo$
  */
 
-
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
 uniform sampler2D diffuseMap;
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 void main() 
 {
-	//gl_FragColor = vec4(1,1,1,gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy).a);
+	//gl_FragColor = vec4(1,1,1,vertex_color.a * texture2D(diffuseMap, vary_texcoord0.xy).a);
 	gl_FragColor = vec4(1,1,1,1);
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
index bf4e79d815e3106d98d89b5385b35dfdcbfbc5f7..533babf3dc264a2d5807d51f3a25dce3250c7bb8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
@@ -22,23 +22,32 @@
  * $/LicenseInfo$
  */
 
+uniform mat4 projection_matrix;
+uniform mat4 modelview_matrix;
+uniform mat4 texture_matrix0;
 
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 mat4 getObjectSkinnedTransform();
 
 void main()
 {
 	//transform vertex
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 	
 	mat4 mat = getObjectSkinnedTransform();
 	
-	mat = gl_ModelViewMatrix * mat;
-	vec3 pos = (mat*gl_Vertex).xyz;
+	mat = modelview_matrix * mat;
+	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
 	
-	gl_FrontColor = gl_Color;
+	vertex_color = diffuse_color;
 	
-	vec4 p = gl_ProjectionMatrix * vec4(pos, 1.0);
+	vec4 p = projection_matrix * vec4(pos, 1.0);
 	p.z = max(p.z, -p.w+0.01);
 	gl_Position = p;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl
index f70ea4da526afecaf1172b3b7f7975da6536ad10..acbc3f7e156c7467f2ff6abb28dc347112b24c28 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl
@@ -22,8 +22,12 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
 
 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
 mat4 getSkinnedTransform();
@@ -37,14 +41,22 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);
 vec3 scaleDownLight(vec3 light);
 vec3 scaleUpLight(vec3 light);
 
-varying vec3 vary_position;
-varying vec3 vary_ambient;
-varying vec3 vary_directional;
-varying vec3 vary_fragcoord;
-varying vec3 vary_pointlight_col;
+VARYING vec3 vary_position;
+VARYING vec3 vary_ambient;
+VARYING vec3 vary_directional;
+VARYING vec3 vary_fragcoord;
+VARYING vec3 vary_pointlight_col;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
 
 uniform float near_clip;
 
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec3 light_attenuation[8]; 
+uniform vec3 light_diffuse[8];
+
 float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
 {
 	//get light vector
@@ -77,56 +89,55 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
 
 void main()
 {
-	gl_TexCoord[0] = gl_MultiTexCoord0;
+	vary_texcoord0 = texcoord0;
 				
 	vec4 pos;
 	vec3 norm;
 	
 	mat4 trans = getSkinnedTransform();
-	pos.x = dot(trans[0], gl_Vertex);
-	pos.y = dot(trans[1], gl_Vertex);
-	pos.z = dot(trans[2], gl_Vertex);
+	vec4 pos_in = vec4(position.xyz, 1.0);
+	pos.x = dot(trans[0], pos_in);
+	pos.y = dot(trans[1], pos_in);
+	pos.z = dot(trans[2], pos_in);
 	pos.w = 1.0;
 	
-	norm.x = dot(trans[0].xyz, gl_Normal);
-	norm.y = dot(trans[1].xyz, gl_Normal);
-	norm.z = dot(trans[2].xyz, gl_Normal);
+	norm.x = dot(trans[0].xyz, normal);
+	norm.y = dot(trans[1].xyz, normal);
+	norm.z = dot(trans[2].xyz, normal);
 	norm = normalize(norm);
 		
-	vec4 frag_pos = gl_ProjectionMatrix * pos;
+	vec4 frag_pos = projection_matrix * pos;
 	gl_Position = frag_pos;
 	
 	vary_position = pos.xyz;
 	
 	calcAtmospherics(pos.xyz);
 
-	//vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.));
-
-	vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);
+	vec4 col = vec4(0.0, 0.0, 0.0, 1.0);
 
 	// Collect normal lights
-	col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation, gl_LightSource[2].specular.a);
-	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation ,gl_LightSource[3].specular.a);
-	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation, gl_LightSource[4].specular.a);
-	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].quadraticAttenuation, gl_LightSource[5].specular.a);
-	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].quadraticAttenuation, gl_LightSource[6].specular.a);
-	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].quadraticAttenuation, gl_LightSource[7].specular.a);
+	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
+	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
+	col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
+	col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
+	col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
+	col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
 	
-	vary_pointlight_col = col.rgb*gl_Color.rgb;
+	vary_pointlight_col = col.rgb;
 
 	col.rgb = vec3(0,0,0);
 
 	// Add windlight lights
 	col.rgb = atmosAmbient(vec3(0.));
 	
-	vary_ambient = col.rgb*gl_Color.rgb;
-	vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a)));
+	vary_ambient = col.rgb;
+	vary_directional = atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), 0.0));
 	
-	col.rgb = min(col.rgb*gl_Color.rgb, 1.0);
+	col.rgb = min(col.rgb, 1.0);
 	
-	gl_FrontColor = col;
+	vertex_color = col;
 
-	gl_FogFragCoord = pos.z;
+	
 	
 	vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl
index d0f33979325dfdb8ff268b620c1c3cdef117fb7d..01ffb862f70e9aed4a1a342fee2ec1706264214a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl
@@ -22,18 +22,27 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
 
-varying vec3 vary_normal;
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec3 vary_normal;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 void main()
 {
 	//transform vertex
-	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); 
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 	
-	vary_normal = normalize(gl_NormalMatrix * gl_Normal);
+	vary_normal = normalize(normal_matrix * normal);
 
-	gl_FrontColor = gl_Color;
+	vertex_color = diffuse_color;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
index 3f30402583d9cd23c4854e63f6dcd8af4951cdcc..9a3b2e3e8a52e0735761aa037f8ade84d5cc3b4f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
@@ -22,16 +22,19 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragData[3];
+#endif
 
 uniform sampler2D diffuseMap;
 
-varying vec3 vary_normal;
+VARYING vec3 vary_normal;
+VARYING vec2 vary_texcoord0;
 
 void main() 
 {
-	vec4 diff = gl_Color*texture2D(diffuseMap, gl_TexCoord[0].xy);
+	vec4 diff = texture2D(diffuseMap, vary_texcoord0.xy);
 	
 	if (diff.a < 0.2)
 	{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
index c9a349f0263b041a17f021b21d5e56df75366c9b..558a88009aada4d4bf2b7c2ae9807275ecede98c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
@@ -23,15 +23,16 @@
  * $/LicenseInfo$
  */
  
-
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
 uniform sampler2D diffuseMap;
 
-varying vec4 post_pos;
+VARYING vec4 post_pos;
 
 void main() 
 {
-	//gl_FragColor = vec4(1,1,1,gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy).a);
 	gl_FragColor = vec4(1,1,1,1);
 
 	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
index 3d2ad397dfb86fc2ff465a9753aad9aeed0842d2..525acbe4ea907d28f01d9e47cba904a855b6df7a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
@@ -23,38 +23,40 @@
  * $/LicenseInfo$
  */
  
-
+uniform mat4 projection_matrix;
 
 mat4 getSkinnedTransform();
 
-attribute vec4 weight;
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
 
-varying vec4 post_pos;
+VARYING vec4 post_pos;
+VARYING vec2 vary_texcoord0;
 
 void main()
 {
-	gl_TexCoord[0] = gl_MultiTexCoord0;
+	vary_texcoord0 = texcoord0;
 				
 	vec4 pos;
 	vec3 norm;
 	
+	vec4 pos_in = vec4(position.xyz, 1.0);
 	mat4 trans = getSkinnedTransform();
-	pos.x = dot(trans[0], gl_Vertex);
-	pos.y = dot(trans[1], gl_Vertex);
-	pos.z = dot(trans[2], gl_Vertex);
+	pos.x = dot(trans[0], pos_in);
+	pos.y = dot(trans[1], pos_in);
+	pos.z = dot(trans[2], pos_in);
 	pos.w = 1.0;
 	
-	norm.x = dot(trans[0].xyz, gl_Normal);
-	norm.y = dot(trans[1].xyz, gl_Normal);
-	norm.z = dot(trans[2].xyz, gl_Normal);
+	norm.x = dot(trans[0].xyz, normal);
+	norm.y = dot(trans[1].xyz, normal);
+	norm.z = dot(trans[2].xyz, normal);
 	norm = normalize(norm);
 	
-	pos = gl_ProjectionMatrix * pos;
+	pos = projection_matrix * pos;
 	post_pos = pos;
 
 	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-	
-	gl_FrontColor = gl_Color;
 }
 
 
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl
index 37fcef81f3f9de0418ae7ecc7f773f95d2ac5601..1bd8fee7c974949ee9e43f1f520ec441c7cc6644 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl
@@ -23,38 +23,41 @@
  * $/LicenseInfo$
  */
  
+uniform mat4 projection_matrix;
 
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
 
 mat4 getSkinnedTransform();
 
-attribute vec4 weight;
+ATTRIBUTE vec4 weight;
 
-varying vec3 vary_normal;
+VARYING vec3 vary_normal;
+VARYING vec2 vary_texcoord0;
 
 void main()
 {
-	gl_TexCoord[0] = gl_MultiTexCoord0;
+	vary_texcoord0 = texcoord0;
 				
 	vec4 pos;
 	vec3 norm;
 	
+	vec4 pos_in = vec4(position.xyz, 1.0);
 	mat4 trans = getSkinnedTransform();
-	pos.x = dot(trans[0], gl_Vertex);
-	pos.y = dot(trans[1], gl_Vertex);
-	pos.z = dot(trans[2], gl_Vertex);
+	pos.x = dot(trans[0], pos_in);
+	pos.y = dot(trans[1], pos_in);
+	pos.z = dot(trans[2], pos_in);
 	pos.w = 1.0;
 	
-	norm.x = dot(trans[0].xyz, gl_Normal);
-	norm.y = dot(trans[1].xyz, gl_Normal);
-	norm.z = dot(trans[2].xyz, gl_Normal);
+	norm.x = dot(trans[0].xyz, normal);
+	norm.y = dot(trans[1].xyz, normal);
+	norm.z = dot(trans[2].xyz, normal);
 	norm = normalize(norm);
 	
 	vary_normal = norm;
 	
-	gl_Position = gl_ProjectionMatrix * pos;
-	//gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;	
-	
-	gl_FrontColor = gl_Color;
+	gl_Position = projection_matrix * pos;
 }
 
 
diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
index 3609cc054b9980b596d2dfcfb297998e9bbeca4c..7d3b546d3e64f6989295e80f38492c50d9131af3 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
@@ -22,11 +22,13 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
-
 
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform sampler2DRect depthMap;
 uniform sampler2DRect normalMap;
 uniform sampler2DRect lightMap;
@@ -37,7 +39,7 @@ uniform vec2 delta;
 uniform vec3 kern[4];
 uniform float kern_scale;
 
-varying vec2 vary_fragcoord;
+VARYING vec2 vary_fragcoord;
 
 uniform mat4 inv_proj;
 uniform vec2 screen_res;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightMSF.glsl
deleted file mode 100644
index c858eb7a3a8e3fe2424e34f03dc208617fd09ace..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/blurLightMSF.glsl
+++ /dev/null
@@ -1,131 +0,0 @@
-/** 
- * @file blurLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_texture_multisample : enable
-
-uniform sampler2DMS depthMap;
-uniform sampler2DMS normalMap;
-uniform sampler2DRect lightMap;
-
-uniform float dist_factor;
-uniform float blur_size;
-uniform vec2 delta;
-uniform vec3 kern[4];
-uniform float kern_scale;
-
-varying vec2 vary_fragcoord;
-
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-vec3 texture2DMS3(sampler2DMS tex, ivec2 tc)
-{
-	vec3 ret = vec3(0,0,0);
-	for (int i = 0; i < samples; i++)
-	{
-		ret += texelFetch(tex, tc, i).rgb;
-	}
-
-	return ret/samples;
-}
-
-float texture2DMS1(sampler2DMS tex, ivec2 tc)
-{
-	float ret = 0;
-	for (int i = 0; i < samples; i++)
-	{
-		ret += texelFetch(tex, tc, i).r;
-	}
-
-	return ret/samples;
-}
-
-vec4 getPosition(ivec2 pos_screen)
-{
-	float depth = texture2DMS1(depthMap, pos_screen.xy);
-	vec2 sc = pos_screen.xy*2.0;
-	sc /= screen_res;
-	sc -= vec2(1.0,1.0);
-	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
-	vec4 pos = inv_proj * ndc;
-	pos /= pos.w;
-	pos.w = 1.0;
-	return pos;
-}
-
-void main() 
-{
-    vec2 tc = vary_fragcoord.xy;
-	ivec2 itc = ivec2(tc);
-
-	vec3 norm = texture2DMS3(normalMap, itc).xyz;
-	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
-	vec3 pos = getPosition(itc).xyz;
-	vec4 ccol = texture2DRect(lightMap, tc).rgba;
-	
-	vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy);
-	dlt /= max(-pos.z*dist_factor, 1.0);
-	
-	vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
-	vec4 col = defined_weight.xyxx * ccol;
-
-	// relax tolerance according to distance to avoid speckling artifacts, as angles and distances are a lot more abrupt within a small screen area at larger distances
-	float pointplanedist_tolerance_pow2 = pos.z*pos.z*0.00005;
-
-	// perturb sampling origin slightly in screen-space to hide edge-ghosting artifacts where smoothing radius is quite large
-	tc += ( (mod(tc.x+tc.y,2) - 0.5) * kern[1].z * dlt * 0.5 );
-
-	for (int i = 1; i < 4; i++)
-	{
-		vec2 samptc = tc + kern[i].z*dlt;
-		vec3 samppos = getPosition(ivec2(samptc)).xyz; 
-		float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
-		if (d*d <= pointplanedist_tolerance_pow2)
-		{
-			col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
-			defined_weight += kern[i].xy;
-		}
-	}
-	for (int i = 1; i < 4; i++)
-	{
-		vec2 samptc = vec2(tc - kern[i].z*dlt);
-		vec3 samppos = getPosition(ivec2(samptc)).xyz; 
-		float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
-		if (d*d <= pointplanedist_tolerance_pow2)
-		{
-			col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
-			defined_weight += kern[i].xy;
-		}
-	}
-
-	col /= defined_weight.xyxx;
-	col.y *= col.y;
-
-	gl_FragColor = col;
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl
index e904b7ded006c69cd7a6bb9b022d8f4e7ba2e423..212f7e56adff95dc365e2673f47b416045361411 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl
@@ -22,16 +22,18 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 modelview_projection_matrix;
 
-varying vec2 vary_fragcoord;
+ATTRIBUTE vec3 position;
+
+VARYING vec2 vary_fragcoord;
 uniform vec2 screen_res;
 
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform(); 
-	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
+	vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	gl_Position = pos; 
 	vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
index 429a891f0734b5579a8daa9f3b8c399a5de0e2cb..6cc5f23acaf43f64103b221b15949ba91dd25616 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
@@ -23,27 +23,32 @@
  * $/LicenseInfo$
  */
  
-
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragData[3];
+#endif
 
 uniform sampler2D diffuseMap;
 uniform sampler2D bumpMap;
 
-varying vec3 vary_mat0;
-varying vec3 vary_mat1;
-varying vec3 vary_mat2;
+VARYING vec3 vary_mat0;
+VARYING vec3 vary_mat1;
+VARYING vec3 vary_mat2;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 void main() 
 {
-	vec3 col = gl_Color.rgb * texture2D(diffuseMap, gl_TexCoord[0].xy).rgb;
-	vec3 norm = texture2D(bumpMap, gl_TexCoord[0].xy).rgb * 2.0 - 1.0;
+	vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb;
+	vec3 norm = texture2D(bumpMap, vary_texcoord0.xy).rgb * 2.0 - 1.0;
 
 	vec3 tnorm = vec3(dot(norm,vary_mat0),
 			  dot(norm,vary_mat1),
 			  dot(norm,vary_mat2));
 						
 	gl_FragData[0] = vec4(col, 0.0);
-	gl_FragData[1] = gl_Color.aaaa; // spec
-	//gl_FragData[1] = vec4(vec3(gl_Color.a), gl_Color.a+(1.0-gl_Color.a)*gl_Color.a); // spec - from former class3 - maybe better, but not so well tested
+	gl_FragData[1] = vertex_color.aaaa; // spec
+	//gl_FragData[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
 	vec3 nvn = normalize(tnorm);
 	gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl
index 7d934e7ff836f1353d21de682fa3eb2c49c5f602..6c205074b4e623fb83b296f58a3d58a04dd8b125 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl
@@ -22,33 +22,43 @@
  * $/LicenseInfo$
  */
 
+uniform mat4 projection_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
 
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec2 texcoord2;
 
-varying vec3 vary_mat0;
-varying vec3 vary_mat1;
-varying vec3 vary_mat2;
+VARYING vec3 vary_mat0;
+VARYING vec3 vary_mat1;
+VARYING vec3 vary_mat2;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 mat4 getObjectSkinnedTransform();
 
 void main()
 {
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 	
 	mat4 mat = getObjectSkinnedTransform();
 	
-	mat = gl_ModelViewMatrix * mat;
+	mat = modelview_matrix * mat;
 	
-	vec3 pos = (mat*gl_Vertex).xyz;
+	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
 	
 	
-	vec3 n = normalize((mat * vec4(gl_Normal.xyz+gl_Vertex.xyz, 1.0)).xyz-pos.xyz);
-	vec3 b = normalize((mat * vec4(gl_MultiTexCoord2.xyz+gl_Vertex.xyz, 1.0)).xyz-pos.xyz);
+	vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz);
+	vec3 b = normalize((mat * vec4(vec4(texcoord2,0,1).xyz+position.xyz, 1.0)).xyz-pos.xyz);
 	vec3 t = cross(b, n);
 	
 	vary_mat0 = vec3(t.x, b.x, n.x);
 	vary_mat1 = vec3(t.y, b.y, n.y);
 	vary_mat2 = vec3(t.z, b.z, n.z);
 	
-	gl_Position = gl_ProjectionMatrix*vec4(pos, 1.0);
-	gl_FrontColor = gl_Color;
+	gl_Position = projection_matrix*vec4(pos, 1.0);
+	vertex_color = diffuse_color;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl
index 92fd41554db63f0ce9290a1ae7c70aa978279100..c8d38bb8f74e72dd4ad681f1fb43b94cec2f6b00 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl
@@ -22,26 +22,36 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
 
-varying vec3 vary_mat0;
-varying vec3 vary_mat1;
-varying vec3 vary_mat2;
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec3 binormal;
+
+VARYING vec3 vary_mat0;
+VARYING vec3 vary_mat1;
+VARYING vec3 vary_mat2;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform(); 
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); 
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 	
-	vec3 n = normalize(gl_NormalMatrix * gl_Normal);
-	vec3 b = normalize(gl_NormalMatrix * gl_MultiTexCoord2.xyz);
+	vec3 n = normalize(normal_matrix * normal);
+	vec3 b = normalize(normal_matrix * binormal);
 	vec3 t = cross(b, n);
 	
 	vary_mat0 = vec3(t.x, b.x, n.x);
 	vary_mat1 = vec3(t.y, b.y, n.y);
 	vary_mat2 = vec3(t.z, b.z, n.z);
 	
-	gl_FrontColor = gl_Color;
+	vertex_color = diffuse_color;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
index f4310dae958796b181a132ff98192ffabad5ebe5..db272cf601efe783fc0f3a280d07824ab1f29e6a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
@@ -24,20 +24,28 @@
  */
  
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragData[3];
+#endif
 
 /////////////////////////////////////////////////////////////////////////
 // The fragment shader for the sky
 /////////////////////////////////////////////////////////////////////////
 
-varying vec4 vary_CloudColorSun;
-varying vec4 vary_CloudColorAmbient;
-varying float vary_CloudDensity;
+VARYING vec4 vary_CloudColorSun;
+VARYING vec4 vary_CloudColorAmbient;
+VARYING float vary_CloudDensity;
 
 uniform sampler2D cloud_noise_texture;
 uniform vec4 cloud_pos_density1;
 uniform vec4 cloud_pos_density2;
 uniform vec4 gamma;
 
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
+VARYING vec2 vary_texcoord3;
+
 /// Soft clips the light with a gamma correction
 vec3 scaleSoftClip(vec3 light) {
 	//soft clip effect:
@@ -50,14 +58,14 @@ vec3 scaleSoftClip(vec3 light) {
 void main()
 {
 	// Set variables
-	vec2 uv1 = gl_TexCoord[0].xy;
-	vec2 uv2 = gl_TexCoord[1].xy;
+	vec2 uv1 = vary_texcoord0.xy;
+	vec2 uv2 = vary_texcoord1.xy;
 
 	vec4 cloudColorSun = vary_CloudColorSun;
 	vec4 cloudColorAmbient = vary_CloudColorAmbient;
 	float cloudDensity = vary_CloudDensity;
-	vec2 uv3 = gl_TexCoord[2].xy;
-	vec2 uv4 = gl_TexCoord[3].xy;
+	vec2 uv3 = vary_texcoord2.xy;
+	vec2 uv4 = vary_texcoord3.xy;
 
 	// Offset texture coords
 	uv1 += cloud_pos_density1.xy;	//large texture, visible density
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
index c175a834c23386c0e5c866fdf0aaf57efd74b078..64e094e3c5b13e1e6d3e8c627a5d2b8efd451477 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
@@ -22,17 +22,25 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
 
 //////////////////////////////////////////////////////////////////////////
 // The vertex shader for creating the atmospheric sky
 ///////////////////////////////////////////////////////////////////////////////
 
 // Output parameters
-varying vec4 vary_CloudColorSun;
-varying vec4 vary_CloudColorAmbient;
-varying float vary_CloudDensity;
+VARYING vec4 vary_CloudColorSun;
+VARYING vec4 vary_CloudColorAmbient;
+VARYING float vary_CloudDensity;
+
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
+VARYING vec2 vary_texcoord3;
 
 // Inputs
 uniform vec3 camPosLocal;
@@ -59,12 +67,12 @@ void main()
 {
 
 	// World / view / projection
-	gl_Position = ftransform();
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
 
-	gl_TexCoord[0] = gl_MultiTexCoord0;
+	vary_texcoord0 = texcoord0;
 
 	// Get relative position
-	vec3 P = gl_Vertex.xyz - camPosLocal.xyz + vec3(0,50,0);
+	vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0);
 
 	// Set altitude
 	if (P.y > 0.)
@@ -160,17 +168,17 @@ void main()
 
 
 	// Texture coords
-	gl_TexCoord[0] = gl_MultiTexCoord0;
-	gl_TexCoord[0].xy -= 0.5;
-	gl_TexCoord[0].xy /= cloud_scale.x;
-	gl_TexCoord[0].xy += 0.5;
+	vary_texcoord0 = texcoord0;
+	vary_texcoord0.xy -= 0.5;
+	vary_texcoord0.xy /= cloud_scale.x;
+	vary_texcoord0.xy += 0.5;
 
-	gl_TexCoord[1] = gl_TexCoord[0];
-	gl_TexCoord[1].x += lightnorm.x * 0.0125;
-	gl_TexCoord[1].y += lightnorm.z * 0.0125;
+	vary_texcoord1 = vary_texcoord0;
+	vary_texcoord1.x += lightnorm.x * 0.0125;
+	vary_texcoord1.y += lightnorm.z * 0.0125;
 
-	gl_TexCoord[2] = gl_TexCoord[0] * 16.;
-	gl_TexCoord[3] = gl_TexCoord[1] * 16.;
+	vary_texcoord2 = vary_texcoord0 * 16.;
+	vary_texcoord3 = vary_texcoord1 * 16.;
 
 	// Combine these to minimize register use
 	vary_CloudColorAmbient += oHazeColorBelowCloud;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
index 933e50fed148d8808782596e86dfd27a0bf2fb64..14b79c37fd25120eea29f384c94ce7901ac4ce40 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
@@ -1,5 +1,5 @@
 /** 
- * @file diffuseF.glsl
+ * @file diffuseAlphaMaskF.glsl
  *
  * $LicenseInfo:firstyear=2011&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -22,18 +22,23 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragData[3];
+#endif
 
 uniform float minimum_alpha;
 uniform float maximum_alpha;
 
 uniform sampler2D diffuseMap;
 
-varying vec3 vary_normal;
+VARYING vec3 vary_normal;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 void main() 
 {
-	vec4 col = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color;
+	vec4 col = texture2D(diffuseMap, vary_texcoord0.xy) * vertex_color;
 	
 	if (col.a < minimum_alpha || col.a > maximum_alpha)
 	{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
index f3ad6f92de58686a6bdf79d7f7a3b40fa04a6a24..381fba8813e99ea4fbea82c555408d21676e5ffa 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
@@ -22,15 +22,22 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
-varying vec3 vary_normal;
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragData[3];
+#endif
+
+VARYING vec3 vary_normal;
 
 uniform float minimum_alpha;
 uniform float maximum_alpha;
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
 void main() 
 {
-	vec4 col = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;
+	vec4 col = diffuseLookup(vary_texcoord0.xy) * vertex_color;
 	
 	if (col.a < minimum_alpha || col.a > maximum_alpha)
 	{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..b582ba7f9c5309fd9a13f34391baea94faf031e5
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
@@ -0,0 +1,53 @@
+/** 
+ * @file diffuseAlphaMaskNoColorF.glsl
+ *
+ * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2005, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+ 
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragData[3];
+#endif
+
+uniform float minimum_alpha;
+uniform float maximum_alpha;
+
+uniform sampler2D diffuseMap;
+
+VARYING vec3 vary_normal;
+VARYING vec2 vary_texcoord0;
+
+void main() 
+{
+	vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
+	
+	if (col.a < minimum_alpha || col.a > maximum_alpha)
+	{
+		discard;
+	}
+
+	gl_FragData[0] = vec4(col.rgb, 0.0);
+	gl_FragData[1] = vec4(0,0,0,0); // spec
+	vec3 nvn = normalize(vary_normal);
+	gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
index 9c9a8b56c59085b950fe7d8201c25133fceff97a..7bde49eb86b9b647af9631f3f076ff7ab3283143 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
@@ -23,18 +23,22 @@
  * $/LicenseInfo$
  */
  
-
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragData[3];
+#endif
 
 uniform sampler2D diffuseMap;
 
-varying vec3 vary_normal;
+VARYING vec3 vary_normal;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 void main() 
 {
-	vec3 col = gl_Color.rgb * texture2D(diffuseMap, gl_TexCoord[0].xy).rgb;
+	vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb;
 	gl_FragData[0] = vec4(col, 0.0);
-	gl_FragData[1] = gl_Color.aaaa; // spec
-	//gl_FragData[1] = vec4(vec3(gl_Color.a), gl_Color.a+(1.0-gl_Color.a)*gl_Color.a); // spec - from former class3 - maybe better, but not so well tested
+	gl_FragData[1] = vertex_color.aaaa; // spec
+	//gl_FragData[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
 	vec3 nvn = normalize(vary_normal);
 	gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
index 4d996a099dcfdf00edff08c4d2b1436af1c94134..75b45111e0e40247ab1abdde7f93eded58f45c98 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
@@ -22,16 +22,22 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
-varying vec3 vary_normal;
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragData[3];
+#endif
+
+VARYING vec3 vary_normal;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 void main() 
 {
-	vec3 col = gl_Color.rgb * diffuseLookup(gl_TexCoord[0].xy).rgb;
+	vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
 
 	gl_FragData[0] = vec4(col, 0.0);
-	gl_FragData[1] = gl_Color.aaaa; // spec
-	//gl_FragData[1] = vec4(vec3(gl_Color.a), gl_Color.a+(1.0-gl_Color.a)*gl_Color.a); // spec - from former class3 - maybe better, but not so well tested
+	gl_FragData[1] = vertex_color.aaaa; // spec
+	//gl_FragData[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
 	vec3 nvn = normalize(vary_normal);
 	gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseNoColorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseNoColorV.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..9461e3e32e52ee78d018925fd0c7d936932dfd96
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseNoColorV.glsl
@@ -0,0 +1,45 @@
+/** 
+ * @file diffuseNoColorV.glsl
+ *
+  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix; 
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec3 vary_normal;
+
+VARYING vec2 vary_texcoord0;
+
+void main()
+{
+	//transform vertex
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); 
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+	
+	vary_normal = normalize(normal_matrix * normal);
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl
index 1470d7c9ca8bcbfbf4427f8e8acd0712fe03ab13..a74290bfcd0c60ba2f123e535f862ed017e18f62 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl
@@ -22,29 +22,38 @@
  * $/LicenseInfo$
  */
 
+uniform mat4 projection_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
 
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
 
-varying vec3 vary_normal;
+VARYING vec3 vary_normal;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 mat4 getObjectSkinnedTransform();
 
 void main()
 {
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 	
 	mat4 mat = getObjectSkinnedTransform();
 	
-	mat = gl_ModelViewMatrix * mat;
-	vec3 pos = (mat*gl_Vertex).xyz;
+	mat = modelview_matrix * mat;
+	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
 	
-	vec4 norm = gl_Vertex;
-	norm.xyz += gl_Normal.xyz;
+	vec4 norm = vec4(position.xyz, 1.0);
+	norm.xyz += normal.xyz;
 	norm.xyz = (mat*norm).xyz;
 	norm.xyz = normalize(norm.xyz-pos.xyz);
 
 	vary_normal = norm.xyz;
 			
-	gl_FrontColor = gl_Color;
+	vertex_color = diffuse_color;
 	
-	gl_Position = gl_ProjectionMatrix*vec4(pos, 1.0);
+	gl_Position = projection_matrix*vec4(pos, 1.0);
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
index 7c5a4d35b380e05fb85e63b1db9684c9c521892e..76d29b1df7dce0986ccdbe508f33cd13a42b1fdd 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
@@ -22,20 +22,31 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
 
-varying vec3 vary_normal;
-varying float vary_texture_index;
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec3 vary_normal;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+void passTextureIndex();
 
 void main()
 {
 	//transform vertex
-	gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz, 1.0); 
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); 
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 	
-	vary_texture_index = gl_Vertex.w;
-	vary_normal = normalize(gl_NormalMatrix * gl_Normal);
+	passTextureIndex();
+	vary_normal = normalize(normal_matrix * normal);
 
-	gl_FrontColor = gl_Color;
+	vertex_color = diffuse_color;
 }
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
similarity index 73%
rename from indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl
rename to indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
index f03b1fdc749102c3976ed93de01afb145d5a01fd..92f78125d840a56cee60026fca694c68c4a81fde 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
@@ -1,9 +1,9 @@
 /** 
- * @file lightFullbrightF.glsl
+ * @file emissiveF.glsl
  *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2005, Linden Research, Inc.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -23,17 +23,26 @@
  * $/LicenseInfo$
  */
  
+#extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
 vec3 fullbrightAtmosTransport(vec3 light);
 vec3 fullbrightScaleSoftClip(vec3 light);
 
-void fullbright_lighting()
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+void main() 
 {
-	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;
+	float shadow = 1.0;
+
+	vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
 	
 	color.rgb = fullbrightAtmosTransport(color.rgb);
-	
+
 	color.rgb = fullbrightScaleSoftClip(color.rgb);
 
 	gl_FragColor = color;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..115b04797f8a1bfc346cc14057f08d77f9d47d82
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl
@@ -0,0 +1,63 @@
+/** 
+ * @file emissiveV.glsl
+ *
+  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+void passTextureIndex();
+ATTRIBUTE vec4 emissive;
+ATTRIBUTE vec2 texcoord0;
+
+void calcAtmospherics(vec3 inPositionEye);
+
+vec3 atmosAmbient(vec3 light);
+vec3 atmosAffectDirectionalLight(float lightIntensity);
+vec3 scaleDownLight(vec3 light);
+vec3 scaleUpLight(vec3 light);
+
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+
+void main()
+{
+	//transform vertex
+	vec4 vert = vec4(position.xyz, 1.0);
+	vec4 pos = (modelview_matrix * vert);
+	passTextureIndex();
+
+	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+	
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+	
+	calcAtmospherics(pos.xyz);
+	
+	vertex_color = emissive;
+
+	
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
index 6c506676afd2ced5770dc4cefad12a8ce8f824ca..84ae2f9f109f180a6ab49a71bf75a57cbd2d1ea4 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
@@ -23,9 +23,14 @@
  * $/LicenseInfo$
  */
  
+#extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
-#extension GL_ARB_texture_rectangle : enable
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 vec3 fullbrightAtmosTransport(vec3 light);
 vec3 fullbrightScaleSoftClip(vec3 light);
@@ -35,7 +40,7 @@ void main()
 {
 	float shadow = 1.0;
 
-	vec4 color = diffuseLookup(gl_TexCoord[0].xy)*gl_Color;
+	vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
 	
 	color.rgb = fullbrightAtmosTransport(color.rgb);
 
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
index a4ff0b80e2df9b14fb601d032a3f1a30c6350c32..2e6982d101791c337bb96c3775a40cdd0912a821 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
@@ -22,8 +22,16 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+
+ATTRIBUTE vec3 position;
+void passTextureIndex();
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
 
 void calcAtmospherics(vec3 inPositionEye);
 
@@ -32,23 +40,25 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);
 vec3 scaleDownLight(vec3 light);
 vec3 scaleUpLight(vec3 light);
 
-varying float vary_texture_index;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
 
 void main()
 {
 	//transform vertex
-	vec4 vert = vec4(gl_Vertex.xyz, 1.0);
-	vary_texture_index = gl_Vertex.w;
+	vec4 vert = vec4(position.xyz, 1.0);
+	vec4 pos = (modelview_matrix * vert);
+	passTextureIndex();
 
-	gl_Position = gl_ModelViewProjectionMatrix*vert; 
+	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
 	
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 	
-	vec4 pos = (gl_ModelViewMatrix * vert);
-				
 	calcAtmospherics(pos.xyz);
 	
-	gl_FrontColor = gl_Color;
+	vertex_color = diffuse_color;
 
-	gl_FogFragCoord = pos.z;
+	
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..5af94064526d59ab9faaa5b92a8e53cbf5d8a889
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl
@@ -0,0 +1,2118 @@
+/** 
+ * @file fxaaF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+ 
+#extension GL_ARB_texture_rectangle : enable
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
+#define FXAA_PC 1
+//#define FXAA_GLSL_130 1
+#define FXAA_QUALITY__PRESET 12
+
+/*============================================================================
+
+
+                    NVIDIA FXAA 3.11 by TIMOTHY LOTTES
+
+
+------------------------------------------------------------------------------
+COPYRIGHT (C) 2010, 2011 NVIDIA CORPORATION. ALL RIGHTS RESERVED.
+------------------------------------------------------------------------------
+TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
+*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA
+OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR
+CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR
+LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION,
+OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE
+THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+------------------------------------------------------------------------------
+                           INTEGRATION CHECKLIST
+------------------------------------------------------------------------------
+(1.)
+In the shader source, setup defines for the desired configuration.
+When providing multiple shaders (for different presets),
+simply setup the defines differently in multiple files.
+Example,
+
+  #define FXAA_PC 1
+  #define FXAA_HLSL_5 1
+  #define FXAA_QUALITY__PRESET 12
+
+Or,
+
+  #define FXAA_360 1
+  
+Or,
+
+  #define FXAA_PS3 1
+  
+Etc.
+
+(2.)
+Then include this file,
+
+  #include "Fxaa3_11.h"
+
+(3.)
+Then call the FXAA pixel shader from within your desired shader.
+Look at the FXAA Quality FxaaPixelShader() for docs on inputs.
+As for FXAA 3.11 all inputs for all shaders are the same 
+to enable easy porting between platforms.
+
+  return FxaaPixelShader(...);
+
+(4.)
+Insure pass prior to FXAA outputs RGBL (see next section).
+Or use,
+
+  #define FXAA_GREEN_AS_LUMA 1
+
+(5.)
+Setup engine to provide the following constants
+which are used in the FxaaPixelShader() inputs,
+
+  FxaaFloat2 fxaaQualityRcpFrame,
+  FxaaFloat4 fxaaConsoleRcpFrameOpt,
+  FxaaFloat4 fxaaConsoleRcpFrameOpt2,
+  FxaaFloat4 fxaaConsole360RcpFrameOpt2,
+  FxaaFloat fxaaQualitySubpix,
+  FxaaFloat fxaaQualityEdgeThreshold,
+  FxaaFloat fxaaQualityEdgeThresholdMin,
+  FxaaFloat fxaaConsoleEdgeSharpness,
+  FxaaFloat fxaaConsoleEdgeThreshold,
+  FxaaFloat fxaaConsoleEdgeThresholdMin,
+  FxaaFloat4 fxaaConsole360ConstDir
+
+Look at the FXAA Quality FxaaPixelShader() for docs on inputs.
+
+(6.)
+Have FXAA vertex shader run as a full screen triangle,
+and output "pos" and "fxaaConsolePosPos" 
+such that inputs in the pixel shader provide,
+
+  // {xy} = center of pixel
+  FxaaFloat2 pos,
+
+  // {xy__} = upper left of pixel
+  // {__zw} = lower right of pixel
+  FxaaFloat4 fxaaConsolePosPos,
+
+(7.)
+Insure the texture sampler(s) used by FXAA are set to bilinear filtering.
+
+
+------------------------------------------------------------------------------
+                    INTEGRATION - RGBL AND COLORSPACE
+------------------------------------------------------------------------------
+FXAA3 requires RGBL as input unless the following is set, 
+
+  #define FXAA_GREEN_AS_LUMA 1
+
+In which case the engine uses green in place of luma,
+and requires RGB input is in a non-linear colorspace.
+
+RGB should be LDR (low dynamic range).
+Specifically do FXAA after tonemapping.
+
+RGB data as returned by a texture fetch can be non-linear,
+or linear when FXAA_GREEN_AS_LUMA is not set.
+Note an "sRGB format" texture counts as linear,
+because the result of a texture fetch is linear data.
+Regular "RGBA8" textures in the sRGB colorspace are non-linear.
+
+If FXAA_GREEN_AS_LUMA is not set,
+luma must be stored in the alpha channel prior to running FXAA.
+This luma should be in a perceptual space (could be gamma 2.0).
+Example pass before FXAA where output is gamma 2.0 encoded,
+
+  color.rgb = ToneMap(color.rgb); // linear color output
+  color.rgb = sqrt(color.rgb);    // gamma 2.0 color output
+  return color;
+
+To use FXAA,
+
+  color.rgb = ToneMap(color.rgb);  // linear color output
+  color.rgb = sqrt(color.rgb);     // gamma 2.0 color output
+  color.a = dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114)); // compute luma
+  return color;
+
+Another example where output is linear encoded,
+say for instance writing to an sRGB formated render target,
+where the render target does the conversion back to sRGB after blending,
+
+  color.rgb = ToneMap(color.rgb); // linear color output
+  return color;
+
+To use FXAA,
+
+  color.rgb = ToneMap(color.rgb); // linear color output
+  color.a = sqrt(dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114))); // compute luma
+  return color;
+
+Getting luma correct is required for the algorithm to work correctly.
+
+
+------------------------------------------------------------------------------
+                          BEING LINEARLY CORRECT?
+------------------------------------------------------------------------------
+Applying FXAA to a framebuffer with linear RGB color will look worse.
+This is very counter intuitive, but happends to be true in this case.
+The reason is because dithering artifacts will be more visiable 
+in a linear colorspace.
+
+
+------------------------------------------------------------------------------
+                             COMPLEX INTEGRATION
+------------------------------------------------------------------------------
+Q. What if the engine is blending into RGB before wanting to run FXAA?
+
+A. In the last opaque pass prior to FXAA,
+   have the pass write out luma into alpha.
+   Then blend into RGB only.
+   FXAA should be able to run ok
+   assuming the blending pass did not any add aliasing.
+   This should be the common case for particles and common blending passes.
+
+A. Or use FXAA_GREEN_AS_LUMA.
+
+============================================================================*/
+
+/*============================================================================
+
+                             INTEGRATION KNOBS
+
+============================================================================*/
+//
+// FXAA_PS3 and FXAA_360 choose the console algorithm (FXAA3 CONSOLE).
+// FXAA_360_OPT is a prototype for the new optimized 360 version.
+//
+// 1 = Use API.
+// 0 = Don't use API.
+//
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_PS3
+    #define FXAA_PS3 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_360
+    #define FXAA_360 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_360_OPT
+    #define FXAA_360_OPT 0
+#endif
+/*==========================================================================*/
+#ifndef FXAA_PC
+    //
+    // FXAA Quality
+    // The high quality PC algorithm.
+    //
+    #define FXAA_PC 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_PC_CONSOLE
+    //
+    // The console algorithm for PC is included
+    // for developers targeting really low spec machines.
+    // Likely better to just run FXAA_PC, and use a really low preset.
+    //
+    #define FXAA_PC_CONSOLE 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_GLSL_120
+    #define FXAA_GLSL_120 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_GLSL_130
+    #define FXAA_GLSL_130 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_HLSL_3
+    #define FXAA_HLSL_3 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_HLSL_4
+    #define FXAA_HLSL_4 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_HLSL_5
+    #define FXAA_HLSL_5 0
+#endif
+/*==========================================================================*/
+#ifndef FXAA_GREEN_AS_LUMA
+    //
+    // For those using non-linear color,
+    // and either not able to get luma in alpha, or not wanting to,
+    // this enables FXAA to run using green as a proxy for luma.
+    // So with this enabled, no need to pack luma in alpha.
+    //
+    // This will turn off AA on anything which lacks some amount of green.
+    // Pure red and blue or combination of only R and B, will get no AA.
+    //
+    // Might want to lower the settings for both,
+    //    fxaaConsoleEdgeThresholdMin
+    //    fxaaQualityEdgeThresholdMin
+    // In order to insure AA does not get turned off on colors 
+    // which contain a minor amount of green.
+    //
+    // 1 = On.
+    // 0 = Off.
+    //
+    #define FXAA_GREEN_AS_LUMA 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_EARLY_EXIT
+    //
+    // Controls algorithm's early exit path.
+    // On PS3 turning this ON adds 2 cycles to the shader.
+    // On 360 turning this OFF adds 10ths of a millisecond to the shader.
+    // Turning this off on console will result in a more blurry image.
+    // So this defaults to on.
+    //
+    // 1 = On.
+    // 0 = Off.
+    //
+    #define FXAA_EARLY_EXIT 1
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_DISCARD
+    //
+    // Only valid for PC OpenGL currently.
+    // Probably will not work when FXAA_GREEN_AS_LUMA = 1.
+    //
+    // 1 = Use discard on pixels which don't need AA.
+    //     For APIs which enable concurrent TEX+ROP from same surface.
+    // 0 = Return unchanged color on pixels which don't need AA.
+    //
+    #define FXAA_DISCARD 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_FAST_PIXEL_OFFSET
+    //
+    // Used for GLSL 120 only.
+    //
+    // 1 = GL API supports fast pixel offsets
+    // 0 = do not use fast pixel offsets
+    //
+    #ifdef GL_EXT_gpu_shader4
+        #define FXAA_FAST_PIXEL_OFFSET 1
+    #endif
+    #ifdef GL_NV_gpu_shader5
+        #define FXAA_FAST_PIXEL_OFFSET 1
+    #endif
+    #ifdef GL_ARB_gpu_shader5
+        #define FXAA_FAST_PIXEL_OFFSET 1
+    #endif
+    #ifndef FXAA_FAST_PIXEL_OFFSET
+        #define FXAA_FAST_PIXEL_OFFSET 0
+    #endif
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_GATHER4_ALPHA
+    //
+    // 1 = API supports gather4 on alpha channel.
+    // 0 = API does not support gather4 on alpha channel.
+    //
+    #if (FXAA_HLSL_5 == 1)
+        #define FXAA_GATHER4_ALPHA 1
+    #endif
+    #ifdef GL_ARB_gpu_shader5
+        #define FXAA_GATHER4_ALPHA 1
+    #endif
+    #ifdef GL_NV_gpu_shader5
+        #define FXAA_GATHER4_ALPHA 1
+    #endif
+    #ifndef FXAA_GATHER4_ALPHA
+        #define FXAA_GATHER4_ALPHA 0
+    #endif
+#endif
+
+/*============================================================================
+                      FXAA CONSOLE PS3 - TUNING KNOBS
+============================================================================*/
+#ifndef FXAA_CONSOLE__PS3_EDGE_SHARPNESS
+    //
+    // Consoles the sharpness of edges on PS3 only.
+    // Non-PS3 tuning is done with shader input.
+    //
+    // Due to the PS3 being ALU bound,
+    // there are only two safe values here: 4 and 8.
+    // These options use the shaders ability to a free *|/ by 2|4|8.
+    //
+    // 8.0 is sharper
+    // 4.0 is softer
+    // 2.0 is really soft (good for vector graphics inputs)
+    //
+    #if 1
+        #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 8.0
+    #endif
+    #if 0
+        #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 4.0
+    #endif
+    #if 0
+        #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 2.0
+    #endif
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_CONSOLE__PS3_EDGE_THRESHOLD
+    //
+    // Only effects PS3.
+    // Non-PS3 tuning is done with shader input.
+    //
+    // The minimum amount of local contrast required to apply algorithm.
+    // The console setting has a different mapping than the quality setting.
+    //
+    // This only applies when FXAA_EARLY_EXIT is 1.
+    //
+    // Due to the PS3 being ALU bound,
+    // there are only two safe values here: 0.25 and 0.125.
+    // These options use the shaders ability to a free *|/ by 2|4|8.
+    //
+    // 0.125 leaves less aliasing, but is softer
+    // 0.25 leaves more aliasing, and is sharper
+    //
+    #if 1
+        #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.125
+    #else
+        #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.25
+    #endif
+#endif
+
+/*============================================================================
+                        FXAA QUALITY - TUNING KNOBS
+------------------------------------------------------------------------------
+NOTE the other tuning knobs are now in the shader function inputs!
+============================================================================*/
+#ifndef FXAA_QUALITY__PRESET
+    //
+    // Choose the quality preset.
+    // This needs to be compiled into the shader as it effects code.
+    // Best option to include multiple presets is to 
+    // in each shader define the preset, then include this file.
+    // 
+    // OPTIONS
+    // -----------------------------------------------------------------------
+    // 10 to 15 - default medium dither (10=fastest, 15=highest quality)
+    // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality)
+    // 39       - no dither, very expensive 
+    //
+    // NOTES
+    // -----------------------------------------------------------------------
+    // 12 = slightly faster then FXAA 3.9 and higher edge quality (default)
+    // 13 = about same speed as FXAA 3.9 and better than 12
+    // 23 = closest to FXAA 3.9 visually and performance wise
+    //  _ = the lowest digit is directly related to performance
+    // _  = the highest digit is directly related to style
+    // 
+    #define FXAA_QUALITY__PRESET 12
+#endif
+
+
+/*============================================================================
+
+                           FXAA QUALITY - PRESETS
+
+============================================================================*/
+
+/*============================================================================
+                     FXAA QUALITY - MEDIUM DITHER PRESETS
+============================================================================*/
+#if (FXAA_QUALITY__PRESET == 10)
+    #define FXAA_QUALITY__PS 3
+    #define FXAA_QUALITY__P0 1.5
+    #define FXAA_QUALITY__P1 3.0
+    #define FXAA_QUALITY__P2 12.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 11)
+    #define FXAA_QUALITY__PS 4
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 3.0
+    #define FXAA_QUALITY__P3 12.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 12)
+    #define FXAA_QUALITY__PS 5
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 4.0
+    #define FXAA_QUALITY__P4 12.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 13)
+    #define FXAA_QUALITY__PS 6
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 4.0
+    #define FXAA_QUALITY__P5 12.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 14)
+    #define FXAA_QUALITY__PS 7
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 2.0
+    #define FXAA_QUALITY__P5 4.0
+    #define FXAA_QUALITY__P6 12.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 15)
+    #define FXAA_QUALITY__PS 8
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 2.0
+    #define FXAA_QUALITY__P5 2.0
+    #define FXAA_QUALITY__P6 4.0
+    #define FXAA_QUALITY__P7 12.0
+#endif
+
+/*============================================================================
+                     FXAA QUALITY - LOW DITHER PRESETS
+============================================================================*/
+#if (FXAA_QUALITY__PRESET == 20)
+    #define FXAA_QUALITY__PS 3
+    #define FXAA_QUALITY__P0 1.5
+    #define FXAA_QUALITY__P1 2.0
+    #define FXAA_QUALITY__P2 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 21)
+    #define FXAA_QUALITY__PS 4
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 22)
+    #define FXAA_QUALITY__PS 5
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 23)
+    #define FXAA_QUALITY__PS 6
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 2.0
+    #define FXAA_QUALITY__P5 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 24)
+    #define FXAA_QUALITY__PS 7
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 2.0
+    #define FXAA_QUALITY__P5 3.0
+    #define FXAA_QUALITY__P6 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 25)
+    #define FXAA_QUALITY__PS 8
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 2.0
+    #define FXAA_QUALITY__P5 2.0
+    #define FXAA_QUALITY__P6 4.0
+    #define FXAA_QUALITY__P7 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 26)
+    #define FXAA_QUALITY__PS 9
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 2.0
+    #define FXAA_QUALITY__P5 2.0
+    #define FXAA_QUALITY__P6 2.0
+    #define FXAA_QUALITY__P7 4.0
+    #define FXAA_QUALITY__P8 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 27)
+    #define FXAA_QUALITY__PS 10
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 2.0
+    #define FXAA_QUALITY__P5 2.0
+    #define FXAA_QUALITY__P6 2.0
+    #define FXAA_QUALITY__P7 2.0
+    #define FXAA_QUALITY__P8 4.0
+    #define FXAA_QUALITY__P9 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 28)
+    #define FXAA_QUALITY__PS 11
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 2.0
+    #define FXAA_QUALITY__P5 2.0
+    #define FXAA_QUALITY__P6 2.0
+    #define FXAA_QUALITY__P7 2.0
+    #define FXAA_QUALITY__P8 2.0
+    #define FXAA_QUALITY__P9 4.0
+    #define FXAA_QUALITY__P10 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 29)
+    #define FXAA_QUALITY__PS 12
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 2.0
+    #define FXAA_QUALITY__P5 2.0
+    #define FXAA_QUALITY__P6 2.0
+    #define FXAA_QUALITY__P7 2.0
+    #define FXAA_QUALITY__P8 2.0
+    #define FXAA_QUALITY__P9 2.0
+    #define FXAA_QUALITY__P10 4.0
+    #define FXAA_QUALITY__P11 8.0
+#endif
+
+/*============================================================================
+                     FXAA QUALITY - EXTREME QUALITY
+============================================================================*/
+#if (FXAA_QUALITY__PRESET == 39)
+    #define FXAA_QUALITY__PS 12
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.0
+    #define FXAA_QUALITY__P2 1.0
+    #define FXAA_QUALITY__P3 1.0
+    #define FXAA_QUALITY__P4 1.0
+    #define FXAA_QUALITY__P5 1.5
+    #define FXAA_QUALITY__P6 2.0
+    #define FXAA_QUALITY__P7 2.0
+    #define FXAA_QUALITY__P8 2.0
+    #define FXAA_QUALITY__P9 2.0
+    #define FXAA_QUALITY__P10 4.0
+    #define FXAA_QUALITY__P11 8.0
+#endif
+
+
+
+/*============================================================================
+
+                                API PORTING
+
+============================================================================*/
+#if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1)
+    #define FxaaBool bool
+    #define FxaaDiscard discard
+    #define FxaaFloat float
+    #define FxaaFloat2 vec2
+    #define FxaaFloat3 vec3
+    #define FxaaFloat4 vec4
+    #define FxaaHalf float
+    #define FxaaHalf2 vec2
+    #define FxaaHalf3 vec3
+    #define FxaaHalf4 vec4
+    #define FxaaInt2 ivec2
+    #define FxaaSat(x) clamp(x, 0.0, 1.0)
+    #define FxaaTex sampler2D
+#else
+    #define FxaaBool bool
+    #define FxaaDiscard clip(-1)
+    #define FxaaFloat float
+    #define FxaaFloat2 float2
+    #define FxaaFloat3 float3
+    #define FxaaFloat4 float4
+    #define FxaaHalf half
+    #define FxaaHalf2 half2
+    #define FxaaHalf3 half3
+    #define FxaaHalf4 half4
+    #define FxaaSat(x) saturate(x)
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_GLSL_120 == 1)
+    // Requires,
+    //  #version 120
+    // And at least,
+    //  #extension GL_EXT_gpu_shader4 : enable
+    //  (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9)
+    #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0)
+    #if (FXAA_FAST_PIXEL_OFFSET == 1)
+        #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)
+    #else
+        #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0)
+    #endif
+    #if (FXAA_GATHER4_ALPHA == 1)
+        // use #extension GL_ARB_gpu_shader5 : enable
+        #define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
+        #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
+        #define FxaaTexGreen4(t, p) textureGather(t, p, 1)
+        #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)
+    #endif
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_GLSL_130 == 1)
+    // Requires "#version 130" or better
+    #define FxaaTexTop(t, p) textureLod(t, p, 0.0)
+    #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)
+    #if (FXAA_GATHER4_ALPHA == 1)
+        // use #extension GL_ARB_gpu_shader5 : enable
+        #define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
+        #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
+        #define FxaaTexGreen4(t, p) textureGather(t, p, 1)
+        #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)
+    #endif
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_HLSL_3 == 1) || (FXAA_360 == 1) || (FXAA_PS3 == 1)
+    #define FxaaInt2 float2
+    #define FxaaTex sampler2D
+    #define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0))
+    #define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0))
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_HLSL_4 == 1)
+    #define FxaaInt2 int2
+    struct FxaaTex { SamplerState smpl; Texture2D tex; };
+    #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
+    #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_HLSL_5 == 1)
+    #define FxaaInt2 int2
+    struct FxaaTex { SamplerState smpl; Texture2D tex; };
+    #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
+    #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)
+    #define FxaaTexAlpha4(t, p) t.tex.GatherAlpha(t.smpl, p)
+    #define FxaaTexOffAlpha4(t, p, o) t.tex.GatherAlpha(t.smpl, p, o)
+    #define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p)
+    #define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o)
+#endif
+
+
+/*============================================================================
+                   GREEN AS LUMA OPTION SUPPORT FUNCTION
+============================================================================*/
+#if (FXAA_GREEN_AS_LUMA == 0)
+    FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; }
+#else
+    FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; }
+#endif    
+
+
+
+
+/*============================================================================
+
+                             FXAA3 QUALITY - PC
+
+============================================================================*/
+#if (FXAA_PC == 1)
+/*--------------------------------------------------------------------------*/
+FxaaFloat4 FxaaPixelShader(
+    //
+    // Use noperspective interpolation here (turn off perspective interpolation).
+    // {xy} = center of pixel
+    FxaaFloat2 pos,
+    //
+    // Used only for FXAA Console, and not used on the 360 version.
+    // Use noperspective interpolation here (turn off perspective interpolation).
+    // {xy__} = upper left of pixel
+    // {__zw} = lower right of pixel
+    FxaaFloat4 fxaaConsolePosPos,
+    //
+    // Input color texture.
+    // {rgb_} = color in linear or perceptual color space
+    // if (FXAA_GREEN_AS_LUMA == 0)
+    //     {___a} = luma in perceptual color space (not linear)
+    FxaaTex tex,
+    //
+    // Only used on the optimized 360 version of FXAA Console.
+    // For everything but 360, just use the same input here as for "tex".
+    // For 360, same texture, just alias with a 2nd sampler.
+    // This sampler needs to have an exponent bias of -1.
+    FxaaTex fxaaConsole360TexExpBiasNegOne,
+    //
+    // Only used on the optimized 360 version of FXAA Console.
+    // For everything but 360, just use the same input here as for "tex".
+    // For 360, same texture, just alias with a 3nd sampler.
+    // This sampler needs to have an exponent bias of -2.
+    FxaaTex fxaaConsole360TexExpBiasNegTwo,
+    //
+    // Only used on FXAA Quality.
+    // This must be from a constant/uniform.
+    // {x_} = 1.0/screenWidthInPixels
+    // {_y} = 1.0/screenHeightInPixels
+    FxaaFloat2 fxaaQualityRcpFrame,
+    //
+    // Only used on FXAA Console.
+    // This must be from a constant/uniform.
+    // This effects sub-pixel AA quality and inversely sharpness.
+    //   Where N ranges between,
+    //     N = 0.50 (default)
+    //     N = 0.33 (sharper)
+    // {x___} = -N/screenWidthInPixels  
+    // {_y__} = -N/screenHeightInPixels
+    // {__z_} =  N/screenWidthInPixels  
+    // {___w} =  N/screenHeightInPixels 
+    FxaaFloat4 fxaaConsoleRcpFrameOpt,
+    //
+    // Only used on FXAA Console.
+    // Not used on 360, but used on PS3 and PC.
+    // This must be from a constant/uniform.
+    // {x___} = -2.0/screenWidthInPixels  
+    // {_y__} = -2.0/screenHeightInPixels
+    // {__z_} =  2.0/screenWidthInPixels  
+    // {___w} =  2.0/screenHeightInPixels 
+    FxaaFloat4 fxaaConsoleRcpFrameOpt2,
+    //
+    // Only used on FXAA Console.
+    // Only used on 360 in place of fxaaConsoleRcpFrameOpt2.
+    // This must be from a constant/uniform.
+    // {x___} =  8.0/screenWidthInPixels  
+    // {_y__} =  8.0/screenHeightInPixels
+    // {__z_} = -4.0/screenWidthInPixels  
+    // {___w} = -4.0/screenHeightInPixels 
+    FxaaFloat4 fxaaConsole360RcpFrameOpt2,
+    //
+    // Only used on FXAA Quality.
+    // This used to be the FXAA_QUALITY__SUBPIX define.
+    // It is here now to allow easier tuning.
+    // Choose the amount of sub-pixel aliasing removal.
+    // This can effect sharpness.
+    //   1.00 - upper limit (softer)
+    //   0.75 - default amount of filtering
+    //   0.50 - lower limit (sharper, less sub-pixel aliasing removal)
+    //   0.25 - almost off
+    //   0.00 - completely off
+    FxaaFloat fxaaQualitySubpix,
+    //
+    // Only used on FXAA Quality.
+    // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define.
+    // It is here now to allow easier tuning.
+    // The minimum amount of local contrast required to apply algorithm.
+    //   0.333 - too little (faster)
+    //   0.250 - low quality
+    //   0.166 - default
+    //   0.125 - high quality 
+    //   0.063 - overkill (slower)
+    FxaaFloat fxaaQualityEdgeThreshold,
+    //
+    // Only used on FXAA Quality.
+    // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define.
+    // It is here now to allow easier tuning.
+    // Trims the algorithm from processing darks.
+    //   0.0833 - upper limit (default, the start of visible unfiltered edges)
+    //   0.0625 - high quality (faster)
+    //   0.0312 - visible limit (slower)
+    // Special notes when using FXAA_GREEN_AS_LUMA,
+    //   Likely want to set this to zero.
+    //   As colors that are mostly not-green
+    //   will appear very dark in the green channel!
+    //   Tune by looking at mostly non-green content,
+    //   then start at zero and increase until aliasing is a problem.
+    FxaaFloat fxaaQualityEdgeThresholdMin,
+    // 
+    // Only used on FXAA Console.
+    // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define.
+    // It is here now to allow easier tuning.
+    // This does not effect PS3, as this needs to be compiled in.
+    //   Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3.
+    //   Due to the PS3 being ALU bound,
+    //   there are only three safe values here: 2 and 4 and 8.
+    //   These options use the shaders ability to a free *|/ by 2|4|8.
+    // For all other platforms can be a non-power of two.
+    //   8.0 is sharper (default!!!)
+    //   4.0 is softer
+    //   2.0 is really soft (good only for vector graphics inputs)
+    FxaaFloat fxaaConsoleEdgeSharpness,
+    //
+    // Only used on FXAA Console.
+    // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define.
+    // It is here now to allow easier tuning.
+    // This does not effect PS3, as this needs to be compiled in.
+    //   Use FXAA_CONSOLE__PS3_EDGE_THRESHOLD for PS3.
+    //   Due to the PS3 being ALU bound,
+    //   there are only two safe values here: 1/4 and 1/8.
+    //   These options use the shaders ability to a free *|/ by 2|4|8.
+    // The console setting has a different mapping than the quality setting.
+    // Other platforms can use other values.
+    //   0.125 leaves less aliasing, but is softer (default!!!)
+    //   0.25 leaves more aliasing, and is sharper
+    FxaaFloat fxaaConsoleEdgeThreshold,
+    //
+    // Only used on FXAA Console.
+    // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD_MIN define.
+    // It is here now to allow easier tuning.
+    // Trims the algorithm from processing darks.
+    // The console setting has a different mapping than the quality setting.
+    // This only applies when FXAA_EARLY_EXIT is 1.
+    // This does not apply to PS3, 
+    // PS3 was simplified to avoid more shader instructions.
+    //   0.06 - faster but more aliasing in darks
+    //   0.05 - default
+    //   0.04 - slower and less aliasing in darks
+    // Special notes when using FXAA_GREEN_AS_LUMA,
+    //   Likely want to set this to zero.
+    //   As colors that are mostly not-green
+    //   will appear very dark in the green channel!
+    //   Tune by looking at mostly non-green content,
+    //   then start at zero and increase until aliasing is a problem.
+    FxaaFloat fxaaConsoleEdgeThresholdMin,
+    //    
+    // Extra constants for 360 FXAA Console only.
+    // Use zeros or anything else for other platforms.
+    // These must be in physical constant registers and NOT immedates.
+    // Immedates will result in compiler un-optimizing.
+    // {xyzw} = float4(1.0, -1.0, 0.25, -0.25)
+    FxaaFloat4 fxaaConsole360ConstDir
+) {
+/*--------------------------------------------------------------------------*/
+    FxaaFloat2 posM;
+    posM.x = pos.x;
+    posM.y = pos.y;
+    #if (FXAA_GATHER4_ALPHA == 1)
+        #if (FXAA_DISCARD == 0)
+            FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);
+            #if (FXAA_GREEN_AS_LUMA == 0)
+                #define lumaM rgbyM.w
+            #else
+                #define lumaM rgbyM.y
+            #endif
+        #endif
+        #if (FXAA_GREEN_AS_LUMA == 0)
+            FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM);
+            FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1));
+        #else
+            FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM);
+            FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1));
+        #endif
+        #if (FXAA_DISCARD == 1)
+            #define lumaM luma4A.w
+        #endif
+        #define lumaE luma4A.z
+        #define lumaS luma4A.x
+        #define lumaSE luma4A.y
+        #define lumaNW luma4B.w
+        #define lumaN luma4B.z
+        #define lumaW luma4B.x
+    #else
+        FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);
+        #if (FXAA_GREEN_AS_LUMA == 0)
+            #define lumaM rgbyM.w
+        #else
+            #define lumaM rgbyM.y
+        #endif
+        FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy));
+        FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy));
+        FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy));
+        FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy));
+    #endif
+/*--------------------------------------------------------------------------*/
+    FxaaFloat maxSM = max(lumaS, lumaM);
+    FxaaFloat minSM = min(lumaS, lumaM);
+    FxaaFloat maxESM = max(lumaE, maxSM);
+    FxaaFloat minESM = min(lumaE, minSM);
+    FxaaFloat maxWN = max(lumaN, lumaW);
+    FxaaFloat minWN = min(lumaN, lumaW);
+    FxaaFloat rangeMax = max(maxWN, maxESM);
+    FxaaFloat rangeMin = min(minWN, minESM);
+    FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold;
+    FxaaFloat range = rangeMax - rangeMin;
+    FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);
+    FxaaBool earlyExit = range < rangeMaxClamped;
+/*--------------------------------------------------------------------------*/
+    if(earlyExit)
+        #if (FXAA_DISCARD == 1)
+            FxaaDiscard;
+        #else
+            return rgbyM;
+        #endif
+/*--------------------------------------------------------------------------*/
+    #if (FXAA_GATHER4_ALPHA == 0)
+        FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy));
+        FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy));
+        FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy));
+        FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));
+    #else
+        FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy));
+        FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));
+    #endif
+/*--------------------------------------------------------------------------*/
+    FxaaFloat lumaNS = lumaN + lumaS;
+    FxaaFloat lumaWE = lumaW + lumaE;
+    FxaaFloat subpixRcpRange = 1.0/range;
+    FxaaFloat subpixNSWE = lumaNS + lumaWE;
+    FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS;
+    FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE;
+/*--------------------------------------------------------------------------*/
+    FxaaFloat lumaNESE = lumaNE + lumaSE;
+    FxaaFloat lumaNWNE = lumaNW + lumaNE;
+    FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE;
+    FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE;
+/*--------------------------------------------------------------------------*/
+    FxaaFloat lumaNWSW = lumaNW + lumaSW;
+    FxaaFloat lumaSWSE = lumaSW + lumaSE;
+    FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);
+    FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);
+    FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;
+    FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE;
+    FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4;
+    FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4;
+/*--------------------------------------------------------------------------*/
+    FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE;
+    FxaaFloat lengthSign = fxaaQualityRcpFrame.x;
+    FxaaBool horzSpan = edgeHorz >= edgeVert;
+    FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;
+/*--------------------------------------------------------------------------*/
+    if(!horzSpan) lumaN = lumaW;
+    if(!horzSpan) lumaS = lumaE;
+    if(horzSpan) lengthSign = fxaaQualityRcpFrame.y;
+    FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM;
+/*--------------------------------------------------------------------------*/
+    FxaaFloat gradientN = lumaN - lumaM;
+    FxaaFloat gradientS = lumaS - lumaM;
+    FxaaFloat lumaNN = lumaN + lumaM;
+    FxaaFloat lumaSS = lumaS + lumaM;
+    FxaaBool pairN = abs(gradientN) >= abs(gradientS);
+    FxaaFloat gradient = max(abs(gradientN), abs(gradientS));
+    if(pairN) lengthSign = -lengthSign;
+    FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange);
+/*--------------------------------------------------------------------------*/
+    FxaaFloat2 posB;
+    posB.x = posM.x;
+    posB.y = posM.y;
+    FxaaFloat2 offNP;
+    offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;
+    offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;
+    if(!horzSpan) posB.x += lengthSign * 0.5;
+    if( horzSpan) posB.y += lengthSign * 0.5;
+/*--------------------------------------------------------------------------*/
+    FxaaFloat2 posN;
+    posN.x = posB.x - offNP.x * FXAA_QUALITY__P0;
+    posN.y = posB.y - offNP.y * FXAA_QUALITY__P0;
+    FxaaFloat2 posP;
+    posP.x = posB.x + offNP.x * FXAA_QUALITY__P0;
+    posP.y = posB.y + offNP.y * FXAA_QUALITY__P0;
+    FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0;
+    FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN));
+    FxaaFloat subpixE = subpixC * subpixC;
+    FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP));
+/*--------------------------------------------------------------------------*/
+    if(!pairN) lumaNN = lumaSS;
+    FxaaFloat gradientScaled = gradient * 1.0/4.0;
+    FxaaFloat lumaMM = lumaM - lumaNN * 0.5;
+    FxaaFloat subpixF = subpixD * subpixE;
+    FxaaBool lumaMLTZero = lumaMM < 0.0;
+/*--------------------------------------------------------------------------*/
+    lumaEndN -= lumaNN * 0.5;
+    lumaEndP -= lumaNN * 0.5;
+    FxaaBool doneN = abs(lumaEndN) >= gradientScaled;
+    FxaaBool doneP = abs(lumaEndP) >= gradientScaled;
+    if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1;
+    if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1;
+    FxaaBool doneNP = (!doneN) || (!doneP);
+    if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1;
+    if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1;
+/*--------------------------------------------------------------------------*/
+    if(doneNP) {
+        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+        doneN = abs(lumaEndN) >= gradientScaled;
+        doneP = abs(lumaEndP) >= gradientScaled;
+        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2;
+        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2;
+        doneNP = (!doneN) || (!doneP);
+        if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2;
+        if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2;
+/*--------------------------------------------------------------------------*/
+        #if (FXAA_QUALITY__PS > 3)
+        if(doneNP) {
+            if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+            if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+            if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+            if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+            doneN = abs(lumaEndN) >= gradientScaled;
+            doneP = abs(lumaEndP) >= gradientScaled;
+            if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3;
+            if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3;
+            doneNP = (!doneN) || (!doneP);
+            if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3;
+            if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3;
+/*--------------------------------------------------------------------------*/
+            #if (FXAA_QUALITY__PS > 4)
+            if(doneNP) {
+                if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+                if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+                if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+                if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+                doneN = abs(lumaEndN) >= gradientScaled;
+                doneP = abs(lumaEndP) >= gradientScaled;
+                if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4;
+                if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4;
+                doneNP = (!doneN) || (!doneP);
+                if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4;
+                if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4;
+/*--------------------------------------------------------------------------*/
+                #if (FXAA_QUALITY__PS > 5)
+                if(doneNP) {
+                    if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+                    if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+                    if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+                    if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+                    doneN = abs(lumaEndN) >= gradientScaled;
+                    doneP = abs(lumaEndP) >= gradientScaled;
+                    if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5;
+                    if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5;
+                    doneNP = (!doneN) || (!doneP);
+                    if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5;
+                    if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5;
+/*--------------------------------------------------------------------------*/
+                    #if (FXAA_QUALITY__PS > 6)
+                    if(doneNP) {
+                        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+                        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+                        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+                        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+                        doneN = abs(lumaEndN) >= gradientScaled;
+                        doneP = abs(lumaEndP) >= gradientScaled;
+                        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6;
+                        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6;
+                        doneNP = (!doneN) || (!doneP);
+                        if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6;
+                        if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6;
+/*--------------------------------------------------------------------------*/
+                        #if (FXAA_QUALITY__PS > 7)
+                        if(doneNP) {
+                            if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+                            if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+                            if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+                            if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+                            doneN = abs(lumaEndN) >= gradientScaled;
+                            doneP = abs(lumaEndP) >= gradientScaled;
+                            if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7;
+                            if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7;
+                            doneNP = (!doneN) || (!doneP);
+                            if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7;
+                            if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7;
+/*--------------------------------------------------------------------------*/
+    #if (FXAA_QUALITY__PS > 8)
+    if(doneNP) {
+        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+        doneN = abs(lumaEndN) >= gradientScaled;
+        doneP = abs(lumaEndP) >= gradientScaled;
+        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8;
+        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8;
+        doneNP = (!doneN) || (!doneP);
+        if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8;
+        if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8;
+/*--------------------------------------------------------------------------*/
+        #if (FXAA_QUALITY__PS > 9)
+        if(doneNP) {
+            if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+            if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+            if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+            if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+            doneN = abs(lumaEndN) >= gradientScaled;
+            doneP = abs(lumaEndP) >= gradientScaled;
+            if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9;
+            if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9;
+            doneNP = (!doneN) || (!doneP);
+            if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9;
+            if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9;
+/*--------------------------------------------------------------------------*/
+            #if (FXAA_QUALITY__PS > 10)
+            if(doneNP) {
+                if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+                if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+                if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+                if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+                doneN = abs(lumaEndN) >= gradientScaled;
+                doneP = abs(lumaEndP) >= gradientScaled;
+                if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10;
+                if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10;
+                doneNP = (!doneN) || (!doneP);
+                if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10;
+                if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10;
+/*--------------------------------------------------------------------------*/
+                #if (FXAA_QUALITY__PS > 11)
+                if(doneNP) {
+                    if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+                    if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+                    if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+                    if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+                    doneN = abs(lumaEndN) >= gradientScaled;
+                    doneP = abs(lumaEndP) >= gradientScaled;
+                    if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11;
+                    if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11;
+                    doneNP = (!doneN) || (!doneP);
+                    if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11;
+                    if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11;
+/*--------------------------------------------------------------------------*/
+                    #if (FXAA_QUALITY__PS > 12)
+                    if(doneNP) {
+                        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+                        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+                        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+                        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+                        doneN = abs(lumaEndN) >= gradientScaled;
+                        doneP = abs(lumaEndP) >= gradientScaled;
+                        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12;
+                        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12;
+                        doneNP = (!doneN) || (!doneP);
+                        if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12;
+                        if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12;
+/*--------------------------------------------------------------------------*/
+                    }
+                    #endif
+/*--------------------------------------------------------------------------*/
+                }
+                #endif
+/*--------------------------------------------------------------------------*/
+            }
+            #endif
+/*--------------------------------------------------------------------------*/
+        }
+        #endif
+/*--------------------------------------------------------------------------*/
+    }
+    #endif
+/*--------------------------------------------------------------------------*/
+                        }
+                        #endif
+/*--------------------------------------------------------------------------*/
+                    }
+                    #endif
+/*--------------------------------------------------------------------------*/
+                }
+                #endif
+/*--------------------------------------------------------------------------*/
+            }
+            #endif
+/*--------------------------------------------------------------------------*/
+        }
+        #endif
+/*--------------------------------------------------------------------------*/
+    }
+/*--------------------------------------------------------------------------*/
+    FxaaFloat dstN = posM.x - posN.x;
+    FxaaFloat dstP = posP.x - posM.x;
+    if(!horzSpan) dstN = posM.y - posN.y;
+    if(!horzSpan) dstP = posP.y - posM.y;
+/*--------------------------------------------------------------------------*/
+    FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;
+    FxaaFloat spanLength = (dstP + dstN);
+    FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;
+    FxaaFloat spanLengthRcp = 1.0/spanLength;
+/*--------------------------------------------------------------------------*/
+    FxaaBool directionN = dstN < dstP;
+    FxaaFloat dst = min(dstN, dstP);
+    FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP;
+    FxaaFloat subpixG = subpixF * subpixF;
+    FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5;
+    FxaaFloat subpixH = subpixG * fxaaQualitySubpix;
+/*--------------------------------------------------------------------------*/
+    FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0;
+    FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH);
+    if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;
+    if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;
+    #if (FXAA_DISCARD == 1)
+        return FxaaTexTop(tex, posM);
+    #else
+        return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM);
+    #endif
+}
+/*==========================================================================*/
+#endif
+
+
+
+
+/*============================================================================
+
+                         FXAA3 CONSOLE - PC VERSION
+                         
+------------------------------------------------------------------------------
+Instead of using this on PC, I'd suggest just using FXAA Quality with
+    #define FXAA_QUALITY__PRESET 10
+Or 
+    #define FXAA_QUALITY__PRESET 20
+Either are higher qualilty and almost as fast as this on modern PC GPUs.
+============================================================================*/
+#if (FXAA_PC_CONSOLE == 1)
+/*--------------------------------------------------------------------------*/
+FxaaFloat4 FxaaPixelShader(
+    // See FXAA Quality FxaaPixelShader() source for docs on Inputs!
+    FxaaFloat2 pos,
+    FxaaFloat4 fxaaConsolePosPos,
+    FxaaTex tex,
+    FxaaTex fxaaConsole360TexExpBiasNegOne,
+    FxaaTex fxaaConsole360TexExpBiasNegTwo,
+    FxaaFloat2 fxaaQualityRcpFrame,
+    FxaaFloat4 fxaaConsoleRcpFrameOpt,
+    FxaaFloat4 fxaaConsoleRcpFrameOpt2,
+    FxaaFloat4 fxaaConsole360RcpFrameOpt2,
+    FxaaFloat fxaaQualitySubpix,
+    FxaaFloat fxaaQualityEdgeThreshold,
+    FxaaFloat fxaaQualityEdgeThresholdMin,
+    FxaaFloat fxaaConsoleEdgeSharpness,
+    FxaaFloat fxaaConsoleEdgeThreshold,
+    FxaaFloat fxaaConsoleEdgeThresholdMin,
+    FxaaFloat4 fxaaConsole360ConstDir
+) {
+/*--------------------------------------------------------------------------*/
+    FxaaFloat lumaNw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xy));
+    FxaaFloat lumaSw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xw));
+    FxaaFloat lumaNe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zy));
+    FxaaFloat lumaSe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zw));
+/*--------------------------------------------------------------------------*/
+    FxaaFloat4 rgbyM = FxaaTexTop(tex, pos.xy);
+    #if (FXAA_GREEN_AS_LUMA == 0)
+        FxaaFloat lumaM = rgbyM.w;
+    #else
+        FxaaFloat lumaM = rgbyM.y;
+    #endif
+/*--------------------------------------------------------------------------*/
+    FxaaFloat lumaMaxNwSw = max(lumaNw, lumaSw);
+    lumaNe += 1.0/384.0;
+    FxaaFloat lumaMinNwSw = min(lumaNw, lumaSw);
+/*--------------------------------------------------------------------------*/
+    FxaaFloat lumaMaxNeSe = max(lumaNe, lumaSe);
+    FxaaFloat lumaMinNeSe = min(lumaNe, lumaSe);
+/*--------------------------------------------------------------------------*/
+    FxaaFloat lumaMax = max(lumaMaxNeSe, lumaMaxNwSw);
+    FxaaFloat lumaMin = min(lumaMinNeSe, lumaMinNwSw);
+/*--------------------------------------------------------------------------*/
+    FxaaFloat lumaMaxScaled = lumaMax * fxaaConsoleEdgeThreshold;
+/*--------------------------------------------------------------------------*/
+    FxaaFloat lumaMinM = min(lumaMin, lumaM);
+    FxaaFloat lumaMaxScaledClamped = max(fxaaConsoleEdgeThresholdMin, lumaMaxScaled);
+    FxaaFloat lumaMaxM = max(lumaMax, lumaM);
+    FxaaFloat dirSwMinusNe = lumaSw - lumaNe;
+    FxaaFloat lumaMaxSubMinM = lumaMaxM - lumaMinM;
+    FxaaFloat dirSeMinusNw = lumaSe - lumaNw;
+    if(lumaMaxSubMinM < lumaMaxScaledClamped) return rgbyM;
+/*--------------------------------------------------------------------------*/
+    FxaaFloat2 dir;
+    dir.x = dirSwMinusNe + dirSeMinusNw;
+    dir.y = dirSwMinusNe - dirSeMinusNw;
+/*--------------------------------------------------------------------------*/
+    FxaaFloat2 dir1 = normalize(dir.xy);
+    FxaaFloat4 rgbyN1 = FxaaTexTop(tex, pos.xy - dir1 * fxaaConsoleRcpFrameOpt.zw);
+    FxaaFloat4 rgbyP1 = FxaaTexTop(tex, pos.xy + dir1 * fxaaConsoleRcpFrameOpt.zw);
+/*--------------------------------------------------------------------------*/
+    FxaaFloat dirAbsMinTimesC = min(abs(dir1.x), abs(dir1.y)) * fxaaConsoleEdgeSharpness;
+    FxaaFloat2 dir2 = clamp(dir1.xy / dirAbsMinTimesC, -2.0, 2.0);
+/*--------------------------------------------------------------------------*/
+    FxaaFloat4 rgbyN2 = FxaaTexTop(tex, pos.xy - dir2 * fxaaConsoleRcpFrameOpt2.zw);
+    FxaaFloat4 rgbyP2 = FxaaTexTop(tex, pos.xy + dir2 * fxaaConsoleRcpFrameOpt2.zw);
+/*--------------------------------------------------------------------------*/
+    FxaaFloat4 rgbyA = rgbyN1 + rgbyP1;
+    FxaaFloat4 rgbyB = ((rgbyN2 + rgbyP2) * 0.25) + (rgbyA * 0.25);
+/*--------------------------------------------------------------------------*/
+    #if (FXAA_GREEN_AS_LUMA == 0)
+        FxaaBool twoTap = (rgbyB.w < lumaMin) || (rgbyB.w > lumaMax);
+    #else
+        FxaaBool twoTap = (rgbyB.y < lumaMin) || (rgbyB.y > lumaMax);
+    #endif
+    if(twoTap) rgbyB.xyz = rgbyA.xyz * 0.5;
+    return rgbyB; }
+/*==========================================================================*/
+#endif
+
+
+
+/*============================================================================
+
+                      FXAA3 CONSOLE - 360 PIXEL SHADER 
+
+------------------------------------------------------------------------------
+This optimized version thanks to suggestions from Andy Luedke.
+Should be fully tex bound in all cases.
+As of the FXAA 3.11 release, I have still not tested this code,
+however I fixed a bug which was in both FXAA 3.9 and FXAA 3.10.
+And note this is replacing the old unoptimized version.
+If it does not work, please let me know so I can fix it.
+============================================================================*/
+#if (FXAA_360 == 1)
+/*--------------------------------------------------------------------------*/
+[reduceTempRegUsage(4)]
+float4 FxaaPixelShader(
+    // See FXAA Quality FxaaPixelShader() source for docs on Inputs!
+    FxaaFloat2 pos,
+    FxaaFloat4 fxaaConsolePosPos,
+    FxaaTex tex,
+    FxaaTex fxaaConsole360TexExpBiasNegOne,
+    FxaaTex fxaaConsole360TexExpBiasNegTwo,
+    FxaaFloat2 fxaaQualityRcpFrame,
+    FxaaFloat4 fxaaConsoleRcpFrameOpt,
+    FxaaFloat4 fxaaConsoleRcpFrameOpt2,
+    FxaaFloat4 fxaaConsole360RcpFrameOpt2,
+    FxaaFloat fxaaQualitySubpix,
+    FxaaFloat fxaaQualityEdgeThreshold,
+    FxaaFloat fxaaQualityEdgeThresholdMin,
+    FxaaFloat fxaaConsoleEdgeSharpness,
+    FxaaFloat fxaaConsoleEdgeThreshold,
+    FxaaFloat fxaaConsoleEdgeThresholdMin,
+    FxaaFloat4 fxaaConsole360ConstDir
+) {
+/*--------------------------------------------------------------------------*/
+    float4 lumaNwNeSwSe;
+    #if (FXAA_GREEN_AS_LUMA == 0)
+        asm { 
+            tfetch2D lumaNwNeSwSe.w___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false
+            tfetch2D lumaNwNeSwSe._w__, tex, pos.xy, OffsetX =  0.5, OffsetY = -0.5, UseComputedLOD=false
+            tfetch2D lumaNwNeSwSe.__w_, tex, pos.xy, OffsetX = -0.5, OffsetY =  0.5, UseComputedLOD=false
+            tfetch2D lumaNwNeSwSe.___w, tex, pos.xy, OffsetX =  0.5, OffsetY =  0.5, UseComputedLOD=false
+        };
+    #else
+        asm { 
+            tfetch2D lumaNwNeSwSe.y___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false
+            tfetch2D lumaNwNeSwSe._y__, tex, pos.xy, OffsetX =  0.5, OffsetY = -0.5, UseComputedLOD=false
+            tfetch2D lumaNwNeSwSe.__y_, tex, pos.xy, OffsetX = -0.5, OffsetY =  0.5, UseComputedLOD=false
+            tfetch2D lumaNwNeSwSe.___y, tex, pos.xy, OffsetX =  0.5, OffsetY =  0.5, UseComputedLOD=false
+        };
+    #endif
+/*--------------------------------------------------------------------------*/
+    lumaNwNeSwSe.y += 1.0/384.0;
+    float2 lumaMinTemp = min(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw);
+    float2 lumaMaxTemp = max(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw);
+    float lumaMin = min(lumaMinTemp.x, lumaMinTemp.y);
+    float lumaMax = max(lumaMaxTemp.x, lumaMaxTemp.y);
+/*--------------------------------------------------------------------------*/
+    float4 rgbyM = tex2Dlod(tex, float4(pos.xy, 0.0, 0.0));
+    #if (FXAA_GREEN_AS_LUMA == 0)
+        float lumaMinM = min(lumaMin, rgbyM.w);
+        float lumaMaxM = max(lumaMax, rgbyM.w);
+    #else
+        float lumaMinM = min(lumaMin, rgbyM.y);
+        float lumaMaxM = max(lumaMax, rgbyM.y);
+    #endif        
+    if((lumaMaxM - lumaMinM) < max(fxaaConsoleEdgeThresholdMin, lumaMax * fxaaConsoleEdgeThreshold)) return rgbyM;
+/*--------------------------------------------------------------------------*/
+    float2 dir;
+    dir.x = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.yyxx);
+    dir.y = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.xyxy);
+    dir = normalize(dir);
+/*--------------------------------------------------------------------------*/
+    float4 dir1 = dir.xyxy * fxaaConsoleRcpFrameOpt.xyzw;
+/*--------------------------------------------------------------------------*/
+    float4 dir2;
+    float dirAbsMinTimesC = min(abs(dir.x), abs(dir.y)) * fxaaConsoleEdgeSharpness;
+    dir2 = saturate(fxaaConsole360ConstDir.zzww * dir.xyxy / dirAbsMinTimesC + 0.5);
+    dir2 = dir2 * fxaaConsole360RcpFrameOpt2.xyxy + fxaaConsole360RcpFrameOpt2.zwzw;
+/*--------------------------------------------------------------------------*/
+    float4 rgbyN1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.xy, 0.0, 0.0));
+    float4 rgbyP1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.zw, 0.0, 0.0));
+    float4 rgbyN2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.xy, 0.0, 0.0));
+    float4 rgbyP2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.zw, 0.0, 0.0));
+/*--------------------------------------------------------------------------*/
+    float4 rgbyA = rgbyN1 + rgbyP1;
+    float4 rgbyB = rgbyN2 + rgbyP2 * 0.5 + rgbyA;
+/*--------------------------------------------------------------------------*/
+    float4 rgbyR = ((rgbyB.w - lumaMax) > 0.0) ? rgbyA : rgbyB;
+    rgbyR = ((rgbyB.w - lumaMin) > 0.0) ? rgbyR : rgbyA;
+    return rgbyR; }
+/*==========================================================================*/
+#endif
+
+
+
+/*============================================================================
+
+         FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (NO EARLY EXIT)
+
+==============================================================================
+The code below does not exactly match the assembly.
+I have a feeling that 12 cycles is possible, but was not able to get there.
+Might have to increase register count to get full performance.
+Note this shader does not use perspective interpolation.
+
+Use the following cgc options,
+
+  --fenable-bx2 --fastmath --fastprecision --nofloatbindings
+
+------------------------------------------------------------------------------
+                             NVSHADERPERF OUTPUT
+------------------------------------------------------------------------------
+For reference and to aid in debug, output of NVShaderPerf should match this,
+
+Shader to schedule:
+  0: texpkb h0.w(TRUE), v5.zyxx, #0
+  2: addh h2.z(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x
+  4: texpkb h0.w(TRUE), v5.xwxx, #0
+  6: addh h0.z(TRUE), -h2, h0.w
+  7: texpkb h1.w(TRUE), v5, #0
+  9: addh h0.x(TRUE), h0.z, -h1.w
+ 10: addh h3.w(TRUE), h0.z, h1
+ 11: texpkb h2.w(TRUE), v5.zwzz, #0
+ 13: addh h0.z(TRUE), h3.w, -h2.w
+ 14: addh h0.x(TRUE), h2.w, h0
+ 15: nrmh h1.xz(TRUE), h0_n
+ 16: minh_m8 h0.x(TRUE), |h1|, |h1.z|
+ 17: maxh h4.w(TRUE), h0, h1
+ 18: divx h2.xy(TRUE), h1_n.xzzw, h0_n
+ 19: movr r1.zw(TRUE), v4.xxxy
+ 20: madr r2.xz(TRUE), -h1, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zzww, r1.zzww
+ 22: minh h5.w(TRUE), h0, h1
+ 23: texpkb h0(TRUE), r2.xzxx, #0
+ 25: madr r0.zw(TRUE), h1.xzxz, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w), r1
+ 27: maxh h4.x(TRUE), h2.z, h2.w
+ 28: texpkb h1(TRUE), r0.zwzz, #0
+ 30: addh_d2 h1(TRUE), h0, h1
+ 31: madr r0.xy(TRUE), -h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz
+ 33: texpkb h0(TRUE), r0, #0
+ 35: minh h4.z(TRUE), h2, h2.w
+ 36: fenct TRUE
+ 37: madr r1.xy(TRUE), h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz
+ 39: texpkb h2(TRUE), r1, #0
+ 41: addh_d2 h0(TRUE), h0, h2
+ 42: maxh h2.w(TRUE), h4, h4.x
+ 43: minh h2.x(TRUE), h5.w, h4.z
+ 44: addh_d2 h0(TRUE), h0, h1
+ 45: slth h2.x(TRUE), h0.w, h2
+ 46: sgth h2.w(TRUE), h0, h2
+ 47: movh h0(TRUE), h0
+ 48: addx.c0 rc(TRUE), h2, h2.w
+ 49: movh h0(c0.NE.x), h1
+
+IPU0 ------ Simplified schedule: --------
+Pass |  Unit  |  uOp |  PC:  Op
+-----+--------+------+-------------------------
+   1 | SCT0/1 |  mov |   0:  TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0;
+     |    TEX |  txl |   0:  TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0;
+     |   SCB1 |  add |   2:  ADDh h2.z, h0.--w-, const.--x-;
+     |        |      |
+   2 | SCT0/1 |  mov |   4:  TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0;
+     |    TEX |  txl |   4:  TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0;
+     |   SCB1 |  add |   6:  ADDh h0.z,-h2, h0.--w-;
+     |        |      |
+   3 | SCT0/1 |  mov |   7:  TXLr h1.w, g[TEX1], const.xxxx, TEX0;
+     |    TEX |  txl |   7:  TXLr h1.w, g[TEX1], const.xxxx, TEX0;
+     |   SCB0 |  add |   9:  ADDh h0.x, h0.z---,-h1.w---;
+     |   SCB1 |  add |  10:  ADDh h3.w, h0.---z, h1;
+     |        |      |
+   4 | SCT0/1 |  mov |  11:  TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0;
+     |    TEX |  txl |  11:  TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0;
+     |   SCB0 |  add |  14:  ADDh h0.x, h2.w---, h0;
+     |   SCB1 |  add |  13:  ADDh h0.z, h3.--w-,-h2.--w-;
+     |        |      |
+   5 |   SCT1 |  mov |  15:  NRMh h1.xz, h0;
+     |    SRB |  nrm |  15:  NRMh h1.xz, h0;
+     |   SCB0 |  min |  16:  MINh*8 h0.x, |h1|, |h1.z---|;
+     |   SCB1 |  max |  17:  MAXh h4.w, h0, h1;
+     |        |      |
+   6 |   SCT0 |  div |  18:  DIVx h2.xy, h1.xz--, h0;
+     |   SCT1 |  mov |  19:  MOVr r1.zw, g[TEX0].--xy;
+     |   SCB0 |  mad |  20:  MADr r2.xz,-h1, const.z-w-, r1.z-w-;
+     |   SCB1 |  min |  22:  MINh h5.w, h0, h1;
+     |        |      |
+   7 | SCT0/1 |  mov |  23:  TXLr h0, r2.xzxx, const.xxxx, TEX0;
+     |    TEX |  txl |  23:  TXLr h0, r2.xzxx, const.xxxx, TEX0;
+     |   SCB0 |  max |  27:  MAXh h4.x, h2.z---, h2.w---;
+     |   SCB1 |  mad |  25:  MADr r0.zw, h1.--xz, const, r1;
+     |        |      |
+   8 | SCT0/1 |  mov |  28:  TXLr h1, r0.zwzz, const.xxxx, TEX0;
+     |    TEX |  txl |  28:  TXLr h1, r0.zwzz, const.xxxx, TEX0;
+     | SCB0/1 |  add |  30:  ADDh/2 h1, h0, h1;
+     |        |      |
+   9 |   SCT0 |  mad |  31:  MADr r0.xy,-h2, const.xy--, r1.zw--;
+     |   SCT1 |  mov |  33:  TXLr h0, r0, const.zzzz, TEX0;
+     |    TEX |  txl |  33:  TXLr h0, r0, const.zzzz, TEX0;
+     |   SCB1 |  min |  35:  MINh h4.z, h2, h2.--w-;
+     |        |      |
+  10 |   SCT0 |  mad |  37:  MADr r1.xy, h2, const.xy--, r1.zw--;
+     |   SCT1 |  mov |  39:  TXLr h2, r1, const.zzzz, TEX0;
+     |    TEX |  txl |  39:  TXLr h2, r1, const.zzzz, TEX0;
+     | SCB0/1 |  add |  41:  ADDh/2 h0, h0, h2;
+     |        |      |
+  11 |   SCT0 |  min |  43:  MINh h2.x, h5.w---, h4.z---;
+     |   SCT1 |  max |  42:  MAXh h2.w, h4, h4.---x;
+     | SCB0/1 |  add |  44:  ADDh/2 h0, h0, h1;
+     |        |      |
+  12 |   SCT0 |  set |  45:  SLTh h2.x, h0.w---, h2;
+     |   SCT1 |  set |  46:  SGTh h2.w, h0, h2;
+     | SCB0/1 |  mul |  47:  MOVh h0, h0;
+     |        |      |
+  13 |   SCT0 |  mad |  48:  ADDxc0_s rc, h2, h2.w---;
+     | SCB0/1 |  mul |  49:  MOVh h0(NE0.xxxx), h1;
+ 
+Pass   SCT  TEX  SCB
+  1:   0% 100%  25%
+  2:   0% 100%  25%
+  3:   0% 100%  50%
+  4:   0% 100%  50%
+  5:   0%   0%  50%
+  6: 100%   0%  75%
+  7:   0% 100%  75%
+  8:   0% 100% 100%
+  9:   0% 100%  25%
+ 10:   0% 100% 100%
+ 11:  50%   0% 100%
+ 12:  50%   0% 100%
+ 13:  25%   0% 100%
+
+MEAN:  17%  61%  67%
+
+Pass   SCT0  SCT1   TEX  SCB0  SCB1
+  1:    0%    0%  100%    0%  100%
+  2:    0%    0%  100%    0%  100%
+  3:    0%    0%  100%  100%  100%
+  4:    0%    0%  100%  100%  100%
+  5:    0%    0%    0%  100%  100%
+  6:  100%  100%    0%  100%  100%
+  7:    0%    0%  100%  100%  100%
+  8:    0%    0%  100%  100%  100%
+  9:    0%    0%  100%    0%  100%
+ 10:    0%    0%  100%  100%  100%
+ 11:  100%  100%    0%  100%  100%
+ 12:  100%  100%    0%  100%  100%
+ 13:  100%    0%    0%  100%  100%
+
+MEAN:   30%   23%   61%   76%  100%
+Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5
+Results 13 cycles, 3 r regs, 923,076,923 pixels/s
+============================================================================*/
+#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 0)
+/*--------------------------------------------------------------------------*/
+#pragma regcount 7
+#pragma disablepc all
+#pragma option O3
+#pragma option OutColorPrec=fp16
+#pragma texformat default RGBA8
+/*==========================================================================*/
+half4 FxaaPixelShader(
+    // See FXAA Quality FxaaPixelShader() source for docs on Inputs!
+    FxaaFloat2 pos,
+    FxaaFloat4 fxaaConsolePosPos,
+    FxaaTex tex,
+    FxaaTex fxaaConsole360TexExpBiasNegOne,
+    FxaaTex fxaaConsole360TexExpBiasNegTwo,
+    FxaaFloat2 fxaaQualityRcpFrame,
+    FxaaFloat4 fxaaConsoleRcpFrameOpt,
+    FxaaFloat4 fxaaConsoleRcpFrameOpt2,
+    FxaaFloat4 fxaaConsole360RcpFrameOpt2,
+    FxaaFloat fxaaQualitySubpix,
+    FxaaFloat fxaaQualityEdgeThreshold,
+    FxaaFloat fxaaQualityEdgeThresholdMin,
+    FxaaFloat fxaaConsoleEdgeSharpness,
+    FxaaFloat fxaaConsoleEdgeThreshold,
+    FxaaFloat fxaaConsoleEdgeThresholdMin,
+    FxaaFloat4 fxaaConsole360ConstDir
+) {
+/*--------------------------------------------------------------------------*/
+// (1)
+    half4 dir;
+    half4 lumaNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0));
+    #if (FXAA_GREEN_AS_LUMA == 0)
+        lumaNe.w += half(1.0/512.0);
+        dir.x = -lumaNe.w;
+        dir.z = -lumaNe.w;
+    #else
+        lumaNe.y += half(1.0/512.0);
+        dir.x = -lumaNe.y;
+        dir.z = -lumaNe.y;
+    #endif
+/*--------------------------------------------------------------------------*/
+// (2)
+    half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0));
+    #if (FXAA_GREEN_AS_LUMA == 0)
+        dir.x += lumaSw.w;
+        dir.z += lumaSw.w;
+    #else
+        dir.x += lumaSw.y;
+        dir.z += lumaSw.y;
+    #endif        
+/*--------------------------------------------------------------------------*/
+// (3)
+    half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0));
+    #if (FXAA_GREEN_AS_LUMA == 0)
+        dir.x -= lumaNw.w;
+        dir.z += lumaNw.w;
+    #else
+        dir.x -= lumaNw.y;
+        dir.z += lumaNw.y;
+    #endif
+/*--------------------------------------------------------------------------*/
+// (4)
+    half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0));
+    #if (FXAA_GREEN_AS_LUMA == 0)
+        dir.x += lumaSe.w;
+        dir.z -= lumaSe.w;
+    #else
+        dir.x += lumaSe.y;
+        dir.z -= lumaSe.y;
+    #endif
+/*--------------------------------------------------------------------------*/
+// (5)
+    half4 dir1_pos;
+    dir1_pos.xy = normalize(dir.xyz).xz;
+    half dirAbsMinTimesC = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS);
+/*--------------------------------------------------------------------------*/
+// (6)
+    half4 dir2_pos;
+    dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimesC, half(-2.0), half(2.0));
+    dir1_pos.zw = pos.xy;
+    dir2_pos.zw = pos.xy;
+    half4 temp1N;
+    temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
+/*--------------------------------------------------------------------------*/
+// (7)
+    temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0));
+    half4 rgby1;
+    rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
+/*--------------------------------------------------------------------------*/
+// (8)
+    rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0));
+    rgby1 = (temp1N + rgby1) * 0.5;
+/*--------------------------------------------------------------------------*/
+// (9)
+    half4 temp2N;
+    temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
+    temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0));
+/*--------------------------------------------------------------------------*/
+// (10)
+    half4 rgby2;
+    rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
+    rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0));
+    rgby2 = (temp2N + rgby2) * 0.5;
+/*--------------------------------------------------------------------------*/
+// (11)
+    // compilier moves these scalar ops up to other cycles
+    #if (FXAA_GREEN_AS_LUMA == 0)
+        half lumaMin = min(min(lumaNw.w, lumaSw.w), min(lumaNe.w, lumaSe.w));
+        half lumaMax = max(max(lumaNw.w, lumaSw.w), max(lumaNe.w, lumaSe.w));
+    #else
+        half lumaMin = min(min(lumaNw.y, lumaSw.y), min(lumaNe.y, lumaSe.y));
+        half lumaMax = max(max(lumaNw.y, lumaSw.y), max(lumaNe.y, lumaSe.y));
+    #endif        
+    rgby2 = (rgby2 + rgby1) * 0.5;
+/*--------------------------------------------------------------------------*/
+// (12)
+    #if (FXAA_GREEN_AS_LUMA == 0)
+        bool twoTapLt = rgby2.w < lumaMin;
+        bool twoTapGt = rgby2.w > lumaMax;
+    #else
+        bool twoTapLt = rgby2.y < lumaMin;
+        bool twoTapGt = rgby2.y > lumaMax;
+    #endif
+/*--------------------------------------------------------------------------*/
+// (13)
+    if(twoTapLt || twoTapGt) rgby2 = rgby1;
+/*--------------------------------------------------------------------------*/
+    return rgby2; }
+/*==========================================================================*/
+#endif
+
+
+
+/*============================================================================
+
+       FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (WITH EARLY EXIT)
+
+==============================================================================
+The code mostly matches the assembly.
+I have a feeling that 14 cycles is possible, but was not able to get there.
+Might have to increase register count to get full performance.
+Note this shader does not use perspective interpolation.
+
+Use the following cgc options,
+
+ --fenable-bx2 --fastmath --fastprecision --nofloatbindings
+
+Use of FXAA_GREEN_AS_LUMA currently adds a cycle (16 clks).
+Will look at fixing this for FXAA 3.12.
+------------------------------------------------------------------------------
+                             NVSHADERPERF OUTPUT
+------------------------------------------------------------------------------
+For reference and to aid in debug, output of NVShaderPerf should match this,
+
+Shader to schedule:
+  0: texpkb h0.w(TRUE), v5.zyxx, #0
+  2: addh h2.y(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x
+  4: texpkb h1.w(TRUE), v5.xwxx, #0
+  6: addh h0.x(TRUE), h1.w, -h2.y
+  7: texpkb h2.w(TRUE), v5.zwzz, #0
+  9: minh h4.w(TRUE), h2.y, h2
+ 10: maxh h5.x(TRUE), h2.y, h2.w
+ 11: texpkb h0.w(TRUE), v5, #0
+ 13: addh h3.w(TRUE), -h0, h0.x
+ 14: addh h0.x(TRUE), h0.w, h0
+ 15: addh h0.z(TRUE), -h2.w, h0.x
+ 16: addh h0.x(TRUE), h2.w, h3.w
+ 17: minh h5.y(TRUE), h0.w, h1.w
+ 18: nrmh h2.xz(TRUE), h0_n
+ 19: minh_m8 h2.w(TRUE), |h2.x|, |h2.z|
+ 20: divx h4.xy(TRUE), h2_n.xzzw, h2_n.w
+ 21: movr r1.zw(TRUE), v4.xxxy
+ 22: maxh h2.w(TRUE), h0, h1
+ 23: fenct TRUE
+ 24: madr r0.xy(TRUE), -h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz
+ 26: texpkb h0(TRUE), r0, #0
+ 28: maxh h5.x(TRUE), h2.w, h5
+ 29: minh h5.w(TRUE), h5.y, h4
+ 30: madr r1.xy(TRUE), h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz
+ 32: texpkb h2(TRUE), r1, #0
+ 34: addh_d2 h2(TRUE), h0, h2
+ 35: texpkb h1(TRUE), v4, #0
+ 37: maxh h5.y(TRUE), h5.x, h1.w
+ 38: minh h4.w(TRUE), h1, h5
+ 39: madr r0.xy(TRUE), -h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz
+ 41: texpkb h0(TRUE), r0, #0
+ 43: addh_m8 h5.z(TRUE), h5.y, -h4.w
+ 44: madr r2.xy(TRUE), h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz
+ 46: texpkb h3(TRUE), r2, #0
+ 48: addh_d2 h0(TRUE), h0, h3
+ 49: addh_d2 h3(TRUE), h0, h2
+ 50: movh h0(TRUE), h3
+ 51: slth h3.x(TRUE), h3.w, h5.w
+ 52: sgth h3.w(TRUE), h3, h5.x
+ 53: addx.c0 rc(TRUE), h3.x, h3
+ 54: slth.c0 rc(TRUE), h5.z, h5
+ 55: movh h0(c0.NE.w), h2
+ 56: movh h0(c0.NE.x), h1
+
+IPU0 ------ Simplified schedule: --------
+Pass |  Unit  |  uOp |  PC:  Op
+-----+--------+------+-------------------------
+   1 | SCT0/1 |  mov |   0:  TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0;
+     |    TEX |  txl |   0:  TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0;
+     |   SCB0 |  add |   2:  ADDh h2.y, h0.-w--, const.-x--;
+     |        |      |
+   2 | SCT0/1 |  mov |   4:  TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0;
+     |    TEX |  txl |   4:  TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0;
+     |   SCB0 |  add |   6:  ADDh h0.x, h1.w---,-h2.y---;
+     |        |      |
+   3 | SCT0/1 |  mov |   7:  TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0;
+     |    TEX |  txl |   7:  TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0;
+     |   SCB0 |  max |  10:  MAXh h5.x, h2.y---, h2.w---;
+     |   SCB1 |  min |   9:  MINh h4.w, h2.---y, h2;
+     |        |      |
+   4 | SCT0/1 |  mov |  11:  TXLr h0.w, g[TEX1], const.xxxx, TEX0;
+     |    TEX |  txl |  11:  TXLr h0.w, g[TEX1], const.xxxx, TEX0;
+     |   SCB0 |  add |  14:  ADDh h0.x, h0.w---, h0;
+     |   SCB1 |  add |  13:  ADDh h3.w,-h0, h0.---x;
+     |        |      |
+   5 |   SCT0 |  mad |  16:  ADDh h0.x, h2.w---, h3.w---;
+     |   SCT1 |  mad |  15:  ADDh h0.z,-h2.--w-, h0.--x-;
+     |   SCB0 |  min |  17:  MINh h5.y, h0.-w--, h1.-w--;
+     |        |      |
+   6 |   SCT1 |  mov |  18:  NRMh h2.xz, h0;
+     |    SRB |  nrm |  18:  NRMh h2.xz, h0;
+     |   SCB1 |  min |  19:  MINh*8 h2.w, |h2.---x|, |h2.---z|;
+     |        |      |
+   7 |   SCT0 |  div |  20:  DIVx h4.xy, h2.xz--, h2.ww--;
+     |   SCT1 |  mov |  21:  MOVr r1.zw, g[TEX0].--xy;
+     |   SCB1 |  max |  22:  MAXh h2.w, h0, h1;
+     |        |      |
+   8 |   SCT0 |  mad |  24:  MADr r0.xy,-h2.xz--, const.zw--, r1.zw--;
+     |   SCT1 |  mov |  26:  TXLr h0, r0, const.xxxx, TEX0;
+     |    TEX |  txl |  26:  TXLr h0, r0, const.xxxx, TEX0;
+     |   SCB0 |  max |  28:  MAXh h5.x, h2.w---, h5;
+     |   SCB1 |  min |  29:  MINh h5.w, h5.---y, h4;
+     |        |      |
+   9 |   SCT0 |  mad |  30:  MADr r1.xy, h2.xz--, const.zw--, r1.zw--;
+     |   SCT1 |  mov |  32:  TXLr h2, r1, const.xxxx, TEX0;
+     |    TEX |  txl |  32:  TXLr h2, r1, const.xxxx, TEX0;
+     | SCB0/1 |  add |  34:  ADDh/2 h2, h0, h2;
+     |        |      |
+  10 | SCT0/1 |  mov |  35:  TXLr h1, g[TEX0], const.xxxx, TEX0;
+     |    TEX |  txl |  35:  TXLr h1, g[TEX0], const.xxxx, TEX0;
+     |   SCB0 |  max |  37:  MAXh h5.y, h5.-x--, h1.-w--;
+     |   SCB1 |  min |  38:  MINh h4.w, h1, h5;
+     |        |      |
+  11 |   SCT0 |  mad |  39:  MADr r0.xy,-h4, const.xy--, r1.zw--;
+     |   SCT1 |  mov |  41:  TXLr h0, r0, const.zzzz, TEX0;
+     |    TEX |  txl |  41:  TXLr h0, r0, const.zzzz, TEX0;
+     |   SCB0 |  mad |  44:  MADr r2.xy, h4, const.xy--, r1.zw--;
+     |   SCB1 |  add |  43:  ADDh*8 h5.z, h5.--y-,-h4.--w-;
+     |        |      |
+  12 | SCT0/1 |  mov |  46:  TXLr h3, r2, const.xxxx, TEX0;
+     |    TEX |  txl |  46:  TXLr h3, r2, const.xxxx, TEX0;
+     | SCB0/1 |  add |  48:  ADDh/2 h0, h0, h3;
+     |        |      |
+  13 | SCT0/1 |  mad |  49:  ADDh/2 h3, h0, h2;
+     | SCB0/1 |  mul |  50:  MOVh h0, h3;
+     |        |      |
+  14 |   SCT0 |  set |  51:  SLTh h3.x, h3.w---, h5.w---;
+     |   SCT1 |  set |  52:  SGTh h3.w, h3, h5.---x;
+     |   SCB0 |  set |  54:  SLThc0 rc, h5.z---, h5;
+     |   SCB1 |  add |  53:  ADDxc0_s rc, h3.---x, h3;
+     |        |      |
+  15 | SCT0/1 |  mul |  55:  MOVh h0(NE0.wwww), h2;
+     | SCB0/1 |  mul |  56:  MOVh h0(NE0.xxxx), h1;
+ 
+Pass   SCT  TEX  SCB
+  1:   0% 100%  25%
+  2:   0% 100%  25%
+  3:   0% 100%  50%
+  4:   0% 100%  50%
+  5:  50%   0%  25%
+  6:   0%   0%  25%
+  7: 100%   0%  25%
+  8:   0% 100%  50%
+  9:   0% 100% 100%
+ 10:   0% 100%  50%
+ 11:   0% 100%  75%
+ 12:   0% 100% 100%
+ 13: 100%   0% 100%
+ 14:  50%   0%  50%
+ 15: 100%   0% 100%
+
+MEAN:  26%  60%  56%
+
+Pass   SCT0  SCT1   TEX  SCB0  SCB1
+  1:    0%    0%  100%  100%    0%
+  2:    0%    0%  100%  100%    0%
+  3:    0%    0%  100%  100%  100%
+  4:    0%    0%  100%  100%  100%
+  5:  100%  100%    0%  100%    0%
+  6:    0%    0%    0%    0%  100%
+  7:  100%  100%    0%    0%  100%
+  8:    0%    0%  100%  100%  100%
+  9:    0%    0%  100%  100%  100%
+ 10:    0%    0%  100%  100%  100%
+ 11:    0%    0%  100%  100%  100%
+ 12:    0%    0%  100%  100%  100%
+ 13:  100%  100%    0%  100%  100%
+ 14:  100%  100%    0%  100%  100%
+ 15:  100%  100%    0%  100%  100%
+
+MEAN:   33%   33%   60%   86%   80%
+Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5
+Results 15 cycles, 3 r regs, 800,000,000 pixels/s
+============================================================================*/
+#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 1)
+/*--------------------------------------------------------------------------*/
+#pragma regcount 7
+#pragma disablepc all
+#pragma option O2
+#pragma option OutColorPrec=fp16
+#pragma texformat default RGBA8
+/*==========================================================================*/
+half4 FxaaPixelShader(
+    // See FXAA Quality FxaaPixelShader() source for docs on Inputs!
+    FxaaFloat2 pos,
+    FxaaFloat4 fxaaConsolePosPos,
+    FxaaTex tex,
+    FxaaTex fxaaConsole360TexExpBiasNegOne,
+    FxaaTex fxaaConsole360TexExpBiasNegTwo,
+    FxaaFloat2 fxaaQualityRcpFrame,
+    FxaaFloat4 fxaaConsoleRcpFrameOpt,
+    FxaaFloat4 fxaaConsoleRcpFrameOpt2,
+    FxaaFloat4 fxaaConsole360RcpFrameOpt2,
+    FxaaFloat fxaaQualitySubpix,
+    FxaaFloat fxaaQualityEdgeThreshold,
+    FxaaFloat fxaaQualityEdgeThresholdMin,
+    FxaaFloat fxaaConsoleEdgeSharpness,
+    FxaaFloat fxaaConsoleEdgeThreshold,
+    FxaaFloat fxaaConsoleEdgeThresholdMin,
+    FxaaFloat4 fxaaConsole360ConstDir
+) {
+/*--------------------------------------------------------------------------*/
+// (1)
+    half4 rgbyNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0));
+    #if (FXAA_GREEN_AS_LUMA == 0)
+        half lumaNe = rgbyNe.w + half(1.0/512.0);
+    #else
+        half lumaNe = rgbyNe.y + half(1.0/512.0);
+    #endif
+/*--------------------------------------------------------------------------*/
+// (2)
+    half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0));
+    #if (FXAA_GREEN_AS_LUMA == 0)
+        half lumaSwNegNe = lumaSw.w - lumaNe;
+    #else
+        half lumaSwNegNe = lumaSw.y - lumaNe;
+    #endif
+/*--------------------------------------------------------------------------*/
+// (3)
+    half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0));
+    #if (FXAA_GREEN_AS_LUMA == 0)
+        half lumaMaxNwSw = max(lumaNw.w, lumaSw.w);
+        half lumaMinNwSw = min(lumaNw.w, lumaSw.w);
+    #else
+        half lumaMaxNwSw = max(lumaNw.y, lumaSw.y);
+        half lumaMinNwSw = min(lumaNw.y, lumaSw.y);
+    #endif
+/*--------------------------------------------------------------------------*/
+// (4)
+    half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0));
+    #if (FXAA_GREEN_AS_LUMA == 0)
+        half dirZ =  lumaNw.w + lumaSwNegNe;
+        half dirX = -lumaNw.w + lumaSwNegNe;
+    #else
+        half dirZ =  lumaNw.y + lumaSwNegNe;
+        half dirX = -lumaNw.y + lumaSwNegNe;
+    #endif
+/*--------------------------------------------------------------------------*/
+// (5)
+    half3 dir;
+    dir.y = 0.0;
+    #if (FXAA_GREEN_AS_LUMA == 0)
+        dir.x =  lumaSe.w + dirX;
+        dir.z = -lumaSe.w + dirZ;
+        half lumaMinNeSe = min(lumaNe, lumaSe.w);
+    #else
+        dir.x =  lumaSe.y + dirX;
+        dir.z = -lumaSe.y + dirZ;
+        half lumaMinNeSe = min(lumaNe, lumaSe.y);
+    #endif
+/*--------------------------------------------------------------------------*/
+// (6)
+    half4 dir1_pos;
+    dir1_pos.xy = normalize(dir).xz;
+    half dirAbsMinTimes8 = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS);
+/*--------------------------------------------------------------------------*/
+// (7)
+    half4 dir2_pos;
+    dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimes8, half(-2.0), half(2.0));
+    dir1_pos.zw = pos.xy;
+    dir2_pos.zw = pos.xy;
+    #if (FXAA_GREEN_AS_LUMA == 0)
+        half lumaMaxNeSe = max(lumaNe, lumaSe.w);
+    #else
+        half lumaMaxNeSe = max(lumaNe, lumaSe.y);
+    #endif
+/*--------------------------------------------------------------------------*/
+// (8)
+    half4 temp1N;
+    temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
+    temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0));
+    half lumaMax = max(lumaMaxNwSw, lumaMaxNeSe);
+    half lumaMin = min(lumaMinNwSw, lumaMinNeSe);
+/*--------------------------------------------------------------------------*/
+// (9)
+    half4 rgby1;
+    rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
+    rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0));
+    rgby1 = (temp1N + rgby1) * 0.5;
+/*--------------------------------------------------------------------------*/
+// (10)
+    half4 rgbyM = h4tex2Dlod(tex, half4(pos.xy, 0.0, 0.0));
+    #if (FXAA_GREEN_AS_LUMA == 0)
+        half lumaMaxM = max(lumaMax, rgbyM.w);
+        half lumaMinM = min(lumaMin, rgbyM.w);
+    #else
+        half lumaMaxM = max(lumaMax, rgbyM.y);
+        half lumaMinM = min(lumaMin, rgbyM.y);
+    #endif
+/*--------------------------------------------------------------------------*/
+// (11)
+    half4 temp2N;
+    temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
+    temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0));
+    half4 rgby2;
+    rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
+    half lumaRangeM = (lumaMaxM - lumaMinM) / FXAA_CONSOLE__PS3_EDGE_THRESHOLD;
+/*--------------------------------------------------------------------------*/
+// (12)
+    rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0));
+    rgby2 = (temp2N + rgby2) * 0.5;
+/*--------------------------------------------------------------------------*/
+// (13)
+    rgby2 = (rgby2 + rgby1) * 0.5;
+/*--------------------------------------------------------------------------*/
+// (14)
+    #if (FXAA_GREEN_AS_LUMA == 0)
+        bool twoTapLt = rgby2.w < lumaMin;
+        bool twoTapGt = rgby2.w > lumaMax;
+    #else
+        bool twoTapLt = rgby2.y < lumaMin;
+        bool twoTapGt = rgby2.y > lumaMax;
+    #endif
+    bool earlyExit = lumaRangeM < lumaMax;
+    bool twoTap = twoTapLt || twoTapGt;
+/*--------------------------------------------------------------------------*/
+// (15)
+    if(twoTap) rgby2 = rgby1;
+    if(earlyExit) rgby2 = rgbyM;
+/*--------------------------------------------------------------------------*/
+    return rgby2; }
+/*==========================================================================*/
+#endif
+
+uniform sampler2D diffuseMap;
+
+uniform vec2 rcp_screen_res;
+uniform vec4 rcp_frame_opt;
+uniform vec4 rcp_frame_opt2;
+uniform vec2 screen_res;
+VARYING vec2 vary_fragcoord;
+VARYING vec2 vary_tc;
+
+void main() 
+{
+	vec4 diff =			FxaaPixelShader(vary_tc,			//pos
+										vec4(vary_fragcoord.xy, 0, 0), //fxaaConsolePosPos
+										diffuseMap,					//tex
+										diffuseMap,					
+										diffuseMap,
+										rcp_screen_res,				//fxaaQualityRcpFrame
+										vec4(0,0,0,0),				//fxaaConsoleRcpFrameOpt
+										rcp_frame_opt,				//fxaaConsoleRcpFrameOpt2
+										rcp_frame_opt2,				//fxaaConsole360RcpFrameOpt2
+										0.75,						//fxaaQualitySubpix
+										0.07,						//fxaaQualityEdgeThreshold
+										0.03,						//fxaaQualityEdgeThresholdMin
+										8.0,						//fxaaConsoleEdgeSharpness
+										0.125,						//fxaaConsoleEdgeThreshold
+										0.05,						//fxaaConsoleEdgeThresholdMin
+										vec4(0,0,0,0));				//fxaaConsole360ConstDir
+
+
+
+	//diff = texture2D(diffuseMap, vary_tc);
+	
+	gl_FragColor = diff;
+	
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl
index bfb7760af827752ac6ef6a9563266f04ab8bdbe1..29ca80ae92d08fcbd845ddb174a2ff2553a0c7ed 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl
@@ -23,10 +23,12 @@
  * $/LicenseInfo$
  */
  
-
-
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform sampler2DRect depthMap;
 uniform sampler2DRect normalMap;
 uniform sampler2D noiseMap;
@@ -38,7 +40,7 @@ uniform sampler2D		depthGIMap;
 uniform sampler2D		lightFunc;
 
 // Inputs
-varying vec2 vary_fragcoord;
+VARYING vec2 vary_fragcoord;
 
 uniform vec2 screen_res;
 
@@ -182,5 +184,5 @@ void main()
 	vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
 	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
 	
-	gl_FragData[0].xyz = giAmbient(pos, norm);
+	gl_FragColor.xyz = giAmbient(pos, norm);
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/giV.glsl b/indra/newview/app_settings/shaders/class1/deferred/giV.glsl
index 190e32b6a34102d938e25f11ca0f22962d66b332..e5d3bb8ea61d1fc3261f09867bc8ba43bac6b3c8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/giV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/giV.glsl
@@ -22,21 +22,27 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 modelview_projection_matrix;
 
-varying vec2 vary_fragcoord;
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_fragcoord;
 
 uniform vec2 screen_res;
 
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform(); 
-	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
+	vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	gl_Position = pos; 
+	
 	vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res;	
-	vec4 tex = gl_MultiTexCoord0;
+	vec4 tex = vec4(texcoord0,0,1);
 	tex.w = 1.0;
 
-	gl_FrontColor = gl_Color;
+	vertex_color = diffuse_color;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
index 7152e13946f45d405b670be78bc50f25d961428c..5decddebbbde7f87bf3e5ab1ff6ddd9d331c65c9 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
@@ -22,7 +22,11 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragData[3];
+#endif
+
 uniform float minimum_alpha;
 uniform float maximum_alpha;
 
@@ -31,9 +35,11 @@ uniform sampler2D diffuseMap;
 uniform sampler2D normalMap;
 uniform sampler2D specularMap;
 
+VARYING vec2 vary_texcoord0;
+
 void main() 
 {
-	vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy);
+	vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
 
 	if (col.a < minimum_alpha || col.a > maximum_alpha)
 	{
@@ -41,6 +47,6 @@ void main()
 	}
 
 	gl_FragData[0] = vec4(col.rgb, col.a * 0.005);
-	gl_FragData[1] = texture2D(specularMap, gl_TexCoord[0].xy);
-	gl_FragData[2] = vec4(texture2D(normalMap, gl_TexCoord[0].xy).xyz, 0.0);
+	gl_FragData[1] = texture2D(specularMap, vary_texcoord0.xy);
+	gl_FragData[2] = vec4(texture2D(normalMap, vary_texcoord0.xy).xyz, 0.0);
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl
index 0cf8c6817395e90ff5c7c800dd34e52ebad34718..58e5dc0b569be8312272f580ea0915495e479306 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl
@@ -22,14 +22,22 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform(); 
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); 
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 	
-	gl_FrontColor = gl_Color;
+	vertex_color = diffuse_color;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
index 4ba26fb0c6e38a34618112a26ed9d3e5753b4d51..e014a14ad86c0746dbafd48584e78b9496f7423c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
@@ -22,12 +22,14 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
-
-
-
+ 
 uniform sampler2DRect diffuseMap;
 
-varying vec2 vary_fragcoord;
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
+VARYING vec2 vary_fragcoord;
 
 void main() 
 {
diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl
index 9f22175f8402a546e2c07fe48e685ef982d4edbe..f2dc60aa5d2327ec00442d0bb17f951d06601635 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl
@@ -23,19 +23,23 @@
  * $/LicenseInfo$
  */
 
+uniform mat4 modelview_projection_matrix;
+ 
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
 
-
-
-varying vec2 vary_fragcoord;
+VARYING vec2 vary_fragcoord;
+VARYING vec4 vertex_color;
 
 uniform vec2 screen_res;
 
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform(); 
-	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
+	vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	gl_Position = pos;
+	
 	vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res;	
 
-	gl_FrontColor = gl_Color;
+	vertex_color = diffuse_color;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
index 42212a978ea4f94f9f1f3fe3f7952fd25207cf54..179c721a2fad36c471579607d3d679fc319a3f27 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
@@ -23,10 +23,12 @@
  * $/LicenseInfo$
  */
 
-
-
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform sampler2DRect depthMap;
 uniform sampler2DRect diffuseRect;
 uniform sampler2DRect specularRect;
@@ -45,7 +47,7 @@ uniform int light_count;
 uniform vec4 light[MAX_LIGHT_COUNT];
 uniform vec4 light_col[MAX_LIGHT_COUNT];
 
-varying vec4 vary_fragcoord;
+VARYING vec4 vary_fragcoord;
 uniform vec2 screen_res;
 
 uniform float far_z;
@@ -124,7 +126,7 @@ void main()
 				
 				if (sa > 0.0)
 				{
-					sa = texture2D(lightFunc,vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0);
+					sa = texture2D(lightFunc,vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0);
 					sa *= noise;
 					col += da*sa*light_col[i].rgb*spec.rgb;
 				}
@@ -141,6 +143,4 @@ void main()
 	
 	gl_FragColor.rgb = out_col;
 	gl_FragColor.a = 0.0;
-	
-	//gl_FragColor = vec4(0.1, 0.025, 0.025/4.0, 0.0);
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightMSF.glsl
deleted file mode 100644
index 863bac19cfacc6ae1df4e85293cd792affa85ca9..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightMSF.glsl
+++ /dev/null
@@ -1,155 +0,0 @@
-/** 
- * @file multiPointLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_texture_multisample : enable
-
-uniform sampler2DMS depthMap;
-uniform sampler2DMS diffuseRect;
-uniform sampler2DMS specularRect;
-uniform sampler2DMS normalMap;
-uniform sampler2D noiseMap;
-uniform sampler2D lightFunc;
-
-
-uniform vec3 env_mat[3];
-uniform float sun_wash;
-
-uniform int light_count;
-
-#define MAX_LIGHT_COUNT		16
-uniform vec4 light[MAX_LIGHT_COUNT];
-uniform vec4 light_col[MAX_LIGHT_COUNT];
-
-varying vec4 vary_fragcoord;
-uniform vec2 screen_res;
-
-uniform float far_z;
-
-uniform mat4 inv_proj;
-
-vec4 getPosition(ivec2 pos_screen, int sample)
-{
-	float depth = texelFetch(depthMap, pos_screen, sample).r;
-	vec2 sc = vec2(pos_screen.xy)*2.0;
-	sc /= screen_res;
-	sc -= vec2(1.0,1.0);
-	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
-	vec4 pos = inv_proj * ndc;
-	pos /= pos.w;
-	pos.w = 1.0;
-	return pos;
-}
-
-void main() 
-{
-	vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res;
-	ivec2 itc = ivec2(frag);
-
-	int wght = 0;
-	vec3 fcol = vec3(0,0,0);
-
-	for (int s = 0; s < samples; ++s)
-	{
-		vec3 pos = getPosition(itc, s).xyz;
-		if (pos.z >= far_z)
-		{
-			vec3 norm = texelFetch(normalMap, itc, s).xyz;
-			norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
-			norm = normalize(norm);
-			vec4 spec = texelFetch(specularRect, itc, s);
-			vec3 diff = texelFetch(diffuseRect, itc, s).rgb;
-			float noise = texture2D(noiseMap, frag.xy/128.0).b;
-			vec3 out_col = vec3(0,0,0);
-			vec3 npos = normalize(-pos);
-
-			// As of OSX 10.6.7 ATI Apple's crash when using a variable size loop
-			for (int i = 0; i < MAX_LIGHT_COUNT; ++i)
-			{
-				bool light_contrib = (i < light_count);
-		
-				vec3 lv = light[i].xyz-pos;
-				float dist2 = dot(lv,lv);
-				dist2 /= light[i].w;
-				if (dist2 > 1.0)
-				{
-					light_contrib = false;
-				}
-		
-				float da = dot(norm, lv);
-				if (da < 0.0)
-				{
-					light_contrib = false;
-				}
-		
-				if (light_contrib)
-				{
-					lv = normalize(lv);
-					da = dot(norm, lv);
-					
-					float fa = light_col[i].a+1.0;
-					float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
-					dist_atten *= noise;
-
-					float lit = da * dist_atten;
-			
-					vec3 col = light_col[i].rgb*lit*diff;
-					//vec3 col = vec3(dist2, light_col[i].a, lit);
-			
-					if (spec.a > 0.0)
-					{
-						//vec3 ref = dot(pos+lv, norm);
-				
-						float sa = dot(normalize(lv+npos),norm);
-				
-						if (sa > 0.0)
-						{
-							sa = texture2D(lightFunc,vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0);
-							sa *= noise;
-							col += da*sa*light_col[i].rgb*spec.rgb;
-						}
-					}
-			
-					out_col += col;
-				}
-			}
-	
-			fcol += out_col;
-			++wght;
-		}
-	}
-
-	if (wght <= 0)
-	{
-		discard;
-	}
-
-	gl_FragColor.rgb = fcol/samples;
-	gl_FragColor.a = 0.0;
-
-	
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl
index 1362a48daf47df6652151526936ff46bfc59ca6d..eefefa640de101a326a82d83bf5068aa8d41dc2f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl
@@ -23,16 +23,17 @@
  * $/LicenseInfo$
  */
 
+uniform mat4 modelview_projection_matrix;
 
+ATTRIBUTE vec3 position;
 
-varying vec4 vary_fragcoord;
+VARYING vec4 vary_fragcoord;
 
 void main()
 {
 	//transform vertex
-	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
+	vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
 	vary_fragcoord = pos;
 
 	gl_Position = pos;
-	gl_FrontColor = gl_Color;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
index 85b0ce5beb18cb92e3471434903ca6a07a72aeb5..2196d14895b293ea0a0e2f0abb79ae8f01a477e7 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
@@ -23,7 +23,9 @@
  * $/LicenseInfo$
  */
 
-
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
 //class 1 -- no shadows
 
@@ -35,7 +37,6 @@ uniform sampler2DRect depthMap;
 uniform sampler2DRect normalMap;
 uniform samplerCube environmentMap;
 uniform sampler2D noiseMap;
-uniform sampler2D lightFunc;
 uniform sampler2D projectionMap;
 
 uniform mat4 proj_mat; //screen space to light space
@@ -55,9 +56,12 @@ uniform float sun_wash;
 uniform int proj_shadow_idx;
 uniform float shadow_fade;
 
-varying vec4 vary_light;
+uniform vec3 center;
+uniform vec3 color;
+uniform float falloff;
+uniform float size;
 
-varying vec4 vary_fragcoord;
+VARYING vec4 vary_fragcoord;
 uniform vec2 screen_res;
 
 uniform mat4 inv_proj;
@@ -110,7 +114,7 @@ vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
 
 vec4 getPosition(vec2 pos_screen)
 {
-	float depth = texture2DRect(depthMap, pos_screen.xy).a;
+	float depth = texture2DRect(depthMap, pos_screen.xy).r;
 	vec2 sc = pos_screen.xy*2.0;
 	sc /= screen_res;
 	sc -= vec2(1.0,1.0);
@@ -129,9 +133,9 @@ void main()
 	frag.xy *= screen_res;
 	
 	vec3 pos = getPosition(frag.xy).xyz;
-	vec3 lv = vary_light.xyz-pos.xyz;
+	vec3 lv = center.xyz-pos.xyz;
 	float dist2 = dot(lv,lv);
-	dist2 /= vary_light.w;
+	dist2 /= size;
 	if (dist2 > 1.0)
 	{
 		discard;
@@ -150,7 +154,7 @@ void main()
 	
 	proj_tc.xyz /= proj_tc.w;
 	
-	float fa = gl_Color.a+1.0;
+	float fa = falloff+1.0;
 	float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
 	if (dist_atten <= 0.0)
 	{
@@ -182,7 +186,7 @@ void main()
 			
 			vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
 		
-			vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a;
+			vec3 lcol = color.rgb * plcol.rgb * plcol.a;
 			
 			lit = da * dist_atten * noise;
 			
@@ -199,7 +203,7 @@ void main()
 			
 		amb_da = min(amb_da, 1.0-lit);
 			
-		col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
+		col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
 	}
 	
 	
@@ -232,7 +236,7 @@ void main()
 					stc.y > 0.0)
 				{
 					vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
-					col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb;
+					col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb;
 				}
 			}
 		}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightMSF.glsl
deleted file mode 100644
index 10285817c213c20662f3819c9f64b28c4daef2d1..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightMSF.glsl
+++ /dev/null
@@ -1,250 +0,0 @@
-/** 
- * @file multiSpotLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-
-
-//class 1 -- no shadows
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_texture_multisample : enable
-
-uniform sampler2DMS diffuseRect;
-uniform sampler2DMS specularRect;
-uniform sampler2DMS depthMap;
-uniform sampler2DMS normalMap;
-uniform sampler2D noiseMap;
-uniform sampler2D lightFunc;
-uniform sampler2D projectionMap;
-
-uniform mat4 proj_mat; //screen space to light space
-uniform float proj_near; //near clip for projection
-uniform vec3 proj_p; //plane projection is emitting from (in screen space)
-uniform vec3 proj_n;
-uniform float proj_focus; //distance from plane to begin blurring
-uniform float proj_lod;  //(number of mips in proj map)
-uniform float proj_range; //range between near clip and far clip plane of projection
-uniform float proj_ambient_lod;
-uniform float proj_ambiance;
-uniform float near_clip;
-uniform float far_clip;
-
-uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
-uniform float sun_wash;
-uniform float shadow_fade;
-
-varying vec4 vary_light;
-
-varying vec4 vary_fragcoord;
-uniform vec2 screen_res;
-
-uniform mat4 inv_proj;
-
-vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
-{
-	vec4 ret = texture2DLod(projectionMap, tc, lod);
-	
-	vec2 dist = tc-vec2(0.5);
-	
-	float det = max(1.0-lod/(proj_lod*0.5), 0.0);
-	
-	float d = dot(dist,dist);
-		
-	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0);
-	
-	return ret;
-}
-
-vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
-{
-	vec4 ret = texture2DLod(projectionMap, tc, lod);
-	
-	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-	
-	float det = min(lod/(proj_lod*0.5), 1.0);
-	
-	float d = min(dist.x, dist.y);
-	
-	float edge = 0.25*det;
-		
-	ret *= clamp(d/edge, 0.0, 1.0);
-	
-	return ret;
-}
-
-vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
-{
-	vec4 ret = texture2DLod(projectionMap, tc, lod);
-	
-	vec2 dist = tc-vec2(0.5);
-	
-	float d = dot(dist,dist);
-		
-	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
-	
-	return ret;
-}
-
-
-vec4 getPosition(ivec2 pos_screen, int sample)
-{
-	float depth = texelFetch(depthMap, pos_screen, sample).r;
-	vec2 sc = vec2(pos_screen.xy)*2.0;
-	sc /= screen_res;
-	sc -= vec2(1.0,1.0);
-	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
-	vec4 pos = inv_proj * ndc;
-	pos /= pos.w;
-	pos.w = 1.0;
-	return pos;
-}
-
-void main() 
-{
-	int wght = 0;
-
-	vec3 fcol = vec3(0,0,0);
-
-	vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res;
-	
-	ivec2 itc = ivec2(frag.xy);
-
-	for (int i = 0; i < samples; ++i)
-	{
-		vec3 pos = getPosition(itc, i).xyz;
-		vec3 lv = vary_light.xyz-pos.xyz;
-		float dist2 = dot(lv,lv);
-		dist2 /= vary_light.w;
-		if (dist2 <= 1.0)
-		{
-			vec3 norm = texelFetch(normalMap, itc, i).xyz*2.0-1.0;
-	
-			norm = normalize(norm);
-			float l_dist = -dot(lv, proj_n);
-	
-			vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
-			if (proj_tc.z >= 0.0)
-			{
-				proj_tc.xyz /= proj_tc.w;
-	
-				float fa = gl_Color.a+1.0;
-				float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
-				if (dist_atten > 0.0)
-				{
-					lv = proj_origin-pos.xyz;
-					lv = normalize(lv);
-					float da = dot(norm, lv);
-		
-					vec3 col = vec3(0,0,0);
-		
-					vec3 diff_tex = texelFetch(diffuseRect, itc, i).rgb;
-		
-					float noise = texture2D(noiseMap, frag.xy/128.0).b;
-					if (proj_tc.z > 0.0 &&
-						proj_tc.x < 1.0 &&
-						proj_tc.y < 1.0 &&
-						proj_tc.x > 0.0 &&
-						proj_tc.y > 0.0)
-					{
-						float lit = 0.0;
-						float amb_da = proj_ambiance;
-		
-						if (da > 0.0)
-						{
-							float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
-							float lod = diff * proj_lod;
-			
-							vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
-		
-							vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a;
-			
-							lit = da * dist_atten * noise;
-			
-							col = lcol*lit*diff_tex;
-							amb_da += (da*0.5)*proj_ambiance;
-						}
-		
-						//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
-						vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
-							
-						amb_da += (da*da*0.5+0.5)*proj_ambiance;
-				
-						amb_da *= dist_atten * noise;
-			
-						amb_da = min(amb_da, 1.0-lit);
-			
-						col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
-					}
-	
-	
-					vec4 spec = texelFetch(specularRect, itc, i);
-					if (spec.a > 0.0)
-					{
-						vec3 ref = reflect(normalize(pos), norm);
-		
-						//project from point pos in direction ref to plane proj_p, proj_n
-						vec3 pdelta = proj_p-pos;
-						float ds = dot(ref, proj_n);
-		
-						if (ds < 0.0)
-						{
-							vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
-			
-							vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
-
-							if (stc.z > 0.0)
-							{
-								stc.xy /= stc.w;
-
-								float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
-				
-								stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
-								
-								if (stc.x < 1.0 &&
-									stc.y < 1.0 &&
-									stc.x > 0.0 &&
-									stc.y > 0.0)
-								{
-									vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
-									col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb;
-								}
-							}
-						}
-					}
-	
-					fcol += col;
-					++wght;
-				}
-			}
-		}
-	}
-
-	if (wght <= 0)
-	{
-		discard;
-	}
-
-	gl_FragColor.rgb = fcol/samples;	
-	gl_FragColor.a = 0.0;
-}
diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl
similarity index 54%
rename from indra/newview/app_settings/shaders/class1/effects/glowExtractMSF.glsl
rename to indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl
index c2cc8ed5677a096dc946bb4e76434e1e9eb86195..879942d8faa7cd04b53e9a31ea516673c19717a0 100644
--- a/indra/newview/app_settings/shaders/class1/effects/glowExtractMSF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl
@@ -1,5 +1,5 @@
 /** 
- * @file glowExtractF.glsl
+ * @file normgenF.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -23,34 +23,34 @@
  * $/LicenseInfo$
  */
  
+#extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_texture_multisample : enable
+uniform sampler2D alphaMap;
 
-uniform sampler2DMS diffuseMap;
-uniform float minLuminance;
-uniform float maxExtractAlpha;
-uniform vec3 lumWeights;
-uniform vec3 warmthWeights;
-uniform float warmthAmount;
+VARYING vec2 vary_texcoord0;
+
+uniform float stepX;
+uniform float stepY;
+uniform float norm_scale;
 
 void main()
 {
-	ivec2 itc = ivec2(gl_TexCoord[0].xy);
-	vec4 fcol = vec4(0,0,0,0);
-
-	for (int i = 0; i < samples; i++)
-	{
-		vec4 col = texelFetch(diffuseMap, itc, i);	
+	float alpha = texture2D(alphaMap, vary_texcoord0).a;
 
-		/// CALCULATING LUMINANCE (Using NTSC lum weights)
-		/// http://en.wikipedia.org/wiki/Luma_%28video%29
-		float lum = smoothstep(minLuminance, minLuminance+1.0, dot(col.rgb, lumWeights ) );
-		float warmth = smoothstep(minLuminance, minLuminance+1.0, max(col.r * warmthWeights.r, max(col.g * warmthWeights.g, col.b * warmthWeights.b)) ); 
+	vec3 right = vec3(norm_scale, 0, (texture2D(alphaMap, vary_texcoord0+vec2(stepX, 0)).a-alpha)*255);
+	vec3 left = vec3(-norm_scale, 0, (texture2D(alphaMap, vary_texcoord0-vec2(stepX, 0)).a-alpha)*255);
+	vec3 up = vec3(0, -norm_scale, (texture2D(alphaMap, vary_texcoord0-vec2(0, stepY)).a-alpha)*255);
+	vec3 down = vec3(0, norm_scale, (texture2D(alphaMap, vary_texcoord0+vec2(0, stepY)).a-alpha)*255);
 	
-		fcol += vec4(col.rgb, max(col.a, mix(lum, warmth, warmthAmount) * maxExtractAlpha));
-	}
-
-	gl_FragColor = fcol/samples;
+	vec3 norm = cross(right, down) + cross(down, left) + cross(left,up) + cross(up, right);
+	
+	norm = normalize(norm);
+	norm *= 0.5;
+	norm += 0.5;	
+	
+	gl_FragColor = vec4(norm, alpha);
 }
diff --git a/indra/newview/app_settings/shaders/class3/deferred/giFinalV.glsl b/indra/newview/app_settings/shaders/class1/deferred/normgenV.glsl
similarity index 80%
rename from indra/newview/app_settings/shaders/class3/deferred/giFinalV.glsl
rename to indra/newview/app_settings/shaders/class1/deferred/normgenV.glsl
index a6a206502c7ff7fd3dc0553da9bcfa24b60fbddb..9bceae05b71d05783930f7264aa3a13cc7093bab 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/giFinalV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/normgenV.glsl
@@ -1,5 +1,5 @@
 /** 
- * @file giFinalV.glsl
+ * @file normgenV.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -23,15 +23,14 @@
  * $/LicenseInfo$
  */
  
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
 
-
-varying vec2 vary_fragcoord;
-uniform vec2 screen_res;
+VARYING vec2 vary_fragcoord;
+VARYING vec2 vary_texcoord0;
 
 void main()
 {
-	//transform vertex
-	gl_Position = ftransform(); 
-	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
-	vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
+	gl_Position = vec4(position.x*2.0-1.0, position.y*2.0-1.0, -1.0, 1.0); 
+	vary_texcoord0 = texcoord0;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
index 0771f9b91a975954a8864f91b33fd67ad7065a8a..b673d00d6e2e1dd1909d840b76b9733a75f9fa0b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
@@ -23,10 +23,12 @@
  * $/LicenseInfo$
  */
  
- 
-
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform sampler2DRect diffuseRect;
 uniform sampler2DRect specularRect;
 uniform sampler2DRect normalMap;
@@ -38,9 +40,12 @@ uniform sampler2DRect depthMap;
 uniform vec3 env_mat[3];
 uniform float sun_wash;
 
-varying vec4 vary_light;
+uniform vec3 center;
+uniform vec3 color;
+uniform float falloff;
+uniform float size;
 
-varying vec4 vary_fragcoord;
+VARYING vec4 vary_fragcoord;
 uniform vec2 screen_res;
 
 uniform mat4 inv_proj;
@@ -67,9 +72,9 @@ void main()
 	frag.xy *= screen_res;
 	
 	vec3 pos = getPosition(frag.xy).xyz;
-	vec3 lv = vary_light.xyz-pos;
+	vec3 lv = center.xyz-pos;
 	float dist2 = dot(lv,lv);
-	dist2 /= vary_light.w;
+	dist2 /= size;
 	if (dist2 > 1.0)
 	{
 		discard;
@@ -90,11 +95,11 @@ void main()
 	float noise = texture2D(noiseMap, frag.xy/128.0).b;
 	
 	vec3 col = texture2DRect(diffuseRect, frag.xy).rgb;
-	float fa = gl_Color.a+1.0;
+	float fa = falloff+1.0;
 	float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
 	float lit = da * dist_atten * noise;
 	
-	col = gl_Color.rgb*lit*col;
+	col = color.rgb*lit*col;
 
 	vec4 spec = texture2DRect(specularRect, frag.xy);
 	if (spec.a > 0.0)
@@ -102,9 +107,9 @@ void main()
 		float sa = dot(normalize(lv-normalize(pos)),norm);
 		if (sa > 0.0)
 		{
-			sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0);
+			sa = texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0);
 			sa *= noise;
-			col += da*sa*gl_Color.rgb*spec.rgb;
+			col += da*sa*color.rgb*spec.rgb;
 		}
 	}
 	
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightMSF.glsl
deleted file mode 100644
index cdce58c84ef540bd35be24fac4a8e8842b3b0334..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightMSF.glsl
+++ /dev/null
@@ -1,126 +0,0 @@
-/** 
- * @file pointLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
- 
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_texture_multisample : enable
-
-uniform sampler2DMS depthMap;
-uniform sampler2DMS diffuseRect;
-uniform sampler2DMS specularRect;
-uniform sampler2DMS normalMap;
-uniform sampler2D noiseMap;
-uniform sampler2D lightFunc;
-
-
-uniform vec3 env_mat[3];
-uniform float sun_wash;
-
-varying vec4 vary_light;
-
-varying vec4 vary_fragcoord;
-uniform vec2 screen_res;
-
-uniform mat4 inv_proj;
-uniform vec4 viewport;
-
-vec4 getPosition(ivec2 pos_screen, int sample)
-{
-	float depth = texelFetch(depthMap, pos_screen, sample).r;
-	vec2 sc = (vec2(pos_screen.xy)-viewport.xy)*2.0;
-	sc /= viewport.zw;
-	sc -= vec2(1.0,1.0);
-	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
-	vec4 pos = inv_proj * ndc;
-	pos /= pos.w;
-	pos.w = 1.0;
-	return pos;
-}
-
-void main() 
-{
-	vec4 frag = vary_fragcoord;
-	frag.xyz /= frag.w;
-	frag.xyz = frag.xyz*0.5+0.5;
-	frag.xy *= screen_res;
-	
-	ivec2 itc = ivec2(frag.xy);
-
-	int wght = 0;
-	vec3 fcol = vec3(0,0,0);
-
-	for (int s = 0; s < samples; ++s)
-	{
-		vec3 pos = getPosition(itc, s).xyz;
-		vec3 lv = vary_light.xyz-pos;
-		float dist2 = dot(lv,lv);
-		dist2 /= vary_light.w;
-		if (dist2 <= 1.0)
-		{
-			vec3 norm = texelFetch(normalMap, itc, s).xyz;
-			norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
-			float da = dot(norm, lv);
-			if (da >= 0.0)
-			{
-				norm = normalize(norm);
-				lv = normalize(lv);
-				da = dot(norm, lv);
-	
-				float noise = texture2D(noiseMap, frag.xy/128.0).b;
-	
-				vec3 col = texelFetch(diffuseRect, itc, s).rgb;
-				float fa = gl_Color.a+1.0;
-				float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
-				float lit = da * dist_atten * noise;
-	
-				col = gl_Color.rgb*lit*col;
-
-				vec4 spec = texelFetch(specularRect, itc, s);
-				if (spec.a > 0.0)
-				{
-					float sa = dot(normalize(lv-normalize(pos)),norm);
-					if (sa > 0.0)
-					{
-						sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0);
-						sa *= noise;
-						col += da*sa*gl_Color.rgb*spec.rgb;
-					}
-				}
-
-				fcol += col;
-				++wght;
-			}
-		}
-	}
-	
-	if (wght <= 0)
-	{
-		discard;
-	}
-		
-	gl_FragColor.rgb = fcol/samples;	
-	gl_FragColor.a = 0.0;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
index db1b9d3feb88f3e16de78253322a00289e4d4a5a..cb14e6d4e8b164235c9c53ecbb72081ea167b1fd 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
@@ -23,23 +23,17 @@
  * $/LicenseInfo$
  */
 
+uniform mat4 modelview_projection_matrix;
 
+ATTRIBUTE vec3 position;
 
-varying vec4 vary_light;
-varying vec4 vary_fragcoord;
+VARYING vec4 vary_fragcoord;
 
 void main()
 {
 	//transform vertex
-	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
+	vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
 	vary_fragcoord = pos;
 		
-	vec4 tex = gl_MultiTexCoord0;
-	tex.w = 1.0;
-	
-	vary_light = gl_MultiTexCoord0;
-	
 	gl_Position = pos;
-		
-	gl_FrontColor = gl_Color;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
index 29f5f899ba20eeb9856ff3d2a77a4c8cf0cdfba0..985f44fb6c9d7dc35f12a8a60fcc9229f612e6b7 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
@@ -22,11 +22,13 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
-
 
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform sampler2DRect diffuseRect;
 uniform sampler2DRect edgeMap;
 uniform sampler2DRect depthMap;
@@ -43,7 +45,7 @@ uniform float magnification;
 uniform mat4 inv_proj;
 uniform vec2 screen_res;
 
-varying vec2 vary_fragcoord;
+VARYING vec2 vary_fragcoord;
 
 float getDepth(vec2 pos_screen)
 {
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredMSF.glsl
deleted file mode 100644
index 792102a64d7835144c588d4ba8af1d0ed9c6e666..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredMSF.glsl
+++ /dev/null
@@ -1,151 +0,0 @@
-/** 
- * @file postDeferredF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_texture_multisample : enable
-
-uniform sampler2DMS diffuseRect;
-uniform sampler2DMS edgeMap;
-uniform sampler2DMS depthMap;
-uniform sampler2DMS normalMap;
-uniform sampler2D bloomMap;
-
-uniform float depth_cutoff;
-uniform float norm_cutoff;
-uniform float focal_distance;
-uniform float blur_constant;
-uniform float tan_pixel_angle;
-uniform float magnification;
-
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-varying vec2 vary_fragcoord;
-
-vec4 texture2DMS(sampler2DMS tex, ivec2 tc)
-{
-	vec4 ret = vec4(0,0,0,0);
-	for (int i = 0; i < samples; ++i)
-	{
-		ret += texelFetch(tex, tc, i);
-	}
-
-	return ret/samples;
-}
-
-float getDepth(ivec2 pos_screen)
-{
-	float z = texture2DMS(depthMap, pos_screen.xy).r;
-	z = z*2.0-1.0;
-	vec4 ndc = vec4(0.0, 0.0, z, 1.0);
-	vec4 p = inv_proj*ndc;
-	return p.z/p.w;
-}
-
-float calc_cof(float depth)
-{
-	float sc = abs(depth-focal_distance)/-depth*blur_constant;
-		
-	sc /= magnification;
-	
-	// tan_pixel_angle = pixel_length/-depth;
-	float pixel_length =  tan_pixel_angle*-focal_distance;
-	
-	sc = sc/pixel_length;
-	sc *= 1.414;
-	
-	return sc;
-}
-
-void dofSample(inout vec4 diff, inout float w, float min_sc, float cur_depth, ivec2 tc)
-{
-	float d = getDepth(tc);
-	
-	float sc = calc_cof(d);
-	
-	if (sc > min_sc //sampled pixel is more "out of focus" than current sample radius
-	   || d < cur_depth) //sampled pixel is further away than current pixel
-	{
-		float wg = 0.25;
-		
-		vec4 s = texture2DMS(diffuseRect, tc);
-		// de-weight dull areas to make highlights 'pop'
-		wg += s.r+s.g+s.b;
-	
-		diff += wg*s;
-		
-		w += wg;
-	}
-}
-
-
-void main() 
-{
-	ivec2 itc = ivec2(vary_fragcoord.xy);
-
-	vec3 norm = texture2DMS(normalMap, itc).xyz;
-	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
-		
-	float depth = getDepth(itc);
-	
-	vec4 diff = texture2DMS(diffuseRect, itc);
-	
-	{ 
-		float w = 1.0;
-		
-		float sc = calc_cof(depth);
-		sc = min(abs(sc), 10.0);
-		
-		float fd = depth*0.5f;
-		
-		float PI = 3.14159265358979323846264;
-
-		int isc = int(sc);
-		
-		// sample quite uniformly spaced points within a circle, for a circular 'bokeh'		
-		//if (depth < focal_distance)
-		{
-			for (int x = -isc; x <= isc; x+=2)
-			{
-				for (int y = -isc; y <= isc; y+=2)
-				{
-					ivec2 cur_samp = ivec2(x,y);
-					float cur_sc = length(vec2(cur_samp));
-					if (cur_sc < sc)
-					{
-						dofSample(diff, w, cur_sc, depth, itc+cur_samp);
-					}
-				}
-			}
-		}
-		
-		diff /= w;
-	}
-		
-	vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res);
-	gl_FragColor = diff + bloom;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl
index 34e30a30703d9efd7bb53eedce7b146ab20e8be6..c275434777256419a97d9457fd537b557f5357e9 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl
@@ -1,5 +1,5 @@
 /** 
- * @file postDeferredF.glsl
+ * @file postDeferredNoDoFF.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -23,15 +23,17 @@
  * $/LicenseInfo$
  */
  
-
-
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform sampler2DRect diffuseRect;
 uniform sampler2D bloomMap;
 
 uniform vec2 screen_res;
-varying vec2 vary_fragcoord;
+VARYING vec2 vary_fragcoord;
 
 void main() 
 {
@@ -40,3 +42,4 @@ void main()
 	vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res);
 	gl_FragColor = diff + bloom;
 }
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl
index cb83dda795f87098fd9d5bc508b27c762cc53fff..8edf5b2723f90450d09bf857126bdcfc18f9501a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl
@@ -22,16 +22,23 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+
+VARYING vec2 vary_fragcoord;
+VARYING vec2 vary_tc;
+
+uniform vec2 tc_scale;
 
-varying vec2 vary_fragcoord;
 uniform vec2 screen_res;
 
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform(); 
-	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
+	vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	gl_Position = pos;	
+	vary_tc = (pos.xy*0.5+0.5)*tc_scale;
 	vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl
index 99257daca4a8c5b316e67edb5e5869cbaf3d9626..84d65d5b3b23b678e8ede1d53da38b32c970ff45 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl
@@ -22,9 +22,11 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
-
 
+ #ifdef DEFINE_GL_FRAGCOLOR
+ out vec4 gl_FragColor;
+ #endif
+ 
 uniform sampler2DRect depthMap;
 uniform sampler2DRect normalMap;
 uniform sampler2DRect giLightMap;
@@ -38,7 +40,7 @@ uniform int kern_length;
 uniform float kern_scale;
 uniform vec3 blur_quad;
 
-varying vec2 vary_fragcoord;
+VARYING vec2 vary_fragcoord;
 
 uniform mat4 inv_proj;
 uniform vec2 screen_res;
@@ -94,7 +96,5 @@ void main()
 	
 	col = col*col*blur_quad.x + col*blur_quad.y + blur_quad.z;
 	
-	gl_FragData[0].xyz = col;
-	
-	//gl_FragColor = ccol;
+	gl_FragColor.rgb = col;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl
index 6231ee68b75c69b50b1cbd480d448b468fd89833..0d5c8e728740cfb0bb3b7db95efab885d7895577 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl
@@ -22,16 +22,19 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
+
+uniform mat4 modelview_projection_matrix;
  
+ATTRIBUTE vec3 position;
 
 
-varying vec2 vary_fragcoord;
+VARYING vec2 vary_fragcoord;
 uniform vec2 screen_res;
 
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform(); 
-	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
+	vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	gl_Position = pos; 	
 	vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
index 615317febfd24ef4fb9ba842143098fa2658d118..71b12326d8b0a7ece01bf13bc2eb5bca1d678bb2 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
@@ -22,17 +22,23 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform float minimum_alpha;
 uniform float maximum_alpha;
 
 uniform sampler2D diffuseMap;
 
-varying vec4 post_pos;
+VARYING vec4 post_pos;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 void main() 
 {
-	float alpha = texture2D(diffuseMap, gl_TexCoord[0].xy).a * gl_Color.a;
+	float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a * vertex_color.a;
 
 	if (alpha < minimum_alpha || alpha > maximum_alpha)
 	{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
index 4be18a9c5e4970edc957ab4c08f61bc5248a17dd..6a3cba771bbdba0bb3dbc0b1569e3a8b27015bde 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
@@ -22,20 +22,27 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
 
-varying vec4 post_pos;
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 post_pos;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 void main()
 {
 	//transform vertex
-	vec4 pos = gl_ModelViewProjectionMatrix*gl_Vertex;
+	vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
 	
 	post_pos = pos;
 	
 	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
 	
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
-	gl_FrontColor = gl_Color;
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+	vertex_color = diffuse_color;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
index 541f08d5fe71b4bdaef723fbe5936260e6cfe51a..bf75ca262ec1f72161a845c7a3d350c43b32594d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
@@ -23,9 +23,11 @@
  * $/LicenseInfo$
  */
  
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
-
-varying vec4 post_pos;
+VARYING vec4 post_pos;
 
 void main() 
 {
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
index fc3ff45614876bae6c0e6d19ebaa8f7307ab49df..8b46e81f90c03a12ed5d3b4ade3cf217c920d5db 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
@@ -22,15 +22,17 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 modelview_projection_matrix;
 
-varying vec4 post_pos;
+ATTRIBUTE vec3 position;
+
+VARYING vec4 post_pos;
 
 void main()
 {
 	//transform vertex
-	vec4 pos = gl_ModelViewProjectionMatrix*gl_Vertex;
+	vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
 	
 	post_pos = pos;
 	
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
index 59c0a994cdd79d075696a7edb5af51d3dc5e0ff4..96ad0aa93a374f2564840ea123677797f22c9a07 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
@@ -23,13 +23,15 @@
  * $/LicenseInfo$
  */
  
-
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragData[3];
+#endif
 
 /////////////////////////////////////////////////////////////////////////
 // The fragment shader for the sky
 /////////////////////////////////////////////////////////////////////////
 
-varying vec4 vary_HazeColor;
+VARYING vec4 vary_HazeColor;
 
 uniform sampler2D cloud_noise_texture;
 uniform vec4 gamma;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
index 3a44bb6d261af16a1a9fc5f87539a66c9edc32ea..721de18e0b15b05cbd1786833dee4ddb3ed44ad5 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
@@ -22,15 +22,19 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
 
 // SKY ////////////////////////////////////////////////////////////////////////
 // The vertex shader for creating the atmospheric sky
 ///////////////////////////////////////////////////////////////////////////////
 
 // Output parameters
-varying vec4 vary_HazeColor;
+VARYING vec4 vary_HazeColor;
+VARYING vec2 vary_texcoord0;
 
 // Inputs
 uniform vec3 camPosLocal;
@@ -57,12 +61,12 @@ void main()
 {
 
 	// World / view / projection
-	gl_Position = ftransform();
-	gl_TexCoord[0] = gl_MultiTexCoord0;
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	vary_texcoord0 = texcoord0;
 
 	// Get relative position
-	vec3 P = gl_Vertex.xyz - camPosLocal.xyz + vec3(0,50,0);
-	//vec3 P = gl_Vertex.xyz + vec3(0,50,0);
+	vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0);
+	//vec3 P = position.xyz + vec3(0,50,0);
 
 	// Set altitude
 	if (P.y > 0.)
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index 855d89ebe605a4b2f921f175131850c59ba95e38..60952ea38ec00e01569f3232bf5f0ed16accf83e 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -23,10 +23,12 @@
  * $/LicenseInfo$
  */
  
-
-
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform sampler2DRect diffuseRect;
 uniform sampler2DRect specularRect;
 uniform sampler2DRect positionMap;
@@ -63,8 +65,8 @@ uniform vec3 env_mat[3];
 //uniform vec4 shadow_clip;
 uniform mat3 ssao_effect_mat;
 
-varying vec4 vary_light;
-varying vec2 vary_fragcoord;
+uniform vec3 sun_dir;
+VARYING vec2 vary_fragcoord;
 
 vec3 vary_PositionEye;
 
@@ -146,10 +148,6 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
 	vec3 P = inPositionEye;
 	setPositionEye(P);
 	
-	//(TERRAIN) limit altitude
-	if (P.y > max_y.x) P *= (max_y.x / P.y);
-	if (P.y < -max_y.x) P *= (-max_y.x / P.y);
-
 	vec3 tmpLightnorm = lightnorm.xyz;
 
 	vec3 Pn = normalize(P);
@@ -283,7 +281,7 @@ void main()
 	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
 	//vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz;
 	
-	float da = max(dot(norm.xyz, vary_light.xyz), 0.0);
+	float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
 	
 	vec4 diffuse = texture2DRect(diffuseRect, tc);
 	vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
@@ -304,8 +302,8 @@ void main()
 			// the old infinite-sky shiny reflection
 			//
 			vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-			float sa = dot(refnormpersp, vary_light.xyz);
-			vec3 dumbshiny = vary_SunlitColor*texture2D(lightFunc, vec2(sa, spec.a)).a;
+			float sa = dot(refnormpersp, sun_dir.xyz);
+			vec3 dumbshiny = vary_SunlitColor*texture2D(lightFunc, vec2(sa, spec.a)).r;
 			
 			// add the two types of shiny together
 			vec3 spec_contrib = dumbshiny * spec.rgb;
@@ -324,5 +322,6 @@ void main()
 	}
 
 	gl_FragColor.rgb = col;
+
 	gl_FragColor.a = bloom;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightMSF.glsl
deleted file mode 100644
index f118b0da2a486be459313fdb707d0a1cff4420a2..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightMSF.glsl
+++ /dev/null
@@ -1,342 +0,0 @@
-/** 
- * @file softenLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_texture_multisample : enable
-
-uniform sampler2DMS diffuseRect;
-uniform sampler2DMS specularRect;
-uniform sampler2DMS normalMap;
-uniform sampler2DMS depthMap;
-uniform sampler2D	  noiseMap;
-uniform samplerCube environmentMap;
-uniform sampler2D	  lightFunc;
-
-uniform float blur_size;
-uniform float blur_fidelity;
-
-// Inputs
-uniform vec4 morphFactor;
-uniform vec3 camPosLocal;
-//uniform vec4 camPosWorld;
-uniform vec4 gamma;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 ambient;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
-uniform vec4 haze_horizon;
-uniform vec4 haze_density;
-uniform vec4 cloud_shadow;
-uniform vec4 density_multiplier;
-uniform vec4 distance_multiplier;
-uniform vec4 max_y;
-uniform vec4 glow;
-uniform float scene_light_strength;
-uniform vec3 env_mat[3];
-//uniform mat4 shadow_matrix[3];
-//uniform vec4 shadow_clip;
-uniform mat3 ssao_effect_mat;
-
-varying vec4 vary_light;
-varying vec2 vary_fragcoord;
-
-vec3 vary_PositionEye;
-
-vec3 vary_SunlitColor;
-vec3 vary_AmblitColor;
-vec3 vary_AdditiveColor;
-vec3 vary_AtmosAttenuation;
-
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-vec4 getPosition_d(vec2 pos_screen, float depth)
-{
-	vec2 sc = pos_screen.xy*2.0;
-	sc /= screen_res;
-	sc -= vec2(1.0,1.0);
-	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
-	vec4 pos = inv_proj * ndc;
-	pos /= pos.w;
-	pos.w = 1.0;
-	return pos;
-}
-
-vec3 getPositionEye()
-{
-	return vary_PositionEye;
-}
-vec3 getSunlitColor()
-{
-	return vary_SunlitColor;
-}
-vec3 getAmblitColor()
-{
-	return vary_AmblitColor;
-}
-vec3 getAdditiveColor()
-{
-	return vary_AdditiveColor;
-}
-vec3 getAtmosAttenuation()
-{
-	return vary_AtmosAttenuation;
-}
-
-
-void setPositionEye(vec3 v)
-{
-	vary_PositionEye = v;
-}
-
-void setSunlitColor(vec3 v)
-{
-	vary_SunlitColor = v;
-}
-
-void setAmblitColor(vec3 v)
-{
-	vary_AmblitColor = v;
-}
-
-void setAdditiveColor(vec3 v)
-{
-	vary_AdditiveColor = v;
-}
-
-void setAtmosAttenuation(vec3 v)
-{
-	vary_AtmosAttenuation = v;
-}
-
-void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
-
-	vec3 P = inPositionEye;
-	setPositionEye(P);
-	
-	//(TERRAIN) limit altitude
-	if (P.y > max_y.x) P *= (max_y.x / P.y);
-	if (P.y < -max_y.x) P *= (-max_y.x / P.y);
-
-	vec3 tmpLightnorm = lightnorm.xyz;
-
-	vec3 Pn = normalize(P);
-	float Plen = length(P);
-
-	vec4 temp1 = vec4(0);
-	vec3 temp2 = vec3(0);
-	vec4 blue_weight;
-	vec4 haze_weight;
-	vec4 sunlight = sunlight_color;
-	vec4 light_atten;
-
-	//sunlight attenuation effect (hue and brightness) due to atmosphere
-	//this is used later for sunlight modulation at various altitudes
-	light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x);
-		//I had thought blue_density and haze_density should have equal weighting,
-		//but attenuation due to haze_density tends to seem too strong
-
-	temp1 = blue_density + vec4(haze_density.r);
-	blue_weight = blue_density / temp1;
-	haze_weight = vec4(haze_density.r) / temp1;
-
-	//(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
-	temp2.y = max(0.0, tmpLightnorm.y);
-	temp2.y = 1. / temp2.y;
-	sunlight *= exp( - light_atten * temp2.y);
-
-	// main atmospheric scattering line integral
-	temp2.z = Plen * density_multiplier.x;
-
-	// Transparency (-> temp1)
-	// ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati
-	// compiler gets confused.
-	temp1 = exp(-temp1 * temp2.z * distance_multiplier.x);
-
-	//final atmosphere attenuation factor
-	setAtmosAttenuation(temp1.rgb);
-	
-	//compute haze glow
-	//(can use temp2.x as temp because we haven't used it yet)
-	temp2.x = dot(Pn, tmpLightnorm.xyz);
-	temp2.x = 1. - temp2.x;
-		//temp2.x is 0 at the sun and increases away from sun
-	temp2.x = max(temp2.x, .03);	//was glow.y
-		//set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
-	temp2.x *= glow.x;
-		//higher glow.x gives dimmer glow (because next step is 1 / "angle")
-	temp2.x = pow(temp2.x, glow.z);
-		//glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
-	//add "minimum anti-solar illumination"
-	temp2.x += .25;
-	
-	//increase ambient when there are more clouds
-	vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5;
-	
-	/*  decrease value and saturation (that in HSV, not HSL) for occluded areas
-	 * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
-	 * // The following line of code performs the equivalent of:
-	 * float ambAlpha = tmpAmbient.a;
-	 * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
-	 * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
-	 * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
-	 */
-	tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
-
-	//haze color
-	setAdditiveColor(
-		vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient)
-	  + (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x
-		  + tmpAmbient)));
-
-	//brightness of surface both sunlight and ambient
-	setSunlitColor(vec3(sunlight * .5));
-	setAmblitColor(vec3(tmpAmbient * .25));
-	setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
-}
-
-vec3 atmosLighting(vec3 light)
-{
-	light *= getAtmosAttenuation().r;
-	light += getAdditiveColor();
-	return (2.0 * light);
-}
-
-vec3 atmosTransport(vec3 light) {
-	light *= getAtmosAttenuation().r;
-	light += getAdditiveColor() * 2.0;
-	return light;
-}
-vec3 atmosGetDiffuseSunlightColor()
-{
-	return getSunlitColor();
-}
-
-vec3 scaleDownLight(vec3 light)
-{
-	return (light / scene_light_strength );
-}
-
-vec3 scaleUpLight(vec3 light)
-{
-	return (light * scene_light_strength);
-}
-
-vec3 atmosAmbient(vec3 light)
-{
-	return getAmblitColor() + light / 2.0;
-}
-
-vec3 atmosAffectDirectionalLight(float lightIntensity)
-{
-	return getSunlitColor() * lightIntensity;
-}
-
-vec3 scaleSoftClip(vec3 light)
-{
-	//soft clip effect:
-	light = 1. - clamp(light, vec3(0.), vec3(1.));
-	light = 1. - pow(light, gamma.xxx);
-
-	return light;
-}
-
-vec4 texture2DMS(sampler2DMS tex, ivec2 tc)
-{
-	vec4 ret = vec4(0,0,0,0);
-
-	for (int i = 0; i < samples; ++i)
-	{
-		 ret += texelFetch(tex,tc,i);
-	}
-
-	return ret/samples;
-}
-
-void main() 
-{
-	vec2 tc = vary_fragcoord.xy;
-	ivec2 itc = ivec2(tc);
-
-	vec4 fcol = vec4(0,0,0,0);
-
-	for (int i = 0; i < samples; ++i)
-	{
-		float depth = texelFetch(depthMap, itc, i).r;
-		vec3 pos = getPosition_d(tc, depth).xyz;
-		vec3 norm = texelFetch(normalMap, itc, i).xyz;
-
-		norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
-		//vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz;
-	
-		float da = max(dot(norm.xyz, vary_light.xyz), 0.0);
-	
-		vec4 diffuse = texelFetch(diffuseRect, itc, i);
-		vec3 col;
-		float bloom = 0.0;
-
-		if (diffuse.a < 0.9)
-		{
-			vec4 spec = texelFetch(specularRect, itc, i);
-	
-			calcAtmospherics(pos.xyz, 1.0);
-	
-			col = atmosAmbient(vec3(0));
-			col += atmosAffectDirectionalLight(max(min(da, 1.0), diffuse.a));
-	
-			col *= diffuse.rgb;
-	
-			if (spec.a > 0.0) // specular reflection
-			{
-				// the old infinite-sky shiny reflection
-				//
-				vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-				float sa = dot(refnormpersp, vary_light.xyz);
-				vec3 dumbshiny = vary_SunlitColor*texture2D(lightFunc, vec2(sa, spec.a)).a;
-
-				// add the two types of shiny together
-				vec3 spec_contrib = dumbshiny * spec.rgb;
-				bloom = dot(spec_contrib, spec_contrib);
-				col += spec_contrib;
-			}
-
-			col = atmosLighting(col);
-			col = scaleSoftClip(col);
-			col = mix(col, diffuse.rgb, diffuse.a);
-		}
-		else
-		{
-			col = diffuse.rgb;
-		}
-
-		fcol += vec4(col, bloom);
-	}
-				
-	gl_FragColor = fcol/samples;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl
index fed238510a0281a7f4b81520f4c81b9a3972fe89..c6031fc45a28a184822ff9d1118a2443e8ec76e6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl
@@ -23,22 +23,18 @@
  * $/LicenseInfo$
  */
  
+uniform mat4 modelview_projection_matrix;
 
+ATTRIBUTE vec3 position;
 
 uniform vec2 screen_res;
 
-varying vec4 vary_light;
-varying vec2 vary_fragcoord;
+VARYING vec2 vary_fragcoord;
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform(); 
-	
-	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
-	vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
+	vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	gl_Position = pos; 
 		
-	vec4 tex = gl_MultiTexCoord0;
-	tex.w = 1.0;
-	
-	vary_light = gl_MultiTexCoord0;
+	vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
index 7363bd671512a03269c14e4da241d02ee81ca1b9..cc0f4e5b6bff3cfe0e0478986857417476433719 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
@@ -23,17 +23,18 @@
  * $/LicenseInfo$
  */
 
-
-
+ 
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform sampler2DRect diffuseRect;
 uniform sampler2DRect specularRect;
 uniform sampler2DRect depthMap;
 uniform sampler2DRect normalMap;
-uniform samplerCube environmentMap;
 uniform sampler2D noiseMap;
-uniform sampler2D lightFunc;
 uniform sampler2D projectionMap;
 
 uniform mat4 proj_mat; //screen space to light space
@@ -50,9 +51,12 @@ uniform float far_clip;
 uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
 uniform float sun_wash;
 
-varying vec4 vary_light;
+uniform vec3 center;
+uniform vec3 color;
+uniform float falloff;
+uniform float size;
 
-varying vec4 vary_fragcoord;
+VARYING vec4 vary_fragcoord;
 uniform vec2 screen_res;
 
 uniform mat4 inv_proj;
@@ -78,9 +82,9 @@ void main()
 	frag.xy *= screen_res;
 	
 	vec3 pos = getPosition(frag.xy).xyz;
-	vec3 lv = vary_light.xyz-pos.xyz;
+	vec3 lv = center.xyz-pos.xyz;
 	float dist2 = dot(lv,lv);
-	dist2 /= vary_light.w;
+	dist2 /= size;
 	if (dist2 > 1.0)
 	{
 		discard;
@@ -100,7 +104,7 @@ void main()
 	
 	proj_tc.xyz /= proj_tc.w;
 	
-	float fa = gl_Color.a+1.0;
+	float fa = falloff+1.0;
 	float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
 	
 	lv = proj_origin-pos.xyz;
@@ -126,7 +130,7 @@ void main()
 			
 			vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
 		
-			vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a;
+			vec3 lcol = color.rgb * plcol.rgb * plcol.a;
 			
 			lit = da * dist_atten * noise;
 			
@@ -145,7 +149,7 @@ void main()
 		
 		amb_da = min(amb_da, 1.0-lit);
 		
-		col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
+		col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
 	}
 	
 	
@@ -174,7 +178,7 @@ void main()
 					stc.y > 0.0)
 				{
 					vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
-					col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb;
+					col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb;
 				}
 			}
 		}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightMSF.glsl
deleted file mode 100644
index 0c0171881fbb0736eeb414ac417cdbc4835481a3..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/spotLightMSF.glsl
+++ /dev/null
@@ -1,252 +0,0 @@
-/** 
- * @file multiSpotLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-
-
-//class 1 -- no shadows
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_texture_multisample : enable
-
-uniform sampler2DMS diffuseRect;
-uniform sampler2DMS specularRect;
-uniform sampler2DMS depthMap;
-uniform sampler2DMS normalMap;
-uniform sampler2D noiseMap;
-uniform sampler2D lightFunc;
-uniform sampler2D projectionMap;
-
-uniform mat4 proj_mat; //screen space to light space
-uniform float proj_near; //near clip for projection
-uniform vec3 proj_p; //plane projection is emitting from (in screen space)
-uniform vec3 proj_n;
-uniform float proj_focus; //distance from plane to begin blurring
-uniform float proj_lod;  //(number of mips in proj map)
-uniform float proj_range; //range between near clip and far clip plane of projection
-uniform float proj_ambient_lod;
-uniform float proj_ambiance;
-uniform float near_clip;
-uniform float far_clip;
-
-uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
-uniform float sun_wash;
-uniform int proj_shadow_idx;
-uniform float shadow_fade;
-
-varying vec4 vary_light;
-
-varying vec4 vary_fragcoord;
-uniform vec2 screen_res;
-
-uniform mat4 inv_proj;
-
-vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
-{
-	vec4 ret = texture2DLod(projectionMap, tc, lod);
-	
-	vec2 dist = tc-vec2(0.5);
-	
-	float det = max(1.0-lod/(proj_lod*0.5), 0.0);
-	
-	float d = dot(dist,dist);
-		
-	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0);
-	
-	return ret;
-}
-
-vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
-{
-	vec4 ret = texture2DLod(projectionMap, tc, lod);
-	
-	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-	
-	float det = min(lod/(proj_lod*0.5), 1.0);
-	
-	float d = min(dist.x, dist.y);
-	
-	float edge = 0.25*det;
-		
-	ret *= clamp(d/edge, 0.0, 1.0);
-	
-	return ret;
-}
-
-vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
-{
-	vec4 ret = texture2DLod(projectionMap, tc, lod);
-	
-	vec2 dist = tc-vec2(0.5);
-	
-	float d = dot(dist,dist);
-		
-	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
-	
-	return ret;
-}
-
-
-vec4 getPosition(ivec2 pos_screen, int sample)
-{
-	float depth = texelFetch(depthMap, pos_screen, sample).r;
-	vec2 sc = vec2(pos_screen.xy)*2.0;
-	sc /= screen_res;
-	sc -= vec2(1.0,1.0);
-	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
-	vec4 pos = inv_proj * ndc;
-	pos /= pos.w;
-	pos.w = 1.0;
-	return pos;
-}
-
-void main() 
-{
-	vec4 frag = vary_fragcoord;
-	frag.xyz /= frag.w;
-	frag.xyz = frag.xyz*0.5+0.5;
-	frag.xy *= screen_res;
-	ivec2 itc = ivec2(frag.xy);
-
-	vec3 fcol = vec3(0,0,0);
-	int wght = 0;
-	
-	for (int i = 0; i < samples; ++i)
-	{
-		vec3 pos = getPosition(itc, i).xyz;
-		vec3 lv = vary_light.xyz-pos.xyz;
-		float dist2 = dot(lv,lv);
-		dist2 /= vary_light.w;
-		if (dist2 <= 1.0)
-		{
-			vec3 norm = texelFetch(normalMap, itc, i).xyz*2.0-1.0;
-	
-			norm = normalize(norm);
-			float l_dist = -dot(lv, proj_n);
-	
-			vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
-			if (proj_tc.z >= 0.0)
-			{
-				proj_tc.xyz /= proj_tc.w;
-	
-				float fa = gl_Color.a+1.0;
-				float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
-				if (dist_atten > 0.0)
-				{
-					lv = proj_origin-pos.xyz;
-					lv = normalize(lv);
-					float da = dot(norm, lv);
-		
-					vec3 col = vec3(0,0,0);
-		
-					vec3 diff_tex = texelFetch(diffuseRect, itc, i).rgb;
-		
-					float noise = texture2D(noiseMap, frag.xy/128.0).b;
-					if (proj_tc.z > 0.0 &&
-						proj_tc.x < 1.0 &&
-						proj_tc.y < 1.0 &&
-						proj_tc.x > 0.0 &&
-						proj_tc.y > 0.0)
-					{
-						float lit = 0.0;
-						float amb_da = proj_ambiance;
-		
-						if (da > 0.0)
-						{
-							float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
-							float lod = diff * proj_lod;
-			
-							vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
-		
-							vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a;
-			
-							lit = da * dist_atten * noise;
-			
-							col = lcol*lit*diff_tex;
-							amb_da += (da*0.5)*proj_ambiance;
-						}
-		
-						//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
-						vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
-							
-						amb_da += (da*da*0.5+0.5)*proj_ambiance;
-				
-						amb_da *= dist_atten * noise;
-			
-						amb_da = min(amb_da, 1.0-lit);
-			
-						col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
-					}
-	
-	
-					vec4 spec = texelFetch(specularRect, itc, i);
-					if (spec.a > 0.0)
-					{
-						vec3 ref = reflect(normalize(pos), norm);
-		
-						//project from point pos in direction ref to plane proj_p, proj_n
-						vec3 pdelta = proj_p-pos;
-						float ds = dot(ref, proj_n);
-		
-						if (ds < 0.0)
-						{
-							vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
-			
-							vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
-
-							if (stc.z > 0.0)
-							{
-								stc.xy /= stc.w;
-
-								float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
-				
-								stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
-								
-								if (stc.x < 1.0 &&
-									stc.y < 1.0 &&
-									stc.x > 0.0 &&
-									stc.y > 0.0)
-								{
-									vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
-									col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb;
-								}
-							}
-						}
-					}
-	
-					fcol += col;
-					++wght;
-				}
-			}
-		}
-	}
-
-	if (wght <= 0)
-	{
-		discard;
-	}
-
-	gl_FragColor.rgb = fcol/samples;	
-	gl_FragColor.a = 0.0;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
index 4ab59d4d66ad035398d495859e131304ddd45adb..03fccd276614c2bd3393bc2f2d6d725a7335f079 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
@@ -22,14 +22,19 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragData[3];
+#endif
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 uniform sampler2D diffuseMap;
 
 void main() 
 {
-	vec4 col = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy);
+	vec4 col = vertex_color * texture2D(diffuseMap, vary_texcoord0.xy);
 	
 	gl_FragData[0] = col;
 	gl_FragData[1] = vec4(0,0,0,0);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl
index 84adf6bc41ade89e5445446f9f62b47fc597928e..8bc5b063799a77d7edc481fc0283c1577dc319c0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl
@@ -22,14 +22,21 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
 
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 void main()
 {
 	//transform vertex
-	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
-	gl_FrontColor = gl_Color;
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); 
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+	vertex_color = diffuse_color;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl
index 78ea15e87a9b38ae4b76ce00a52fb7541af45222..adc7c5d005881dc9589e0e6664e04e25260d73a4 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl
@@ -23,12 +23,14 @@
  * $/LicenseInfo$
  */
  
-
-
 //class 1, no shadow, no SSAO, should never be called
 
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 void main() 
 {
 	gl_FragColor = vec4(0,0,0,0);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
index 2f880d65dd97ead1a7d37b5985980959ff401bfc..fc5959a33c49545105a9b7857728303bda990758 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
@@ -23,9 +23,12 @@
  */
  
 
-
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 //class 1 -- no shadow, SSAO only
 
 uniform sampler2DRect depthMap;
@@ -41,8 +44,7 @@ uniform float ssao_max_radius;
 uniform float ssao_factor;
 uniform float ssao_factor_inv;
 
-varying vec2 vary_fragcoord;
-varying vec4 vary_light;
+VARYING vec2 vary_fragcoord;
 
 uniform mat4 inv_proj;
 uniform vec2 screen_res;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOMSF.glsl
deleted file mode 100644
index abb64334ed21dedcf3d2b9e18cfe87441c30b767..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOMSF.glsl
+++ /dev/null
@@ -1,140 +0,0 @@
-/** 
- * @file sunLightSSAOF.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_texture_multisample : enable
-
-//class 1 -- no shadow, SSAO only
-
-uniform sampler2DMS depthMap;
-uniform sampler2DMS normalMap;
-uniform sampler2D noiseMap;
-
-
-// Inputs
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-uniform float ssao_radius;
-uniform float ssao_max_radius;
-uniform float ssao_factor;
-uniform float ssao_factor_inv;
-
-varying vec2 vary_fragcoord;
-varying vec4 vary_light;
-
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-uniform float shadow_bias;
-uniform float shadow_offset;
-
-vec4 getPosition(ivec2 pos_screen, int sample)
-{
-	float depth = texelFetch(depthMap, pos_screen, sample).r;
-	vec2 sc = pos_screen.xy*2.0;
-	sc /= screen_res;
-	sc -= vec2(1.0,1.0);
-	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
-	vec4 pos = inv_proj * ndc;
-	pos /= pos.w;
-	pos.w = 1.0;
-	return pos;
-}
-
-//calculate decreases in ambient lighting when crowded out (SSAO)
-float calcAmbientOcclusion(vec4 pos, vec3 norm, int sample)
-{
-	float ret = 1.0;
-	
-	vec2 kern[8];
-	// exponentially (^2) distant occlusion samples spread around origin
-	kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
-	kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
-	kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
-	kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
-	kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
-	kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
-	kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
-	kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
-
-	vec2 pos_screen = vary_fragcoord.xy;
-	vec3 pos_world = pos.xyz;
-	vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy;
-		
-	float angle_hidden = 0.0;
-	int points = 0;
-		
-	float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
-		
-	// it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations unrolling?)
-	for (int i = 0; i < 8; i++)
-	{
-		ivec2 samppos_screen = ivec2(pos_screen + scale * reflect(kern[i], noise_reflect));
-		vec3 samppos_world = getPosition(samppos_screen, sample).xyz; 
-			
-		vec3 diff = pos_world - samppos_world;
-		float dist2 = dot(diff, diff);
-			
-		// assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
-		// --> solid angle shrinking by the square of distance
-		//radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
-		//(k should vary inversely with # of samples, but this is taken care of later)
-			
-		angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv);
-			
-		// 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion" 
-		points = points + int(diff.z > -1.0);
-	}
-		
-	angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0);
-		
-	ret = (1.0 - (float(points != 0) * angle_hidden));
-	
-	return min(ret, 1.0);
-}
-
-void main() 
-{
-	vec2 pos_screen = vary_fragcoord.xy;
-	ivec2 itc = ivec2(pos_screen);
-		
-	float col = 0;
-
-	for (int i = 0; i < samples; i++)
-	{
-		vec4 pos = getPosition(itc, i);
-		vec3 norm = texelFetch(normalMap, itc, i).xyz;
-		norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
-		col += calcAmbientOcclusion(pos,norm,i);
-	}
-
-	col /= samples;
-
-	gl_FragColor[0] = 1.0;
-	gl_FragColor[1] = col;
-	gl_FragColor[2] = 1.0; 
-	gl_FragColor[3] = 1.0;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl
index e7ab11c6ed2866e939c32c39def4d78d7a430dd6..473d6df8faa82fbfe02a63458993bec2cb6f2be3 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl
@@ -22,24 +22,20 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 modelview_projection_matrix;
+ 
+ATTRIBUTE vec3 position;
 
-varying vec4 vary_light;
-varying vec2 vary_fragcoord;
+VARYING vec2 vary_fragcoord;
 
 uniform vec2 screen_res;
 
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform(); 
-	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
-	vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res;	
-	vec4 tex = gl_MultiTexCoord0;
-	tex.w = 1.0;
+	vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	gl_Position = pos; 
 	
-	vary_light = gl_MultiTexCoord0;
-		
-	gl_FrontColor = gl_Color;
+	vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res;	
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
index c6578ea177c07636ec8d4b8ee523c938e7f9ef46..e014e53d25921ee201c581ef49be9bde90fc884e 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
@@ -23,7 +23,9 @@
  * $/LicenseInfo$
  */
  
-
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragData[3];
+#endif
 
 uniform sampler2D detail_0;
 uniform sampler2D detail_1;
@@ -31,20 +33,22 @@ uniform sampler2D detail_2;
 uniform sampler2D detail_3;
 uniform sampler2D alpha_ramp;
 
-varying vec3 vary_normal;
+VARYING vec3 vary_normal;
+VARYING vec4 vary_texcoord0;
+VARYING vec4 vary_texcoord1;
 
 void main()
 {
 	/// Note: This should duplicate the blending functionality currently used for the terrain rendering.
 	
-	vec4 color0 = texture2D(detail_0, gl_TexCoord[0].xy);
-	vec4 color1 = texture2D(detail_1, gl_TexCoord[0].xy);
-	vec4 color2 = texture2D(detail_2, gl_TexCoord[0].xy);
-	vec4 color3 = texture2D(detail_3, gl_TexCoord[0].xy);
+	vec4 color0 = texture2D(detail_0, vary_texcoord0.xy);
+	vec4 color1 = texture2D(detail_1, vary_texcoord0.xy);
+	vec4 color2 = texture2D(detail_2, vary_texcoord0.xy);
+	vec4 color3 = texture2D(detail_3, vary_texcoord0.xy);
 
-	float alpha1 = texture2D(alpha_ramp, gl_TexCoord[0].zw).a;
-	float alpha2 = texture2D(alpha_ramp,gl_TexCoord[1].xy).a;
-	float alphaFinal = texture2D(alpha_ramp, gl_TexCoord[1].zw).a;
+	float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a;
+	float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a;
+	float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a;
 	vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal );
 	
 	gl_FragData[0] = vec4(outColor.rgb, 0.0);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl
index fc19a7370919e5c6c3da58e1d6df89d30d490f13..5effee4e4eabd76c2940129ebf68afb46f0febda 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl
@@ -22,10 +22,24 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
 
-varying vec3 vary_normal;
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec2 texcoord1;
+
+VARYING vec3 vary_normal;
+
+VARYING vec4 vary_texcoord0;
+VARYING vec4 vary_texcoord1;
+
+uniform vec4 object_plane_s;
+uniform vec4 object_plane_t;
 
 vec4 texgen_object(vec4  vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1)
 {
@@ -44,16 +58,16 @@ vec4 texgen_object(vec4  vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1)
 void main()
 {
 	//transform vertex
-	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
 			
-	vary_normal = normalize(gl_NormalMatrix * gl_Normal);
+	vary_normal = normalize(normal_matrix * normal);
 	
 	// Transform and pass tex coords
- 	gl_TexCoord[0].xy = texgen_object(gl_Vertex, gl_MultiTexCoord0, gl_TextureMatrix[0], gl_ObjectPlaneS[0], gl_ObjectPlaneT[0]).xy;
+ 	vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy;
 	
-	vec4 t = gl_MultiTexCoord1;
+	vec4 t = vec4(texcoord1,0,1);
 	
-	gl_TexCoord[0].zw = t.xy;
-	gl_TexCoord[1].xy = t.xy-vec2(2.0, 0.0);
-	gl_TexCoord[1].zw = t.xy-vec2(1.0, 0.0);
+	vary_texcoord0.zw = t.xy;
+	vary_texcoord1.xy = t.xy-vec2(2.0, 0.0);
+	vary_texcoord1.zw = t.xy-vec2(1.0, 0.0);
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
index 56a149523e0c0470013300e2d26ae19564d4ef83..b934bc6991913b278ffb56f365789f5ea657c96f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
@@ -22,17 +22,29 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragData[3];
+#endif
 
 uniform sampler2D diffuseMap;
 
-varying vec3 vary_normal;
+VARYING vec4 vertex_color;
+VARYING vec3 vary_normal;
+VARYING vec2 vary_texcoord0;
+
+uniform float minimum_alpha;
+uniform float maximum_alpha;
 
 void main() 
 {
-	vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy);
-	gl_FragData[0] = vec4(gl_Color.rgb*col.rgb, col.a <= 0.5 ? 0.0 : 0.005);
+	vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
+	if (col.a < minimum_alpha || col.a > maximum_alpha)
+	{
+		discard;
+	}
+
+	gl_FragData[0] = vec4(vertex_color.rgb*col.rgb, 0.0);
 	gl_FragData[1] = vec4(0,0,0,0);
 	vec3 nvn = normalize(vary_normal);
 	gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..29ec6e6beef5c3dfeeb2f247b4cc71cc7d71c4ce
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl
@@ -0,0 +1,50 @@
+/** 
+ * @file treeShadowF.glsl
+ *
+ * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2005, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
+uniform float minimum_alpha;
+uniform float maximum_alpha;
+
+uniform sampler2D diffuseMap;
+
+VARYING vec4 post_pos;
+VARYING vec2 vary_texcoord0;
+
+void main() 
+{
+	float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a;
+
+	if (alpha < minimum_alpha || alpha > maximum_alpha)
+	{
+		discard;
+	}
+
+	gl_FragColor = vec4(1,1,1,1);
+	
+	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeShadowV.glsl
similarity index 67%
rename from indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl
rename to indra/newview/app_settings/shaders/class1/deferred/treeShadowV.glsl
index fed238510a0281a7f4b81520f4c81b9a3972fe89..e472a753045eae3586551c8f8c41990567bd369d 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeShadowV.glsl
@@ -1,7 +1,7 @@
 /** 
- * @file softenLightF.glsl
+ * @file treeShadowV.glsl
  *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2007, Linden Research, Inc.
  * 
@@ -22,23 +22,24 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
+ 
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
 
-uniform vec2 screen_res;
+VARYING vec4 post_pos;
+VARYING vec2 vary_texcoord0;
 
-varying vec4 vary_light;
-varying vec2 vary_fragcoord;
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform(); 
+	vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
+	
+	post_pos = pos;
 	
-	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
-	vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
-		
-	vec4 tex = gl_MultiTexCoord0;
-	tex.w = 1.0;
+	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
 	
-	vary_light = gl_MultiTexCoord0;
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl
index 01401028d643b199462be0422b1e088fe001ed56..3b6571a24a9ded2af5eee0fc1598e54b3a4b8122 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl
@@ -22,18 +22,26 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
+uniform mat3 normal_matrix;
 
-varying vec3 vary_normal;
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec3 vary_normal;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform(); 
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); 
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 	
-	vary_normal = normalize(gl_NormalMatrix * gl_Normal);
+	vary_normal = normalize(normal_matrix * normal);
 
-	gl_FrontColor = gl_Color;
+	vertex_color = vec4(1,1,1,1);
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
index c3e7371c8e4b4407ea8e53b6bb4876be390a6a4a..4c9ea24a249c076f1f62404fd68c4ed14229182e 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
@@ -23,10 +23,12 @@
  * $/LicenseInfo$
  */
  
-
-
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragData[3];
+#endif
+
 vec3 scaleSoftClip(vec3 inColor);
 vec3 atmosTransport(vec3 inColor);
 
@@ -58,10 +60,10 @@ uniform vec2 screen_res;
 uniform mat4 norm_mat; //region space to screen space
 
 //bigWave is (refCoord.w, view.w);
-varying vec4 refCoord;
-varying vec4 littleWave;
-varying vec4 view;
-varying vec4 vary_position;
+VARYING vec4 refCoord;
+VARYING vec4 littleWave;
+VARYING vec4 view;
+VARYING vec4 vary_position;
 
 void main() 
 {
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
index 9d415ade85cf80b45048eca7b9d6ecb3b82499de..9734acf005a372378eff057667cb4bfea6033210 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
@@ -22,7 +22,11 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
 
 
 void calcAtmospherics(vec3 inPositionEye);
@@ -33,11 +37,11 @@ uniform float time;
 uniform vec3 eyeVec;
 uniform float waterHeight;
 
-varying vec4 refCoord;
-varying vec4 littleWave;
-varying vec4 view;
+VARYING vec4 refCoord;
+VARYING vec4 littleWave;
+VARYING vec4 view;
 
-varying vec4 vary_position;
+VARYING vec4 vary_position;
 
 float wave(vec2 v, float t, float f, vec2 d, float s) 
 {
@@ -47,43 +51,42 @@ float wave(vec2 v, float t, float f, vec2 d, float s)
 void main()
 {
 	//transform vertex
-	vec4 position = gl_Vertex;
-	mat4 modelViewProj = gl_ModelViewProjectionMatrix;
+	vec4 pos = vec4(position.xyz, 1.0);
+	mat4 modelViewProj = modelview_projection_matrix;
 	
 	vec4 oPosition;
 		    
 	//get view vector
 	vec3 oEyeVec;
-	oEyeVec.xyz = position.xyz-eyeVec;
+	oEyeVec.xyz = pos.xyz-eyeVec;
 		
 	float d = length(oEyeVec.xy);
 	float ld = min(d, 2560.0);
 	
-	position.xy = eyeVec.xy + oEyeVec.xy/d*ld;
+	pos.xy = eyeVec.xy + oEyeVec.xy/d*ld;
 	view.xyz = oEyeVec;
 		
 	d = clamp(ld/1536.0-0.5, 0.0, 1.0);	
 	d *= d;
 		
-	oPosition = position;
+	oPosition = vec4(position, 1.0);
 	oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d);
-	vary_position = gl_ModelViewMatrix * oPosition;
+	vary_position = modelview_matrix * oPosition;
 	oPosition = modelViewProj * oPosition;
 	
 	refCoord.xyz = oPosition.xyz + vec3(0,0,0.2);
 	
 	//get wave position parameter (create sweeping horizontal waves)
-	vec3 v = position.xyz;
+	vec3 v = pos.xyz;
 	v.x += (cos(v.x*0.08/*+time*0.01*/)+sin(v.y*0.02))*6.0;
 	    
 	//push position for further horizon effect.
-	position.xyz = oEyeVec.xyz*(waterHeight/oEyeVec.z);
-	position.w = 1.0;
-	position = position*gl_ModelViewMatrix;
-	
-	calcAtmospherics((gl_ModelViewMatrix * gl_Vertex).xyz);
-	
+	pos.xyz = oEyeVec.xyz*(waterHeight/oEyeVec.z);
+	pos.w = 1.0;
+	pos = modelview_matrix*pos;
 	
+	calcAtmospherics(pos.xyz);
+		
 	//pass wave parameters to pixel shader
 	vec2 bigWave =  (v.xy) * vec2(0.04,0.04)  + d1 * time * 0.055;
 	//get two normal map (detail map) texture coordinates
diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl
index e827863436dd96e6733801b700d6f740e003d4ba..9a3d7922244c322ab315cb9d481e6af7b1a83104 100644
--- a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl
+++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl
@@ -23,10 +23,12 @@
  * $/LicenseInfo$
  */
  
-
-
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform sampler2DRect diffuseMap;
 uniform float minLuminance;
 uniform float maxExtractAlpha;
@@ -34,10 +36,11 @@ uniform vec3 lumWeights;
 uniform vec3 warmthWeights;
 uniform float warmthAmount;
 
+VARYING vec2 vary_texcoord0;
+
 void main()
 {
-	vec4 col = texture2DRect(diffuseMap, gl_TexCoord[0].xy);	
-
+	vec4 col = texture2DRect(diffuseMap, vary_texcoord0.xy);	
 	/// CALCULATING LUMINANCE (Using NTSC lum weights)
 	/// http://en.wikipedia.org/wiki/Luma_%28video%29
 	float lum = smoothstep(minLuminance, minLuminance+1.0, dot(col.rgb, lumWeights ) );
@@ -45,4 +48,5 @@ void main()
 	
 	gl_FragColor.rgb = col.rgb; 
 	gl_FragColor.a = max(col.a, mix(lum, warmth, warmthAmount) * maxExtractAlpha);
+	
 }
diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl
index 8db6d1bf24b490f88404d431491f040036bf74cc..1396dc6973539d03888ebd4c2c9862c16ac5b6f6 100644
--- a/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl
+++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl
@@ -23,11 +23,16 @@
  * $/LicenseInfo$
  */
 
+uniform mat4 modelview_projection_matrix;
 
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec2 vary_texcoord0;
 
 void main() 
 {
-	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+	gl_Position = modelview_projection_matrix * vec4(position, 1.0);
 	
-	gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;
+	vary_texcoord0.xy = texcoord0;
 }
diff --git a/indra/newview/app_settings/shaders/class1/effects/glowF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowF.glsl
index 75cff75ea9e9f4367c9afc2388fe2acb4ab333e7..90bb84323ccfd916072a082c7502f0a216e9a16b 100644
--- a/indra/newview/app_settings/shaders/class1/effects/glowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/effects/glowF.glsl
@@ -23,11 +23,18 @@
  * $/LicenseInfo$
  */
  
-
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
 uniform sampler2D diffuseMap;
 uniform float glowStrength;
 
+VARYING vec4 vary_texcoord0;
+VARYING vec4 vary_texcoord1;
+VARYING vec4 vary_texcoord2;
+VARYING vec4 vary_texcoord3;
+
 void main()
 {
 
@@ -38,14 +45,14 @@ void main()
 		kern[0] = 0.25; kern[1] = 0.5; kern[2] = 0.8; kern[3] = 1.0;
 		kern[4] = 1.0;  kern[5] = 0.8; kern[6] = 0.5; kern[7] = 0.25;
 	
-	col += kern[0] * texture2D(diffuseMap, gl_TexCoord[0].xy);	
-	col += kern[1] * texture2D(diffuseMap, gl_TexCoord[1].xy);
-	col += kern[2] * texture2D(diffuseMap, gl_TexCoord[2].xy);	
-	col += kern[3] * texture2D(diffuseMap, gl_TexCoord[3].xy);	
-	col += kern[4] * texture2D(diffuseMap, gl_TexCoord[0].zw);	
-	col += kern[5] * texture2D(diffuseMap, gl_TexCoord[1].zw);	
-	col += kern[6] * texture2D(diffuseMap, gl_TexCoord[2].zw);	
-	col += kern[7] * texture2D(diffuseMap, gl_TexCoord[3].zw);	
+	col += kern[0] * texture2D(diffuseMap, vary_texcoord0.xy);	
+	col += kern[1] * texture2D(diffuseMap, vary_texcoord1.xy);
+	col += kern[2] * texture2D(diffuseMap, vary_texcoord2.xy);	
+	col += kern[3] * texture2D(diffuseMap, vary_texcoord3.xy);	
+	col += kern[4] * texture2D(diffuseMap, vary_texcoord0.zw);	
+	col += kern[5] * texture2D(diffuseMap, vary_texcoord1.zw);	
+	col += kern[6] * texture2D(diffuseMap, vary_texcoord2.zw);	
+	col += kern[7] * texture2D(diffuseMap, vary_texcoord3.zw);	
 	
 	gl_FragColor = vec4(col.rgb * glowStrength, col.a);
 }
diff --git a/indra/newview/app_settings/shaders/class1/effects/glowV.glsl b/indra/newview/app_settings/shaders/class1/effects/glowV.glsl
index a5aacc019659c94a0dc055644970658683fd1ba0..cdb2281578ec8316010b340e7371a36068a0dc80 100644
--- a/indra/newview/app_settings/shaders/class1/effects/glowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/effects/glowV.glsl
@@ -23,20 +23,28 @@
  * $/LicenseInfo$
  */
  
+uniform mat4 modelview_projection_matrix;
 
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
 
 uniform vec2 glowDelta;
 
+VARYING vec4 vary_texcoord0;
+VARYING vec4 vary_texcoord1;
+VARYING vec4 vary_texcoord2;
+VARYING vec4 vary_texcoord3;
+
 void main() 
 {
-	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+	gl_Position = modelview_projection_matrix * vec4(position, 1.0);
 	
-	gl_TexCoord[0].xy = gl_MultiTexCoord0.xy + glowDelta*(-3.5);
-	gl_TexCoord[1].xy = gl_MultiTexCoord0.xy + glowDelta*(-2.5);
-	gl_TexCoord[2].xy = gl_MultiTexCoord0.xy + glowDelta*(-1.5);
-	gl_TexCoord[3].xy = gl_MultiTexCoord0.xy + glowDelta*(-0.5);
-	gl_TexCoord[0].zw = gl_MultiTexCoord0.xy + glowDelta*(0.5);
-	gl_TexCoord[1].zw = gl_MultiTexCoord0.xy + glowDelta*(1.5);
-	gl_TexCoord[2].zw = gl_MultiTexCoord0.xy + glowDelta*(2.5);
-	gl_TexCoord[3].zw = gl_MultiTexCoord0.xy + glowDelta*(3.5);
+	vary_texcoord0.xy = texcoord0 + glowDelta*(-3.5);
+	vary_texcoord1.xy = texcoord0 + glowDelta*(-2.5);
+	vary_texcoord2.xy = texcoord0 + glowDelta*(-1.5);
+	vary_texcoord3.xy = texcoord0 + glowDelta*(-0.5);
+	vary_texcoord0.zw = texcoord0 + glowDelta*(0.5);
+	vary_texcoord1.zw = texcoord0 + glowDelta*(1.5);
+	vary_texcoord2.zw = texcoord0 + glowDelta*(2.5);
+	vary_texcoord3.zw = texcoord0 + glowDelta*(3.5);
 }
diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl
index c61d5a2a086c79e358bef42fd001aa6a03410d6b..18f6d91804da058317070dd5ab52208de2c56ce4 100644
--- a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl
@@ -1,4 +1,4 @@
-/** 
+/**
  * @file terrainF.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
@@ -23,19 +23,42 @@
  * $/LicenseInfo$
  */
  
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
+VARYING vec4 vertex_color;
+VARYING vec4 vary_texcoord0;
+VARYING vec4 vary_texcoord1;
 
-uniform sampler2D detail0;
-uniform sampler2D detail1;
-uniform sampler2D alphaRamp;
+uniform sampler2D detail_0;
+uniform sampler2D detail_1;
+uniform sampler2D detail_2;
+uniform sampler2D detail_3;
+uniform sampler2D alpha_ramp;
 
-void main() 
+vec3 atmosLighting(vec3 light);
+
+vec3 scaleSoftClip(vec3 color);
+
+void main()
 {
-	float a = texture2D(alphaRamp, gl_TexCoord[1].xy).a;
-	vec3 color = mix(texture2D(detail1, gl_TexCoord[2].xy).rgb,
-					 texture2D(detail0, gl_TexCoord[0].xy).rgb,
-					 a);
+	/// Note: This should duplicate the blending functionality currently used for the terrain rendering.
+	
+	/// TODO Confirm tex coords and bind them appropriately in vert shader.
+	vec4 color0 = texture2D(detail_0, vary_texcoord0.xy);
+	vec4 color1 = texture2D(detail_1, vary_texcoord0.xy);
+	vec4 color2 = texture2D(detail_2, vary_texcoord0.xy);
+	vec4 color3 = texture2D(detail_3, vary_texcoord0.xy);
 
-	gl_FragColor.rgb = color;
-	gl_FragColor.a = texture2D(alphaRamp, gl_TexCoord[3].xy).a;
+	float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a;
+	float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a;
+	float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a;
+	vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal );
+	
+	/// Add WL Components
+	outColor.rgb = atmosLighting(outColor.rgb * vertex_color.rgb);
+	
+	gl_FragColor = vec4(scaleSoftClip(outColor.rgb), 1.0);
 }
+
diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl
index 917891c063481d1faa584299b04130a2ec3a1dda..f183b885d19f09eab33211d58e211d20471f33ea 100644
--- a/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl
@@ -1,4 +1,4 @@
-/** 
+/**
  * @file terrainV.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
@@ -22,8 +22,26 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+uniform vec4 object_plane_t;
+uniform vec4 object_plane_s;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec2 texcoord1;
+
+VARYING vec4 vertex_color;
+VARYING vec4 vary_texcoord0;
+VARYING vec4 vary_texcoord1;
+
+void calcAtmospherics(vec3 inPositionEye);
 
 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
 
@@ -44,17 +62,27 @@ vec4 texgen_object(vec4  vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1)
 void main()
 {
 	//transform vertex
-	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
-			
-	vec4 pos = gl_ModelViewMatrix * gl_Vertex;
-	vec3 norm = normalize(gl_NormalMatrix * gl_Normal);
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+
+	vec4 pos = modelview_matrix * vec4(position.xyz, 1.0);
+	vec3 norm = normalize(normal_matrix * normal);
+
+	calcAtmospherics(pos.xyz);
+
+	/// Potentially better without it for water.
+	pos /= pos.w;
+
+	vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0));
 	
-	vec4 color = calcLighting(pos.xyz, norm, vec4(1,1,1,1), gl_Color);
+	vertex_color = color;
+
+	// Transform and pass tex coords
+ 	vary_texcoord0.xy = texgen_object(vec4(position.xyz, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy;
 	
-	gl_FrontColor = color;
+	vec4 t = vec4(texcoord1,0,1);
 	
-	gl_TexCoord[0] = texgen_object(gl_Vertex,gl_MultiTexCoord0,gl_TextureMatrix[0],gl_ObjectPlaneS[0],gl_ObjectPlaneT[0]);
-	gl_TexCoord[1] = gl_TextureMatrix[1]*gl_MultiTexCoord1;
-	gl_TexCoord[2] = texgen_object(gl_Vertex,gl_MultiTexCoord2,gl_TextureMatrix[2],gl_ObjectPlaneS[2],gl_ObjectPlaneT[2]);
-	gl_TexCoord[3] = gl_TextureMatrix[3]*gl_MultiTexCoord3;
+	vary_texcoord0.zw = t.xy;
+	vary_texcoord1.xy = t.xy-vec2(2.0, 0.0);
+	vary_texcoord1.zw = t.xy-vec2(1.0, 0.0);
 }
+
diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl
index 711b42b95ed517f6afe7bae767e613608e372e45..e5c7ced52c0d08fa5fd3d71b378f50de73f6eb3d 100644
--- a/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl
@@ -1,4 +1,4 @@
-/** 
+/**
  * @file terrainWaterF.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
@@ -22,22 +22,44 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
-// this class1 shader is just a copy of terrainF
+VARYING vec4 vertex_color;
+VARYING vec4 vary_texcoord0;
+VARYING vec4 vary_texcoord1;
 
-uniform sampler2D detail0;
-uniform sampler2D detail1;
-uniform sampler2D alphaRamp;
+uniform sampler2D detail_0;
+uniform sampler2D detail_1;
+uniform sampler2D detail_2;
+uniform sampler2D detail_3;
+uniform sampler2D alpha_ramp;
 
-void main() 
+vec3 atmosLighting(vec3 light);
+
+vec4 applyWaterFog(vec4 color);
+
+void main()
 {
-	float a = texture2D(alphaRamp, gl_TexCoord[1].xy).a;
-	vec3 color = mix(texture2D(detail1, gl_TexCoord[2].xy).rgb,
-					 texture2D(detail0, gl_TexCoord[0].xy).rgb,
-					 a);
+	/// Note: This should duplicate the blending functionality currently used for the terrain rendering.
+	
+	/// TODO Confirm tex coords and bind them appropriately in vert shader.
+	vec4 color0 = texture2D(detail_0, vary_texcoord0.xy);
+	vec4 color1 = texture2D(detail_1, vary_texcoord0.xy);
+	vec4 color2 = texture2D(detail_2, vary_texcoord0.xy);
+	vec4 color3 = texture2D(detail_3, vary_texcoord0.xy);
 
-	gl_FragColor.rgb = color;
-	gl_FragColor.a = texture2D(alphaRamp, gl_TexCoord[3].xy).a;
+	float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a;
+	float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a;
+	float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a;
+	vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal );
+	
+	/// Add WL Components
+	outColor.rgb = atmosLighting(outColor.rgb * vertex_color.rgb);
+	
+	outColor = applyWaterFog(outColor);
+	gl_FragColor = outColor;
 }
+
diff --git a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
index 72e8e739b3905aafa4f84a710f527e5ba434882c..1fdb90f7926c0e97788a3eeaa4b6ffe5bd847ac8 100644
--- a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
@@ -23,36 +23,82 @@
  * $/LicenseInfo$
  */
  
-
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
 uniform sampler2D diffuseMap;
 uniform sampler2D bumpMap;   
 uniform sampler2D screenTex;
+uniform sampler2D refTex;
+uniform sampler2D screenDepth;
 
+uniform vec4 fogCol;
+uniform vec3 lightDir;
+uniform vec3 specular;
+uniform float lightExp;
+uniform vec2 fbScale;
 uniform float refScale;
+uniform float znear;
+uniform float zfar;
+uniform float kd;
+uniform vec4 waterPlane;
+uniform vec3 eyeVec;
 uniform vec4 waterFogColor;
+uniform float waterFogDensity;
+uniform float waterFogKS;
+uniform vec2 screenRes;
 
 //bigWave is (refCoord.w, view.w);
-varying vec4 refCoord;
-varying vec4 littleWave;
-varying vec4 view;
+VARYING vec4 refCoord;
+VARYING vec4 littleWave;
+VARYING vec4 view;
 
-void main() 
+vec4 applyWaterFog(vec4 color, vec3 viewVec)
 {
-	vec4 color;    
+	//normalize view vector
+	vec3 view = normalize(viewVec);
+	float es = -view.z;
+
+	//find intersection point with water plane and eye vector
 	
-	//get bigwave normal
-	vec3 wavef = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0;
-    
-	//get detail normals
-	vec3 dcol = texture2D(bumpMap, littleWave.xy).rgb*0.75;
-	dcol += texture2D(bumpMap, littleWave.zw).rgb*1.25;
-	    
-	//interpolate between big waves and little waves (big waves in deep water)
-	wavef = (wavef+dcol)*0.5;
+	//get eye depth
+	float e0 = max(-waterPlane.w, 0.0);
+	
+	//get object depth
+	float depth = length(viewVec);
+		
+	//get "thickness" of water
+	float l = max(depth, 0.1);
 
-	//crunch normal to range [-1,1]
-	wavef -= vec3(1,1,1);
+	float kd = waterFogDensity;
+	float ks = waterFogKS;
+	vec4 kc = waterFogColor;
+	
+	float F = 0.98;
+	
+	float t1 = -kd * pow(F, ks * e0);
+	float t2 = kd + ks * es;
+	float t3 = pow(F, t2*l) - 1.0;
+	
+	float L = min(t1/t2*t3, 1.0);
+	
+	float D = pow(0.98, l*kd);
+	//return vec4(1.0, 0.0, 1.0, 1.0);
+	return color * D + kc * L;
+	//depth /= 10.0;
+	//return vec4(depth,depth,depth,0.0);
+}
+
+void main() 
+{
+	vec4 color;
+	    
+	//get detail normals
+	vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
+	vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
+	vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;    
+	vec3 wavef = normalize(wave1+wave2+wave3);
 	
 	//figure out distortion vector (ripply)   
 	vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
@@ -60,6 +106,5 @@ void main()
 		
 	vec4 fb = texture2D(screenTex, distort);
 	
-	gl_FragColor.rgb = mix(waterFogColor.rgb, fb.rgb, waterFogColor.a * 0.001 + 0.999);
-	gl_FragColor.a = fb.a;
+	gl_FragColor = applyWaterFog(fb,view.xyz);
 }
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
index 4d555b566abcc9d33538b02590e266ebe389cfa8..444c896d38888fa00f6e986ac91af09ad3f7485b 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
@@ -23,20 +23,19 @@
  * $/LicenseInfo$
  */
  
-
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
 vec3 scaleSoftClip(vec3 inColor);
 vec3 atmosTransport(vec3 inColor);
-vec3 applyWaterFog(vec4 inColor);
 
-uniform sampler2D diffuseMap;
 uniform sampler2D bumpMap;   
 uniform sampler2D screenTex;
 uniform sampler2D refTex;
 
 uniform float sunAngle;
 uniform float sunAngle2;
-uniform float scaledAngle;
 uniform vec3 lightDir;
 uniform vec3 specular;
 uniform float lightExp;
@@ -47,67 +46,92 @@ uniform vec3 normScale;
 uniform float fresnelScale;
 uniform float fresnelOffset;
 uniform float blurMultiplier;
-uniform vec4 fogCol;
+
 
 //bigWave is (refCoord.w, view.w);
-varying vec4 refCoord;
-varying vec4 littleWave;
-varying vec4 view;
+VARYING vec4 refCoord;
+VARYING vec4 littleWave;
+VARYING vec4 view;
 
 void main() 
 {
-	vec3 viewVec = view.xyz;
 	vec4 color;
 	
-	float dist = length(viewVec.xy);
+	float dist = length(view.xy);
 	
 	//normalize view vector
-	viewVec = normalize(viewVec);
+	vec3 viewVec = normalize(view.xyz);
 	
 	//get wave normals
-	vec3 wavef = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0;
-
-	//get detail normals
-	vec3 dcol = texture2D(bumpMap, littleWave.xy).rgb*0.75;
-	dcol += texture2D(bumpMap, littleWave.zw).rgb*1.25;
-
-	//interpolate between big waves and little waves (big waves in deep water)
-	wavef = (wavef + dcol) * 0.5;
-	
-	//crunch normal to range [-1,1]
-	wavef -= vec3(1,1,1);
-	wavef = normalize(wavef);
-   
+	vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
+	vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
+	vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
 	//get base fresnel components	
 	
-	float df = dot(viewVec,wavef) * fresnelScale + fresnelOffset;
+	vec3 df = vec3(
+					dot(viewVec, wave1),
+					dot(viewVec, (wave2 + wave3) * 0.5),
+					dot(viewVec, wave3)
+				 ) * fresnelScale + fresnelOffset;
+	df *= df;
 		    
 	vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
 	
 	float dist2 = dist;
 	dist = max(dist, 5.0);
 	
+	float dmod = sqrt(dist);
+	
+	vec2 dmod_scale = vec2(dmod*dmod, dmod);
+	
 	//get reflected color
-	vec2 refdistort = wavef.xy*dot(normScale, vec3(0.333));
-	vec2 refvec = distort+refdistort/dist;
-	vec4 refcol = texture2D(refTex, refvec);
+	vec2 refdistort1 = wave1.xy*normScale.x;
+	vec2 refvec1 = distort+refdistort1/dmod_scale;
+	vec4 refcol1 = texture2D(refTex, refvec1);
+	
+	vec2 refdistort2 = wave2.xy*normScale.y;
+	vec2 refvec2 = distort+refdistort2/dmod_scale;
+	vec4 refcol2 = texture2D(refTex, refvec2);
+	
+	vec2 refdistort3 = wave3.xy*normScale.z;
+	vec2 refvec3 = distort+refdistort3/dmod_scale;
+	vec4 refcol3 = texture2D(refTex, refvec3);
+
+	vec4 refcol = refcol1 + refcol2 + refcol3;
+	float df1 = df.x + df.y + df.z;
+	refcol *= df1 * 0.333;
+	
+	vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
+	
+	wavef.z *= max(-viewVec.z, 0.1);
+	wavef = normalize(wavef);
+	
+	float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
+	
+	vec2 refdistort4 = wavef.xy*0.125;
+	refdistort4.y -= abs(refdistort4.y);
+	vec2 refvec4 = distort+refdistort4/dmod;
+	float dweight = min(dist2*blurMultiplier, 1.0);
+	vec4 baseCol = texture2D(refTex, refvec4);
+	refcol = mix(baseCol*df2, refcol, dweight);
 
 	//get specular component
 	float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
-	
+		
 	//harden specular
-	spec = pow(spec, lightExp);
+	spec = pow(spec, 128.0);
 
 	//figure out distortion vector (ripply)   
-	vec2 distort2 = distort+wavef.xy*refScale/max(dist*df, 1.0);
+	vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
 		
 	vec4 fb = texture2D(screenTex, distort2);
 	
 	//mix with reflection
-	color.rgb = mix(mix(fogCol.rgb, fb.rgb, fogCol.a), refcol.rgb, df);
+	// Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug
+	color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
 	color.rgb += spec * specular;
 	
-	//color.rgb = applyWaterFog(color);//atmosTransport(color.rgb);
+	color.rgb = atmosTransport(color.rgb);
 	color.rgb = scaleSoftClip(color.rgb);
 	color.a = spec * sunAngle2;
 
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
index d44690d1fb482e89943e127610b49139d1d0cd15..4bdfce9260c77145dcb244b561d87ce1a4230ea7 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
@@ -25,16 +25,50 @@
  
 
 
+uniform vec4 lightnorm;
+uniform vec4 waterPlane;
+uniform vec4 waterFogColor;
+uniform float waterFogDensity;
+uniform float waterFogKS;
+
+vec3 getPositionEye();
+
 vec4 applyWaterFog(vec4 color)
 {
-	// GL_EXP2 Fog
-	//float fog = exp(-gl_Fog.density * gl_Fog.density * gl_FogFragCoord * gl_FogFragCoord);
-	// GL_EXP Fog
-	// float fog = exp(-gl_Fog.density * gl_FogFragCoord);
-	// GL_LINEAR Fog
-	float fog = (gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale;
-	fog = clamp(fog, 0.0, 1.0);
-	color.rgb = mix(gl_Fog.color.rgb, color.rgb, fog);
+	//normalize view vector
+	vec3 view = normalize(getPositionEye());
+	float es = -(dot(view, waterPlane.xyz));
+
+	//find intersection point with water plane and eye vector
+	
+	//get eye depth
+	float e0 = max(-waterPlane.w, 0.0);
+	
+	vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
+	
+	//get object depth
+	float depth = length(getPositionEye() - int_v);
+		
+	//get "thickness" of water
+	float l = max(depth, 0.1);
+
+	float kd = waterFogDensity;
+	float ks = waterFogKS;
+	vec4 kc = waterFogColor;
+	
+	float F = 0.98;
+	
+	float t1 = -kd * pow(F, ks * e0);
+	float t2 = kd + ks * es;
+	float t3 = pow(F, t2*l) - 1.0;
+	
+	float L = min(t1/t2*t3, 1.0);
+	
+	float D = pow(0.98, l*kd);
+	
+	color.rgb = color.rgb * D + kc.rgb * L;
+	color.a = kc.a + color.a;
+	
 	return color;
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
index 610c06fbbc341c3f69c25876b9dd715a3ca0e0f4..f66ba1d2d9403f0a3f102773b17c363e7ed64e4f 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
@@ -22,8 +22,11 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
 
 void calcAtmospherics(vec3 inPositionEye);
 
@@ -33,9 +36,9 @@ uniform float time;
 uniform vec3 eyeVec;
 uniform float waterHeight;
 
-varying vec4 refCoord;
-varying vec4 littleWave;
-varying vec4 view;
+VARYING vec4 refCoord;
+VARYING vec4 littleWave;
+VARYING vec4 view;
 
 float wave(vec2 v, float t, float f, vec2 d, float s) 
 {
@@ -45,8 +48,7 @@ float wave(vec2 v, float t, float f, vec2 d, float s)
 void main()
 {
 	//transform vertex
-	vec4 position = gl_Vertex;
-	mat4 modelViewProj = gl_ModelViewProjectionMatrix;
+	mat4 modelViewProj = modelview_projection_matrix;
 	
 	vec4 oPosition;
 		    
@@ -57,27 +59,29 @@ void main()
 	float d = length(oEyeVec.xy);
 	float ld = min(d, 2560.0);
 	
-	position.xy = eyeVec.xy + oEyeVec.xy/d*ld;
+	vec3 lpos = position;
+	lpos.xy = eyeVec.xy + oEyeVec.xy/d*ld;
 	view.xyz = oEyeVec;
 		
 	d = clamp(ld/1536.0-0.5, 0.0, 1.0);	
 	d *= d;
 		
-	oPosition = position;
+	oPosition = vec4(lpos, 1.0);
 	oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d);
 	oPosition = modelViewProj * oPosition;
 	refCoord.xyz = oPosition.xyz + vec3(0,0,0.2);
 	
 	//get wave position parameter (create sweeping horizontal waves)
-	vec3 v = position.xyz;
+	vec3 v = lpos;
 	v.x += (cos(v.x*0.08/*+time*0.01*/)+sin(v.y*0.02))*6.0;
 	    
 	//push position for further horizon effect.
-	position.xyz = oEyeVec.xyz*(waterHeight/oEyeVec.z);
-	position.w = 1.0;
-	position = position*gl_ModelViewMatrix;
+	vec4 pos;
+	pos.xyz = oEyeVec.xyz*(waterHeight/oEyeVec.z);
+	pos.w = 1.0;
+	pos = modelview_matrix*pos;
 	
-	calcAtmospherics((gl_ModelViewMatrix * gl_Vertex).xyz);
+	calcAtmospherics(pos.xyz);
 	
 	
 	//pass wave parameters to pixel shader
diff --git a/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/interface/alphamaskF.glsl
similarity index 73%
rename from indra/newview/app_settings/shaders/class3/deferred/treeF.glsl
rename to indra/newview/app_settings/shaders/class1/interface/alphamaskF.glsl
index 56a149523e0c0470013300e2d26ae19564d4ef83..4f2767fc970f6695e6ec0da6a618c7a7fcdefc45 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/alphamaskF.glsl
@@ -1,5 +1,5 @@
 /** 
- * @file treeF.glsl
+ * @file alphamaskF.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -22,18 +22,26 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
 uniform sampler2D diffuseMap;
 
-varying vec3 vary_normal;
+uniform float minimum_alpha;
+uniform float maximum_alpha;
+
+VARYING vec2 vary_texcoord0;
+VARYING vec4 vertex_color;
 
 void main() 
 {
-	vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy);
-	gl_FragData[0] = vec4(gl_Color.rgb*col.rgb, col.a <= 0.5 ? 0.0 : 0.005);
-	gl_FragData[1] = vec4(0,0,0,0);
-	vec3 nvn = normalize(vary_normal);
-	gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
+	vec4 col = vertex_color*texture2D(diffuseMap, vary_texcoord0.xy);
+	if (col.a < minimum_alpha || col.a > maximum_alpha)
+	{
+		discard;
+	}
+
+	gl_FragColor = col;
 }
diff --git a/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl b/indra/newview/app_settings/shaders/class1/interface/alphamaskV.glsl
similarity index 71%
rename from indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl
rename to indra/newview/app_settings/shaders/class1/interface/alphamaskV.glsl
index 2d99ef5481777c7ba2019d3a783f5d2b0b19de0e..3580d1f27b2c247e35ac0704fbb06196fa6a44e5 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/alphamaskV.glsl
@@ -1,5 +1,5 @@
 /** 
- * @file giV.glsl
+ * @file alphamaskV.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -22,19 +22,21 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
 
-varying vec2 vary_fragcoord;
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
 
-uniform vec2 screen_res;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 void main()
 {
-	//transform vertex
-	gl_Position = ftransform(); 
-	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
-	vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res;	
-
-	gl_FrontColor = gl_Color;
+	gl_Position = modelview_projection_matrix * vec4(position, 1);
+	vary_texcoord0 =  (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+	vertex_color = diffuse_color;
 }
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl b/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl
index 27c63fdc8b9c8dea2e496b1b537a9dc73bf25457..4b481ba834a6559bec12cdd464e87d7682752305 100644
--- a/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl
@@ -22,14 +22,21 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform sampler2D diffuseMap;
 
 uniform float custom_alpha;
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
 void main() 
 {
-	vec4 color = gl_Color*texture2D(diffuseMap, gl_TexCoord[0].xy);
+	vec4 color = vertex_color*texture2D(diffuseMap, vary_texcoord0.xy);
 	color.a *= custom_alpha;
 	gl_FragColor = color;
 }
diff --git a/indra/newview/app_settings/shaders/class1/interface/customalphaV.glsl b/indra/newview/app_settings/shaders/class1/interface/customalphaV.glsl
index c4c896c35c4d75ec39c90d0ebfc973508329000e..890474d6d8c1c8af946c15afab2d8b0030240a37 100644
--- a/indra/newview/app_settings/shaders/class1/interface/customalphaV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/customalphaV.glsl
@@ -22,13 +22,20 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 void main()
 {
-	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
-	gl_TexCoord[0] = gl_MultiTexCoord0;
-	gl_FrontColor = gl_Color;
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	vary_texcoord0 = texcoord0;
+	vertex_color = diffuse_color;
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/interface/debugF.glsl b/indra/newview/app_settings/shaders/class1/interface/debugF.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..6bcc97ba1882cba93e48ca5b2a1981f7e98f5008
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/debugF.glsl
@@ -0,0 +1,35 @@
+/** 
+ * @file debugF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
+uniform vec4 color;
+
+void main() 
+{
+	gl_FragColor = color;
+}
diff --git a/indra/newview/app_settings/shaders/class1/interface/debugV.glsl b/indra/newview/app_settings/shaders/class1/interface/debugV.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..f4d704577ad5e6f83bfb83971895255c2258397d
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/debugV.glsl
@@ -0,0 +1,34 @@
+/** 
+ * @file debugV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+
+void main()
+{
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl
index b8963e1decb2813a3eb3418749e3d934dc666a81..f67703b83907b932b8a64e204a2af79d0bec42c8 100644
--- a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl
@@ -22,14 +22,21 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 #extension GL_ARB_texture_rectangle : enable
 
 uniform sampler2D glowMap;
 uniform sampler2DRect screenMap;
 
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+
 void main() 
 {
-	gl_FragColor = texture2D(glowMap, gl_TexCoord[0].xy) +
-					texture2DRect(screenMap, gl_TexCoord[1].xy);
+	gl_FragColor = texture2D(glowMap, vary_texcoord0.xy) +
+					texture2DRect(screenMap, vary_texcoord1.xy);
 }
diff --git a/indra/newview/app_settings/shaders/class3/deferred/giFinalF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl
similarity index 66%
rename from indra/newview/app_settings/shaders/class3/deferred/giFinalF.glsl
rename to indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl
index 7c55fcc2864075f0d8f3d441721a25ba7898127b..7136d412ea46fad3f0f6f9a823d5f65ad8e82c8a 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/giFinalF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl
@@ -1,9 +1,9 @@
 /** 
- * @file giFinalF.glsl
+ * @file glowcombineFXAAF.glsl
  *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2005, Linden Research, Inc.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -23,23 +23,23 @@
  * $/LicenseInfo$
  */
  
-
-
 #extension GL_ARB_texture_rectangle : enable
 
-uniform sampler2DRect diffuseRect;
-uniform sampler2D	  bloomMap;
-uniform sampler2DRect edgeMap;
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
-uniform vec2 screen_res;
-varying vec2 vary_fragcoord;
+uniform sampler2D glowMap;
+uniform sampler2DRect screenMap;
 
+uniform vec2 screen_res;
+VARYING vec2 vary_tc;
 
 void main() 
 {
-	vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res);
-	vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy);
+	vec3 col = texture2D(glowMap, vary_tc).rgb +
+					texture2DRect(screenMap, vary_tc*screen_res).rgb;
+
 	
-	gl_FragColor = bloom + diff;
-	//gl_FragColor.rgb = vec3(texture2DRect(edgeMap, vary_fragcoord.xy).a);
+	gl_FragColor = vec4(col.rgb, dot(col.rgb, vec3(0.299, 0.587, 0.144)));
 }
diff --git a/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAV.glsl
similarity index 76%
rename from indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl
rename to indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAV.glsl
index cb83dda795f87098fd9d5bc508b27c762cc53fff..058f3b1b820e5d97af8b290685074b71b2e3ae03 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAV.glsl
@@ -1,7 +1,7 @@
 /** 
- * @file postDeferredV.glsl
+ * @file glowcombineFXAAV.glsl
  *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2007, Linden Research, Inc.
  * 
@@ -22,16 +22,18 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 modelview_projection_matrix;
 
-varying vec2 vary_fragcoord;
-uniform vec2 screen_res;
+ATTRIBUTE vec3 position;
+
+VARYING vec2 vary_tc;
 
 void main()
 {
-	//transform vertex
-	gl_Position = ftransform(); 
-	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
-	vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
+	vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
+	gl_Position = pos;
+
+	vary_tc = pos.xy*0.5+0.5;
 }
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl
index 4c6360f71d036cb7622afdb452d2cd2e18d3d4cf..f7970b7f78b36ec21b1225cfdf5cab8f6c653875 100644
--- a/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl
@@ -22,12 +22,20 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec2 texcoord1;
+
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
 
 void main()
 {
-	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
-	gl_TexCoord[0] = gl_MultiTexCoord0;
-	gl_TexCoord[1] = gl_MultiTexCoord1;
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	vary_texcoord0 = texcoord0;
+	vary_texcoord1 = texcoord1;
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl
index a3cb5225ba36035b9485c72000f034affaecfc8c..ecbc30f05fff8fba0172bd319841f98c6c059e70 100644
--- a/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl
@@ -23,11 +23,16 @@
  * $/LicenseInfo$
  */
  
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
-
+uniform vec4 color;
 uniform sampler2D diffuseMap;
 
+VARYING vec2 vary_texcoord0;
+
 void main() 
 {
-	gl_FragColor = gl_Color*texture2D(diffuseMap, gl_TexCoord[0].xy);
+	gl_FragColor = color*texture2D(diffuseMap, vary_texcoord0.xy);
 }
diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl
index da3bea6d065c73a3995ed61db61ba40d64952c01..9bf7b60eb76a709653d9a379a1d3392ca9aa79b0 100644
--- a/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl
@@ -22,24 +22,19 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec2 vary_texcoord0;
 
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform();
-	vec3 pos = (gl_ModelViewMatrix * gl_Vertex).xyz;
-	pos = normalize(pos);
-	float d = dot(pos, normalize(gl_NormalMatrix * gl_Normal));
-	d *= d;
-	d = 1.0 - d;
-	d *= d;
-		
-	d = min(d, gl_Color.a*2.0);
-			
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
-	gl_FrontColor.rgb = gl_Color.rgb;
-	gl_FrontColor.a = max(d, gl_Color.a);
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
index 57248699cb97f656523b5ecae0ddaaf484dd2454..85f819f4c29e93fe27198079c4e6854187cf2ddc 100644
--- a/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
@@ -23,6 +23,10 @@
  * $/LicenseInfo$
  */
  
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 void main() 
 {
 	gl_FragColor = vec4(1,1,1,1);
diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionV.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionV.glsl
index 915e452e0f843ae2678e1d95afe92e5a984878dc..c26fa08ddc62e15f9ed80556d197e7ae7d5ef700 100644
--- a/indra/newview/app_settings/shaders/class1/interface/occlusionV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/occlusionV.glsl
@@ -23,8 +23,12 @@
  * $/LicenseInfo$
  */
 
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+
 void main()
 {
-	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorF.glsl b/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorF.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..fafeb5a7b4916bc2c653ea394ba333586a2c900a
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorF.glsl
@@ -0,0 +1,37 @@
+/** 
+ * @file onetexturenocolorF.glsl
+ *
+ * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2005, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
+uniform sampler2D tex0;
+
+VARYING vec2 vary_texcoord0;
+
+void main() 
+{
+	gl_FragColor = texture2D(tex0, vary_texcoord0.xy);
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl b/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorV.glsl
similarity index 79%
rename from indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl
rename to indra/newview/app_settings/shaders/class1/interface/onetexturenocolorV.glsl
index 6231ee68b75c69b50b1cbd480d448b468fd89833..6b9986c8d7f3d52a5a1d3b57ab357f62024a6fa1 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorV.glsl
@@ -1,5 +1,5 @@
 /** 
- * @file postgiV.glsl
+ * @file onetexturenocolorV.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -23,15 +23,16 @@
  * $/LicenseInfo$
  */
  
+uniform mat4 modelview_projection_matrix;
 
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
 
-varying vec2 vary_fragcoord;
-uniform vec2 screen_res;
+VARYING vec2 vary_texcoord0;
 
 void main()
 {
-	//transform vertex
-	gl_Position = ftransform(); 
-	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
-	vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
+	gl_Position = modelview_projection_matrix * vec4(position, 1);
+	vary_texcoord0 = texcoord0;
 }
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl b/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl
index b1d2b949acc49eab38b188f15fcbd6029bed318d..f790122749400020f115babcf9422da6a9cc3629 100644
--- a/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl
@@ -22,12 +22,19 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform sampler2D tex0;
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
 void main() 
 {
-	float alpha = texture2D(tex0, gl_TexCoord[0].xy).a * gl_Color.a;
+	float alpha = texture2D(tex0, vary_texcoord0.xy).a * vertex_color.a;
 
-	gl_FragColor = vec4(gl_Color.rgb, alpha);
+	gl_FragColor = vec4(vertex_color.rgb, alpha);
 }
diff --git a/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl b/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl
index fedf6ae5466ce282650d6772781355e525637a62..c58f9dfdaf84554d27e407035229ae23df175b88 100644
--- a/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl
@@ -22,13 +22,20 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
+
+uniform mat4 modelview_projection_matrix;
  
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 void main()
 {
-	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
-	gl_FrontColor = gl_Color;
-	gl_TexCoord[0] = gl_MultiTexCoord0;
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	vertex_color = diffuse_color;
+	vary_texcoord0 = texcoord0;
 }
 
diff --git a/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl
similarity index 76%
rename from indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl
rename to indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl
index 13517a26baca2a7e633391ddd0df7257d6bc03a3..a0bb255cfaa214818bf95069ac37a8d358adfb1f 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl
@@ -1,9 +1,9 @@
 /** 
- * @file luminanceF.glsl
+ * @file splattexturerectF.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2011, Linden Research, Inc.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -23,17 +23,18 @@
  * $/LicenseInfo$
  */
  
+#extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
-#extension GL_ARB_texture_rectangle : enable
+uniform sampler2DRect screenMap;
 
-uniform sampler2DRect lightMap;
-uniform sampler2DRect diffuseRect;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
-varying vec2 vary_fragcoord;
 void main() 
 {
-	float i = texture2DRect(lightMap, vary_fragcoord.xy).r;
-	gl_FragColor.rgb = vec3(i);
-	gl_FragColor.a = 1.0;
+	gl_FragColor = 	texture2DRect(screenMap, vary_texcoord0.xy) * vertex_color;
 }
diff --git a/indra/newview/app_settings/shaders/class3/deferred/giV.glsl b/indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl
similarity index 70%
rename from indra/newview/app_settings/shaders/class3/deferred/giV.glsl
rename to indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl
index 190e32b6a34102d938e25f11ca0f22962d66b332..641d670c2675111ebd23900912e964db7bfd222e 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/giV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl
@@ -1,9 +1,9 @@
 /** 
- * @file giV.glsl
+ * @file splattexturerectV.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2011, Linden Research, Inc.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -22,21 +22,20 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 modelview_projection_matrix;
 
-varying vec2 vary_fragcoord;
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec4 diffuse_color;
 
-uniform vec2 screen_res;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 void main()
 {
-	//transform vertex
-	gl_Position = ftransform(); 
-	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
-	vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res;	
-	vec4 tex = gl_MultiTexCoord0;
-	tex.w = 1.0;
-
-	gl_FrontColor = gl_Color;
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	vary_texcoord0 = texcoord0;
+	vertex_color = diffuse_color;
 }
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl b/indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl
index 3408cc44f8e37afc52bf6b9a006463eee85ce2bf..cdb48163dd48e2eb20dfa0ffe66fc1d934967e9e 100644
--- a/indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl
@@ -22,11 +22,18 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform sampler2D tex0;
 uniform sampler2D tex1;
 
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+
 void main() 
 {
-	gl_FragColor = texture2D(tex0, gl_TexCoord[0].xy)+texture2D(tex1, gl_TexCoord[1].xy);
+	gl_FragColor = texture2D(tex0, vary_texcoord0.xy)+texture2D(tex1, vary_texcoord1.xy);
 }
diff --git a/indra/newview/app_settings/shaders/class1/interface/twotextureaddV.glsl b/indra/newview/app_settings/shaders/class1/interface/twotextureaddV.glsl
index 94aa964be6d53020557dac7c46759df913501bc7..3c2f297f7f555c6a25461ada639762adca41e9a5 100644
--- a/indra/newview/app_settings/shaders/class1/interface/twotextureaddV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/twotextureaddV.glsl
@@ -23,12 +23,19 @@
  * $/LicenseInfo$
  */
  
+uniform mat4 modelview_projection_matrix;
 
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec2 texcoord1;
+
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
 
 void main()
 {
-	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
-	gl_TexCoord[0] = gl_MultiTexCoord0;
-	gl_TexCoord[1] = gl_MultiTexCoord1;
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	vary_texcoord0 = texcoord0;
+	vary_texcoord1 = texcoord1;
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/interface/uiF.glsl b/indra/newview/app_settings/shaders/class1/interface/uiF.glsl
index 7694056b08f5801ed4ee0f8ef70cfca6946c98f5..36d6e06fc5f7baae3e33e19fb4fe7ab46887cedd 100644
--- a/indra/newview/app_settings/shaders/class1/interface/uiF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/uiF.glsl
@@ -22,10 +22,17 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform sampler2D diffuseMap;
 
+VARYING vec2 vary_texcoord0;
+VARYING vec4 vertex_color;
+
 void main() 
 {
-	gl_FragColor = gl_Color*texture2D(diffuseMap, gl_TexCoord[0].xy);
+	gl_FragColor = vertex_color*texture2D(diffuseMap, vary_texcoord0.xy);
 }
diff --git a/indra/newview/app_settings/shaders/class1/interface/uiV.glsl b/indra/newview/app_settings/shaders/class1/interface/uiV.glsl
index b1b90d0b5eced13de9a2818f3a952a298d5adcef..220dafef25d977f8db1cdb5d9a386258060e0c0b 100644
--- a/indra/newview/app_settings/shaders/class1/interface/uiV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/uiV.glsl
@@ -22,13 +22,21 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 void main()
 {
-	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
-	gl_TexCoord[0] = gl_MultiTexCoord0;
-	gl_FrontColor = gl_Color;
+	gl_Position = modelview_projection_matrix * vec4(position, 1);
+	vary_texcoord0 =  (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+	vertex_color = diffuse_color;
 }
 
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
similarity index 88%
rename from indra/newview/app_settings/shaders/class2/lighting/lightAlphaMaskF.glsl
rename to indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
index 4c053290655bb54fefb354bb06216f9b05d7cd5f..6815f7aa85af3482d56f803b841300d8db9a7829 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
@@ -23,6 +23,9 @@
  * $/LicenseInfo$
  */
  
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
 uniform float minimum_alpha;
 uniform float maximum_alpha;
@@ -30,9 +33,12 @@ uniform float maximum_alpha;
 vec3 atmosLighting(vec3 light);
 vec3 scaleSoftClip(vec3 light);
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
 void default_lighting() 
 {
-	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;
+	vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
 	
 	if (color.a < minimum_alpha || color.a > maximum_alpha)
 	{
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl
similarity index 87%
rename from indra/newview/app_settings/shaders/class2/lighting/lightAlphaMaskNonIndexedF.glsl
rename to indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl
index 0de909353e18fd8b611623ea748e4ba2fb1f4af9..2640668d7dce2db2c7412f05712313ba0596e9ec 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightAlphaMaskNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl
@@ -22,7 +22,10 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
 uniform float minimum_alpha;
 uniform float maximum_alpha;
@@ -33,9 +36,12 @@ uniform sampler2D diffuseMap;
 vec3 atmosLighting(vec3 light);
 vec3 scaleSoftClip(vec3 light);
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
 void default_lighting() 
 {
-	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color;
+	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
 
 	if (color.a < minimum_alpha || color.a > maximum_alpha)
 	{
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl
index 5cb3eb05a7c283da669cd7b88ba1a27835b93ba0..735f5b381376edb98516bcac2469d8349976343a 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl
@@ -22,14 +22,25 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
-uniform sampler2D diffuseMap;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+vec3 atmosLighting(vec3 light);
+vec3 scaleSoftClip(vec3 light);
 
 void default_lighting() 
 {
-	vec4 color = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy);
+	vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
+	
+	color.rgb = atmosLighting(color.rgb);
+
+	color.rgb = scaleSoftClip(color.rgb);
+
 	gl_FragColor = color;
 }
 
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
similarity index 88%
rename from indra/newview/app_settings/shaders/class2/lighting/lightFullbrightAlphaMaskF.glsl
rename to indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
index 8c7713c08db6aa6c3717b8ad865ecef2761323b8..92113d9afa6aff8a98cae86f3339249307eff3c0 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
@@ -22,16 +22,23 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform float minimum_alpha;
 uniform float maximum_alpha;
 
 vec3 fullbrightAtmosTransport(vec3 light);
 vec3 fullbrightScaleSoftClip(vec3 light);
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
 void fullbright_lighting()
 {
-	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;
+	vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
 	
 	if (color.a < minimum_alpha || color.a > maximum_alpha)
 	{
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
index f3ba8b73a80d978d7acf716a4efd0fe60e42fe6a..c3edc0bd708e9cd99ff8030c990b7ba83cdb3d46 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
@@ -22,14 +22,25 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
-uniform sampler2D diffuseMap;
+vec3 fullbrightAtmosTransport(vec3 light);
+vec3 fullbrightScaleSoftClip(vec3 light);
 
 void fullbright_lighting()
 {
-	gl_FragColor = texture2D(diffuseMap, gl_TexCoord[0].xy);
+	vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
+	
+	color.rgb = fullbrightAtmosTransport(color.rgb);
+	
+	color.rgb = fullbrightScaleSoftClip(color.rgb);
+
+	gl_FragColor = color;
 }
 
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
similarity index 88%
rename from indra/newview/app_settings/shaders/class2/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
rename to indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
index 89468b9665316da515dd180fe0471bc16c3bce5d..d1ad3da0096242b2ea7e5052ae318e58fad57ac6 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
@@ -22,7 +22,11 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform float minimum_alpha;
 uniform float maximum_alpha;
 
@@ -31,9 +35,12 @@ vec3 fullbrightScaleSoftClip(vec3 light);
 
 uniform sampler2D diffuseMap;
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
 void fullbright_lighting()
 {
-	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color;
+	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
 	
 	if (color.a < minimum_alpha || color.a > maximum_alpha)
 	{
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl
similarity index 87%
rename from indra/newview/app_settings/shaders/class2/lighting/lightFullbrightNonIndexedF.glsl
rename to indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl
index a909ff608af520cf77357875093462f005df5946..4e1e664e6b5c99f7ee3d62870c8f2502ce1b1b3d 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl
@@ -22,8 +22,13 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 vec3 fullbrightAtmosTransport(vec3 light);
 vec3 fullbrightScaleSoftClip(vec3 light);
@@ -32,7 +37,7 @@ uniform sampler2D diffuseMap;
 
 void fullbright_lighting()
 {
-	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color;
+	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
 	
 	color.rgb = fullbrightAtmosTransport(color.rgb);
 	
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
index b4c8a9abcedbde35c6209cdee0839df470b77f9b..c981e9eba255b0f2df190f2a8f252a8ad8db8cc9 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
@@ -22,14 +22,34 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_texcoord1;
 
-uniform sampler2D diffuseMap;
 uniform samplerCube environmentMap;
 
-void fullbright_shiny_lighting() 
+vec3 fullbrightShinyAtmosTransport(vec3 light);
+vec3 fullbrightScaleSoftClip(vec3 light);
+
+void fullbright_shiny_lighting()
 {
-	gl_FragColor = texture2D(diffuseMap, gl_TexCoord[0].xy);
+	vec4 color = diffuseLookup(vary_texcoord0.xy);
+	color.rgb *= vertex_color.rgb;
+	
+	vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;	
+	color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
+
+	color.rgb = fullbrightShinyAtmosTransport(color.rgb);
+
+	color.rgb = fullbrightScaleSoftClip(color.rgb);
+
+	color.a = max(color.a, vertex_color.a);
+
+	gl_FragColor = color;
 }
+
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl
similarity index 76%
rename from indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyNonIndexedF.glsl
rename to indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl
index af73168c13085ee434bafd166da053802142e0f8..a4893f035997ac9f0deb25609c6a95342081f2fe 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl
@@ -22,8 +22,14 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_texcoord1;
 
 uniform samplerCube environmentMap;
 uniform sampler2D diffuseMap;
@@ -33,17 +39,17 @@ vec3 fullbrightScaleSoftClip(vec3 light);
 
 void fullbright_shiny_lighting()
 {
-	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy);
-	color.rgb *= gl_Color.rgb;
+	vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
+	color.rgb *= vertex_color.rgb;
 	
-	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	
-	color.rgb = mix(color.rgb, envColor.rgb, gl_Color.a);
+	vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;	
+	color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
 
 	color.rgb = fullbrightShinyAtmosTransport(color.rgb);
 
 	color.rgb = fullbrightScaleSoftClip(color.rgb);
 
-	color.a = max(color.a, gl_Color.a);
+	color.a = max(color.a, vertex_color.a);
 
 	gl_FragColor = color;
 }
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl
index 925d6fbcfd860471b9181ceb845ee7b6868bc26a..c10cde98e0ddcb6c493fff00300191e8b649329f 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl
@@ -21,14 +21,33 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
-
  
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_texcoord1;
 
-uniform sampler2D diffuseMap;
 uniform samplerCube environmentMap;
 
-void fullbright_shiny_lighting_water() 
+vec3 fullbrightShinyAtmosTransport(vec3 light);
+vec3 fullbrightScaleSoftClip(vec3 light);
+vec4 applyWaterFog(vec4 color);
+
+void fullbright_shiny_lighting_water()
 {
-	gl_FragColor = texture2D(diffuseMap, gl_TexCoord[0].xy);
+	vec4 color = diffuseLookup(vary_texcoord0.xy);
+	color.rgb *= vertex_color.rgb;
+	
+	vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;	
+	color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
+
+	color.rgb = fullbrightShinyAtmosTransport(color.rgb);
+	color.rgb = fullbrightScaleSoftClip(color.rgb);
+	color.a = max(color.a, vertex_color.a);
+
+	gl_FragColor = applyWaterFog(color);
 }
+
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl
similarity index 77%
rename from indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterNonIndexedF.glsl
rename to indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl
index e0a7986705adb1a96e06e4b57c12e0b74e5555f8..e9b26087f46074854e3a161d264113bfddcfdb0f 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl
@@ -22,8 +22,13 @@
  * $/LicenseInfo$
  */
  
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
-
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_texcoord1;
 
 uniform samplerCube environmentMap;
 uniform sampler2D diffuseMap;
@@ -34,15 +39,15 @@ vec4 applyWaterFog(vec4 color);
 
 void fullbright_shiny_lighting_water()
 {
-	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy);
-	color.rgb *= gl_Color.rgb;
+	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
+	color.rgb *= vertex_color.rgb;
 	
-	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	
-	color.rgb = mix(color.rgb, envColor.rgb, gl_Color.a);
+	vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;	
+	color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
 
 	color.rgb = fullbrightShinyAtmosTransport(color.rgb);
 	color.rgb = fullbrightScaleSoftClip(color.rgb);
-	color.a = max(color.a, gl_Color.a);
+	color.a = max(color.a, vertex_color.a);
 
 	gl_FragColor = applyWaterFog(color);
 }
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
similarity index 88%
rename from indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterAlphaMaskF.glsl
rename to indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
index e5998b77a9ca3151290e835c156c1726e4d39c02..32a1c71099b0fbffc82528acd11da0f29b77452b 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
@@ -23,6 +23,10 @@
  * $/LicenseInfo$
  */
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform float minimum_alpha;
 uniform float maximum_alpha;
 
@@ -31,9 +35,12 @@ vec4 diffuseLookup(vec2 texcoord);
 vec3 fullbrightAtmosTransport(vec3 light);
 vec4 applyWaterFog(vec4 color);
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
 void fullbright_lighting_water()
 {
-	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;
+	vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
 
 	if (color.a < minimum_alpha || color.a > maximum_alpha)
 	{
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
index 71238f7d31609653c2698502a3b2aef2c4157cf4..2547f9e75054957436659fe8b90d392272091eda 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
@@ -23,13 +23,24 @@
  * $/LicenseInfo$
  */
 
- 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
-uniform sampler2D diffuseMap;
+vec4 diffuseLookup(vec2 texcoord);
+
+vec3 fullbrightAtmosTransport(vec3 light);
+vec4 applyWaterFog(vec4 color);
 
 void fullbright_lighting_water()
 {
-	gl_FragColor = texture2D(diffuseMap, gl_TexCoord[0].xy);
+	vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
+
+	color.rgb = fullbrightAtmosTransport(color.rgb);
+	
+	gl_FragColor = applyWaterFog(color);
 }
 
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl
similarity index 87%
rename from indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl
rename to indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl
index 3fdd110f7d76435fa2c6cb9968eafecaa20f0e4e..1b5aa614413c04fdc7673de2e6abf024002bab79 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl
@@ -22,7 +22,11 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform float minimum_alpha;
 uniform float maximum_alpha;
 
@@ -31,9 +35,12 @@ uniform sampler2D diffuseMap;
 vec3 fullbrightAtmosTransport(vec3 light);
 vec4 applyWaterFog(vec4 color);
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
 void fullbright_lighting_water()
 {
-	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color;
+	vec4 color = texture2D(diffuseMap, vary_texcoord0.xy) * vertex_color;
 
 	if (color.a < minimum_alpha || color.a > maximum_alpha)
 	{
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl
similarity index 86%
rename from indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterNonIndexedF.glsl
rename to indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl
index 01b89019b15bb633e49cf6278e9401d81e46b3ae..aa3ef8cdd91290df2ab60b037237abf57e251da5 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl
@@ -22,8 +22,13 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 uniform sampler2D diffuseMap;
 
@@ -32,7 +37,7 @@ vec4 applyWaterFog(vec4 color);
 
 void fullbright_lighting_water()
 {
-	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color;
+	vec4 color = texture2D(diffuseMap, vary_texcoord0.xy) * vertex_color;
 
 	color.rgb = fullbrightAtmosTransport(color.rgb);
 	
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl
similarity index 86%
rename from indra/newview/app_settings/shaders/class2/lighting/lightNonIndexedF.glsl
rename to indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl
index d419c2d116ec1395ec366991b22ad56c919b5275..9f1a358b5389a6c134f9c5a9d3a52149f6cf6ee2 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl
@@ -22,8 +22,13 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+ 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 uniform sampler2D diffuseMap;
 
@@ -32,7 +37,7 @@ vec3 scaleSoftClip(vec3 light);
 
 void default_lighting() 
 {
-	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color;
+	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
 	
 	color.rgb = atmosLighting(color.rgb);
 
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl
index 7c9b7c218f96e5dcb77bdea530593e9f6c5e97ba..e9c27dbefd5c5266260d2137fe611bea7bc91569 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl
@@ -22,16 +22,33 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_texcoord1;
 
-uniform sampler2D diffuseMap;
 uniform samplerCube environmentMap;
 
-void shiny_lighting() 
+vec3 scaleSoftClip(vec3 light);
+vec3 atmosLighting(vec3 light);
+vec4 applyWaterFog(vec4 color);
+
+void shiny_lighting()
 {
-	vec4 color = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy);
+	vec4 color = diffuseLookup(vary_texcoord0.xy);
+	color.rgb *= vertex_color.rgb;
+	
+	vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;	
+	color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
+
+	color.rgb = atmosLighting(color.rgb);
+
+	color.rgb = scaleSoftClip(color.rgb);
+	color.a = max(color.a, vertex_color.a);
 	gl_FragColor = color;
 }
 
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl
similarity index 76%
rename from indra/newview/app_settings/shaders/class2/lighting/lightShinyNonIndexedF.glsl
rename to indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl
index 3b30ebf6f144e8acc4679738a836e15b136c5cf6..595ad743650d9b6b938a4f32b1df9f258eb0f035 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightShinyNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl
@@ -22,9 +22,14 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
-
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+ 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_texcoord1;
 
 uniform samplerCube environmentMap;
 uniform sampler2D diffuseMap;
@@ -35,16 +40,16 @@ vec4 applyWaterFog(vec4 color);
 
 void shiny_lighting()
 {
-	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy);
-	color.rgb *= gl_Color.rgb;
+	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
+	color.rgb *= vertex_color.rgb;
 	
-	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	
-	color.rgb = mix(color.rgb, envColor.rgb, gl_Color.a);
+	vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;	
+	color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
 
 	color.rgb = atmosLighting(color.rgb);
 
 	color.rgb = scaleSoftClip(color.rgb);
-	color.a = max(color.a, gl_Color.a);
+	color.a = max(color.a, vertex_color.a);
 	gl_FragColor = color;
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl
index ca1af8fc795b7e15c9f01dc8e473cbb76fd3aaec..68c727d62c4e4e7b2b3ea64ffbad60e2c27e902b 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl
@@ -22,16 +22,30 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_texcoord1;
 
-uniform sampler2D diffuseMap;
 uniform samplerCube environmentMap;
 
-void shiny_lighting_water() 
+vec3 atmosLighting(vec3 light);
+vec4 applyWaterFog(vec4 color);
+
+void shiny_lighting_water()
 {
-	vec4 color = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy);
-	gl_FragColor = color;
+	vec4 color = diffuseLookup(vary_texcoord0.xy);
+	color.rgb *= vertex_color.rgb;
+	
+	vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;	
+	color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
+
+	color.rgb = atmosLighting(color.rgb);
+	color.a = max(color.a, vertex_color.a);
+	gl_FragColor = applyWaterFog(color);
 }
 
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl
similarity index 75%
rename from indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterNonIndexedF.glsl
rename to indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl
index eeb997fb5f77729c1183c19c439bf5eb1af878c6..f32b9e1958bfb0b15f46635ee3edc30121b92bd2 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl
@@ -22,9 +22,14 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_texcoord1;
 
 uniform sampler2D diffuseMap;
 uniform samplerCube environmentMap;
@@ -34,14 +39,14 @@ vec4 applyWaterFog(vec4 color);
 
 void shiny_lighting_water()
 {
-	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy);
-	color.rgb *= gl_Color.rgb;
+	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
+	color.rgb *= vertex_color.rgb;
 	
-	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	
-	color.rgb = mix(color.rgb, envColor.rgb, gl_Color.a);
+	vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;	
+	color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
 
 	color.rgb = atmosLighting(color.rgb);
-	color.a = max(color.a, gl_Color.a);
+	color.a = max(color.a, vertex_color.a);
 	gl_FragColor = applyWaterFog(color);
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl
index 4a59b8245dc100419b4451e295ea19e6352003ab..24bf9b3cee5168a8cfc7928b545eddc39e8a9736 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl
@@ -1,5 +1,5 @@
 /** 
- * @file lightV.glsl
+ * @file lightSpecularV.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -25,22 +25,12 @@
  
 
 
-float calcDirectionalLight(vec3 n, vec3 l);
+// All lights, no specular highlights
+
+vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol);
 
-// Same as non-specular lighting in lightV.glsl
 vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol)
 {
-	specularColor.rgb = vec3(0.0, 0.0, 0.0);
-	vec4 col;
-	col.a = color.a;
-
-	col.rgb = gl_LightModel.ambient.rgb + baseCol.rgb;
-
-	col.rgb += gl_LightSource[0].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[0].position.xyz);
-	col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);
-
-	col.rgb = min(col.rgb*color.rgb, 1.0);
-
-	return col;	
+	return sumLightsSpecular(pos, norm, color, specularColor, baseCol);
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl
index 742cb38d804ba27595b79ab1ece82a9886b8133a..8045809b82c6cc6e18b4fdfeefa9ec26ed35c706 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl
@@ -25,20 +25,12 @@
  
 
 
-float calcDirectionalLight(vec3 n, vec3 l);
+// All lights, no specular highlights
+
+vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight);
 
 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseLight)
 {
-	vec4 col;
-	col.a = color.a;
-	
-	col.rgb = gl_LightModel.ambient.rgb + baseLight.rgb;
-	
-	col.rgb += gl_LightSource[0].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[0].position.xyz);
-	col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);
-						
-	col.rgb = min(col.rgb*color.rgb, 1.0);
-	
-	return col;	
+	return sumLights(pos, norm, color, baseLight);
 }
 
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
similarity index 87%
rename from indra/newview/app_settings/shaders/class2/lighting/lightWaterAlphaMaskF.glsl
rename to indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
index 072dcaa6b65e327a73642b7dd3ec03fc1038269f..60289cf7f7733694076f9eafc99311fb0fc9e888 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightWaterAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
@@ -22,16 +22,23 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform float minimum_alpha;
 uniform float maximum_alpha;
 
 vec3 atmosLighting(vec3 light);
 vec4 applyWaterFog(vec4 color);
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
 void default_lighting_water()
 {
-	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;
+	vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
 
 	if (color.a < minimum_alpha || color.a > maximum_alpha)
 	{
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightWaterAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
similarity index 87%
rename from indra/newview/app_settings/shaders/class2/lighting/lightWaterAlphaMaskNonIndexedF.glsl
rename to indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
index 2df34da4b47aa2026ce06fde1ecf8694161221d0..d0038ae89bc82931ab06636665bb66ad20fa6c9b 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightWaterAlphaMaskNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
@@ -22,7 +22,11 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform float minimum_alpha;
 uniform float maximum_alpha;
 
@@ -31,9 +35,12 @@ uniform sampler2D diffuseMap;
 vec3 atmosLighting(vec3 light);
 vec4 applyWaterFog(vec4 color);
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
 void default_lighting_water()
 {
-	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color;
+	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
 
 	if (color.a < minimum_alpha || color.a > maximum_alpha)
 	{
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl
index da76a977b6427228c370a3c7eb50ccb51fb62182..e9537d1e9d5eac272053a07269e9dcee4214ee65 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl
@@ -22,14 +22,23 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif 
 
-uniform sampler2D diffuseMap;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
-void default_lighting_water() 
+vec3 atmosLighting(vec3 light);
+vec4 applyWaterFog(vec4 color);
+
+void default_lighting_water()
 {
-	vec4 color = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy);
-	gl_FragColor = color;
+	vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
+
+	color.rgb = atmosLighting(color.rgb);
+
+	gl_FragColor = applyWaterFog(color);
 }
 
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl
similarity index 86%
rename from indra/newview/app_settings/shaders/class2/lighting/lightWaterNonIndexedF.glsl
rename to indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl
index 5a86dad82785c344bbd012d9f99a129a2b1ff955..8b0c25b7053d601d48a63eba8382b869a40fa37d 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightWaterNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl
@@ -22,8 +22,13 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 uniform sampler2D diffuseMap;
 
@@ -32,7 +37,7 @@ vec4 applyWaterFog(vec4 color);
 
 void default_lighting_water()
 {
-	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color;
+	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
 
 	color.rgb = atmosLighting(color.rgb);
 
diff --git a/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl
index 3e0815226c698324b3cd87656be97b575e06178a..7059ff31aed4b7fa8ffb0661c2e6fc98ad939f46 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl
@@ -31,21 +31,22 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);
 vec3 atmosGetDiffuseSunlightColor();
 vec3 scaleDownLight(vec3 light);
 
+uniform vec4 light_position[8];
+uniform vec3 light_diffuse[8];
+
 vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol)
 {
-	vec4 col;
-	col.a = color.a;
-	
-	
+	vec4 col = vec4(0,0,0, color.a);
+		
 	vec3 view = normalize(pos);
 	
 	/// collect all the specular values from each calcXXXLightSpecular() function
 	vec4 specularSum = vec4(0.0);
 
-	col.rgb = gl_LightSource[1].diffuse.rgb * calcDirectionalLightSpecular(specularColor, view, norm, gl_LightSource[1].position.xyz, gl_LightSource[1].diffuse.rgb, 1.0);
+	col.rgb += light_diffuse[1].rgb * calcDirectionalLightSpecular(specularColor, view, norm, light_position[1].xyz,light_diffuse[1].rgb, 1.0);
 	col.rgb = scaleDownLight(col.rgb);
 	col.rgb += atmosAmbient(baseCol.rgb);
-	col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, gl_LightSource[0].position.xyz,atmosGetDiffuseSunlightColor() * baseCol.a, 1.0));
+	col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, light_position[0].xyz,atmosGetDiffuseSunlightColor()*baseCol.a, 1.0));
 
 	col.rgb = min(col.rgb * color.rgb, 1.0);
 	specularColor.rgb = min(specularColor.rgb * specularSum.rgb, 1.0);
diff --git a/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl
index c271dbcd18920be785ce378c7fbcb453093b16b0..41288c21c19c4be8a7ecc5052b108bb74fd690d3 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl
@@ -23,7 +23,8 @@
  * $/LicenseInfo$
  */
  
-
+uniform vec4 light_position[8];
+uniform vec3 light_diffuse[8];
 
 float calcDirectionalLight(vec3 n, vec3 l);
 
@@ -36,10 +37,10 @@ vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight)
 	vec4 col;
 	col.a = color.a;
 	
-	col.rgb = gl_LightSource[1].diffuse.rgb * calcDirectionalLight(norm, gl_LightSource[1].position.xyz);
+	col.rgb = light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
 	col.rgb = scaleDownLight(col.rgb);
 	col.rgb += atmosAmbient(baseLight.rgb);
-	col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, gl_LightSource[0].position.xyz));
+	col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, light_position[0].xyz));
 	
 	col.rgb = min(col.rgb*color.rgb, 1.0);
 	
diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl
index 11031a8829819a074acd4ea55ecaaa0460e38d98..4b85d61aca8b090aae822ad57be3c38b01d1d726 100644
--- a/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl
@@ -22,14 +22,21 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform sampler2D texture0;
 uniform sampler2D texture1;
 
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+
 void main() 
 {
-	float tex0 = texture2D(texture0, gl_TexCoord[0].xy).a;
-	float tex1 = texture2D(texture1, gl_TexCoord[1].xy).a;
+	float tex0 = texture2D(texture0, vary_texcoord0.xy).a;
+	float tex1 = texture2D(texture1, vary_texcoord1.xy).a;
 
 	gl_FragColor = vec4(tex0+(1.0-tex1)-0.5);
 }
diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl
index c50ed86315d172dcfa0873533258e9f9241fb082..a7738087dcc940f41229140b89a9fa54502d85fc 100644
--- a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl
@@ -22,13 +22,21 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec2 texcoord1;
+
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
 
 void main()
 {
 	//transform vertex
-	gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
-	gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1;
-	gl_FrontColor = gl_Color;
+	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+	vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
 }
diff --git a/indra/newview/app_settings/shaders/class2/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl
similarity index 65%
rename from indra/newview/app_settings/shaders/class2/objects/simpleV.glsl
rename to indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl
index b0114763c144f4c86b1dec01853072012cd85783..8494ffba5289f7f3c06d74387d6cff315417b77e 100644
--- a/indra/newview/app_settings/shaders/class2/objects/simpleV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl
@@ -1,5 +1,5 @@
 /** 
- * @file simpleV.glsl
+ * @file emissiveSkinnedV.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -22,30 +22,37 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 projection_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
 
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
-void calcAtmospherics(vec3 inPositionEye);
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 emissive;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
-varying float vary_texture_index;
+
+void calcAtmospherics(vec3 inPositionEye);
+mat4 getObjectSkinnedTransform();
 
 void main()
 {
 	//transform vertex
-	vec4 vert = vec4(gl_Vertex.xyz,1.0);
-	vary_texture_index = gl_Vertex.w;
-	gl_Position = gl_ModelViewProjectionMatrix*vert;
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 	
-	vec4 pos = (gl_ModelViewMatrix * vert);
+	mat4 mat = getObjectSkinnedTransform();
+	
+	mat = modelview_matrix * mat;
+	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
 	
-	vec3 norm = normalize(gl_NormalMatrix * gl_Normal);
-
 	calcAtmospherics(pos.xyz);
 
-	vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.));
-	gl_FrontColor = color;
-
-	gl_FogFragCoord = pos.z;
+	vertex_color = emissive;
+	
+	gl_Position = projection_matrix*vec4(pos, 1.0);
+		
+	
 }
diff --git a/indra/newview/app_settings/shaders/class2/objects/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl
similarity index 63%
rename from indra/newview/app_settings/shaders/class2/objects/fullbrightShinyV.glsl
rename to indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl
index 819b28e4fd9d4214aaf742eeb2dcb1953d1401c0..e984deb0c89c10a12ce0547ce4596dce9cad820d 100644
--- a/indra/newview/app_settings/shaders/class2/objects/fullbrightShinyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl
@@ -1,7 +1,7 @@
 /**
- * @file fullbrightShinyV.glsl
+ * @file emissiveV.glsl
  *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2007, Linden Research, Inc.
  * 
@@ -22,32 +22,35 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+void passTextureIndex();
+ATTRIBUTE vec4 emissive;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 void calcAtmospherics(vec3 inPositionEye);
 
-uniform vec4 origin;
 
-varying float vary_texture_index;
+
 
 void main()
 {
 	//transform vertex
-	vec4 vert = vec4(gl_Vertex.xyz,1.0);
-	vary_texture_index = gl_Vertex.w;
-	gl_Position = gl_ModelViewProjectionMatrix*vert;
+	passTextureIndex();
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 	
-	vec4 pos = (gl_ModelViewMatrix * vert);
-	vec3 norm = normalize(gl_NormalMatrix * gl_Normal);
-	vec3 ref = reflect(pos.xyz, -norm);
-
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
-	gl_TexCoord[1] = gl_TextureMatrix[1]*vec4(ref,1.0);
-
+	vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0));
 	calcAtmospherics(pos.xyz);
 
-	gl_FrontColor = gl_Color;
+	vertex_color = emissive;
 
-	gl_FogFragCoord = pos.z;
+	
 }
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl
index 0fab5e5001007ad0bebf5ce122484ea23206a53d..a54c0caf81079e22e56e76a98257b1ea99a231bc 100644
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl
@@ -20,7 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  * 
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
+ * $/LicenseInfo$F
  */
  
 
diff --git a/indra/newview/app_settings/shaders/class2/objects/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightNoColorV.glsl
similarity index 67%
rename from indra/newview/app_settings/shaders/class2/objects/fullbrightV.glsl
rename to indra/newview/app_settings/shaders/class1/objects/fullbrightNoColorV.glsl
index abf6e37b7cbdd964cce13fb97df42cefdd820527..5d6f14230c73b14a9fd36a94a56d9d45054574cc 100644
--- a/indra/newview/app_settings/shaders/class2/objects/fullbrightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightNoColorV.glsl
@@ -1,5 +1,5 @@
 /**
- * @file fullbrightV.glsl
+ * @file fullbrightNoColorV.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -22,26 +22,32 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec3 normal;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
-void calcAtmospherics(vec3 inPositionEye);
 
-varying float vary_texture_index;
+void calcAtmospherics(vec3 inPositionEye);
 
 void main()
 {
 	//transform vertex
-	vec4 vert = vec4(gl_Vertex.xyz,1.0);
-	vary_texture_index = gl_Vertex.w;
-	gl_Position = gl_ModelViewProjectionMatrix*vert;
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
-	
-	vec4 pos = (gl_ModelViewMatrix * vert);
+	vec4 vert = vec4(position.xyz,1.0);
+	vec4 pos = (modelview_matrix * vert);
+	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 
 	calcAtmospherics(pos.xyz);
 
-	gl_FrontColor = gl_Color;
+	vertex_color = vec4(1,1,1,1);
 
-	gl_FogFragCoord = pos.z;
+	
 }
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl
index e1a7f263f7aaaddf479be6325a081ea573815a3c..79b552ee1a9656fcb18a5e93d406ab30cd8d2b6c 100644
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl
@@ -22,6 +22,19 @@
  * $/LicenseInfo$
  */
 
+uniform mat4 texture_matrix0;
+uniform mat4 texture_matrix1;
+uniform mat4 modelview_matrix;
+uniform mat4 projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_texcoord1;
 
 
 void calcAtmospherics(vec3 inPositionEye);
@@ -31,24 +44,24 @@ void main()
 {
 	mat4 mat = getObjectSkinnedTransform();
 	
-	mat = gl_ModelViewMatrix * mat;
-	vec3 pos = (mat*gl_Vertex).xyz;
+	mat = modelview_matrix * mat;
+	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
 	
-	vec4 norm = gl_Vertex;
-	norm.xyz += gl_Normal.xyz;
+	vec4 norm = vec4(position.xyz, 1.0);
+	norm.xyz += normal.xyz;
 	norm.xyz = (mat*norm).xyz;
 	norm.xyz = normalize(norm.xyz-pos.xyz);
 		
 	vec3 ref = reflect(pos.xyz, -norm.xyz);
 
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
-	gl_TexCoord[1] = gl_TextureMatrix[1]*vec4(ref,1.0);
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+	vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz;
 
 	calcAtmospherics(pos.xyz);
 
-	gl_FrontColor = gl_Color;
+	vertex_color = diffuse_color;
+	
+	gl_Position = projection_matrix*vec4(pos, 1.0);
 	
-	gl_Position = gl_ProjectionMatrix*vec4(pos, 1.0);
 	
-	gl_FogFragCoord = pos.z;
 }
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl
index 36b00dfbc109a4cb09b8b3f69ebffdd8e5fe788d..34bd8d445a0eb532d77e10ea45897715bc369c65 100644
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl
@@ -22,28 +22,46 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 texture_matrix1;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
 
 
 void calcAtmospherics(vec3 inPositionEye);
 
 uniform vec4 origin;
 
+
+
+ATTRIBUTE vec3 position;
+void passTextureIndex();
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_texcoord1;
+
+
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform();
+	vec4 vert = vec4(position.xyz,1.0);
+	passTextureIndex();
+	vec4 pos = (modelview_matrix * vert);
+	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
 	
-	vec4 pos = (gl_ModelViewMatrix * gl_Vertex);
-	vec3 norm = normalize(gl_NormalMatrix * gl_Normal);
+	vec3 norm = normalize(normal_matrix * normal);
 	vec3 ref = reflect(pos.xyz, -norm);
 
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
-	gl_TexCoord[1] = gl_TextureMatrix[1]*vec4(ref,1.0);
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+	vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz;
 
 	calcAtmospherics(pos.xyz);
 
-	gl_FrontColor = gl_Color;
-
-	gl_FogFragCoord = pos.z;
+	vertex_color = diffuse_color;
 }
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl
index b540054c56cee2b99c40a3183594abae477d00f3..eff75435a9459409ffa579611fca663c6c942fbb 100644
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl
@@ -22,31 +22,36 @@
  * $/LicenseInfo$
  */
 
+uniform mat4 projection_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
 
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
 
 void calcAtmospherics(vec3 inPositionEye);
 mat4 getObjectSkinnedTransform();
 
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+
 void main()
 {
 	//transform vertex
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 	
 	mat4 mat = getObjectSkinnedTransform();
 	
-	mat = gl_ModelViewMatrix * mat;
-	vec3 pos = (mat*gl_Vertex).xyz;
+	mat = modelview_matrix * mat;
+	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
 	
-	vec4 norm = gl_Vertex;
-	norm.xyz += gl_Normal.xyz;
-	norm.xyz = (mat*norm).xyz;
-	norm.xyz = normalize(norm.xyz-pos.xyz);
-		
 	calcAtmospherics(pos.xyz);
 
-	gl_FrontColor = gl_Color;
+	vertex_color = diffuse_color;
 	
-	gl_Position = gl_ProjectionMatrix*vec4(pos, 1.0);
+	gl_Position = projection_matrix*vec4(pos, 1.0);
 		
-	gl_FogFragCoord = pos.z;
+	
 }
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl
index 22f731ffde021ddd14dbb2d1da8845fe8b151070..fc20d3270e2a349931b972de5e8a1117b9d0597c 100644
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl
@@ -22,22 +22,37 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
+
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
  
+ATTRIBUTE vec3 position;
+void passTextureIndex();
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 diffuse_color;
 
 
 void calcAtmospherics(vec3 inPositionEye);
 
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform();
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+	vec4 vert = vec4(position.xyz,1.0);
+	passTextureIndex();
+	vec4 pos = (modelview_matrix * vert);
+	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 	
-	vec4 pos = (gl_ModelViewMatrix * gl_Vertex);
-
 	calcAtmospherics(pos.xyz);
 
-	gl_FrontColor = gl_Color;
+	vertex_color = diffuse_color;
 
-	gl_FogFragCoord = pos.z;
+	
 }
diff --git a/indra/newview/app_settings/shaders/class1/objects/impostorF.glsl b/indra/newview/app_settings/shaders/class1/objects/impostorF.glsl
index 92c09ce93715ff8b5db62898baabf5792d6f5d80..e7c81888eb7e7fe70711bac9c90aab682b56a5ad 100644
--- a/indra/newview/app_settings/shaders/class1/objects/impostorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/impostorF.glsl
@@ -22,18 +22,21 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform float minimum_alpha;
 uniform float maximum_alpha;
 
-vec3 fullbrightAtmosTransport(vec3 light);
-vec3 fullbrightScaleSoftClip(vec3 light);
-
 uniform sampler2D diffuseMap;
 
+VARYING vec2 vary_texcoord0;
+
 void main()
 {
-	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color;
+	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
 	
 	if (color.a < minimum_alpha || color.a > maximum_alpha)
 	{
diff --git a/indra/newview/app_settings/shaders/class1/objects/impostorV.glsl b/indra/newview/app_settings/shaders/class1/objects/impostorV.glsl
index eea51eba45009973c9e53908529faa8b27e53a5f..e90dbb115a4c8ffc0ab2e7ce142c53cafdf3741e 100644
--- a/indra/newview/app_settings/shaders/class1/objects/impostorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/impostorV.glsl
@@ -22,13 +22,19 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
- 
+
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
+
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec2 vary_texcoord0;
+
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform();
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
-	
-	gl_FrontColor = gl_Color;
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0, 0, 1)).xy;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightMSF.glsl b/indra/newview/app_settings/shaders/class1/objects/indexedTextureF.glsl
similarity index 86%
rename from indra/newview/app_settings/shaders/class1/deferred/sunLightMSF.glsl
rename to indra/newview/app_settings/shaders/class1/objects/indexedTextureF.glsl
index 78ea15e87a9b38ae4b76ce00a52fb7541af45222..254c1d4fc292962a83b592277162ec9ad5127549 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightMSF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/indexedTextureF.glsl
@@ -1,5 +1,5 @@
 /** 
- * @file sunLightF.glsl
+ * @file fullbrightF.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -23,13 +23,11 @@
  * $/LicenseInfo$
  */
  
+ 
 
 
-//class 1, no shadow, no SSAO, should never be called
-
-#extension GL_ARB_texture_rectangle : enable
-
 void main() 
 {
-	gl_FragColor = vec4(0,0,0,0);
+	fullbright_lighting();
 }
+
diff --git a/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl b/indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl
similarity index 83%
rename from indra/newview/app_settings/shaders/class2/effects/simpleF.glsl
rename to indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl
index abf1be6645c7e53075a97477c71c270204926d7e..a95c9e0ab9ef5a04caf22acfcf116a93b37b960d 100644
--- a/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl
@@ -1,5 +1,5 @@
-/**
- * @file simpleF.glsl
+/** 
+ * @file indexedTextureV.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -22,13 +22,13 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+ATTRIBUTE float texture_index;
 
-uniform sampler2DRect RenderTexture;
+VARYING float vary_texture_index;
 
-void main(void) 
+void passTextureIndex()
 {
-	vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st));
-	gl_FragColor = vec4(1.0 - color, 1.0);
+	vary_texture_index = texture_index;
 }
+
diff --git a/indra/newview/app_settings/shaders/class1/objects/nonindexedTextureV.glsl b/indra/newview/app_settings/shaders/class1/objects/nonindexedTextureV.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..80ea286ac04781fe0b96d93ec1b406256a43f60f
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/objects/nonindexedTextureV.glsl
@@ -0,0 +1,31 @@
+/** 
+ * @file nonindexedTextureV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+void passTextureIndex()
+{
+
+}
+
+
diff --git a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..5dcfa87066fc95e4ec36e254e007c6f93f9655ce
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
@@ -0,0 +1,57 @@
+/** 
+ * @file previewV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+void calcAtmospherics(vec3 inPositionEye);
+
+void main()
+{
+	//transform vertex
+	vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0));
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+		
+	vec3 norm = normalize(normal_matrix * normal);
+
+	calcAtmospherics(pos.xyz);
+
+	vec4 color = calcLighting(pos.xyz, norm, vec4(1,1,1,1), vec4(0.));
+	vertex_color = color;
+
+	
+}
diff --git a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl
index f5fd4ededd1a34a4fe4ee5cdb3dbdbd5b350c8b4..591d6fc5c94853c3e4d833085a1e9209139b9ec9 100644
--- a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl
@@ -22,7 +22,19 @@
  * $/LicenseInfo$
  */
 
+uniform mat4 projection_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 texture_matrix1;
+uniform mat4 modelview_matrix;
 
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_texcoord1;
 
 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
 void calcAtmospherics(vec3 inPositionEye);
@@ -32,23 +44,23 @@ void main()
 {
 	mat4 mat = getObjectSkinnedTransform();
 	
-	mat = gl_ModelViewMatrix * mat;
-	vec3 pos = (mat*gl_Vertex).xyz;
+	mat = modelview_matrix * mat;
+	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
 	
-	vec4 norm = gl_Vertex;
-	norm.xyz += gl_Normal.xyz;
+	vec4 norm = vec4(position.xyz, 1.0);
+	norm.xyz += normal.xyz;
 	norm.xyz = (mat*norm).xyz;
 	norm.xyz = normalize(norm.xyz-pos.xyz);
 		
 	vec3 ref = reflect(pos.xyz, -norm.xyz);
 
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
-	gl_TexCoord[1] = gl_TextureMatrix[1]*vec4(ref,1.0);
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+	vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz;
 
 	calcAtmospherics(pos.xyz);
 
-	vec4 color = calcLighting(pos.xyz, norm.xyz, gl_Color, vec4(0.));
-	gl_FrontColor = color;
+	vec4 color = calcLighting(pos.xyz, norm.xyz, diffuse_color, vec4(0.));
+	vertex_color = color;
 	
-	gl_Position = gl_ProjectionMatrix*vec4(pos, 1.0);
+	gl_Position = projection_matrix*vec4(pos, 1.0);
 }
diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl
index 13a58f0d4a0093289cdab78d06186e788cb319a3..fdb3453cc581dafaee3aaa16dfc32ef01da119a9 100644
--- a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl
@@ -1,4 +1,4 @@
-/** 
+/**
  * @file shinyV.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
@@ -22,8 +22,24 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 texture_matrix1;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+void passTextureIndex();
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 diffuse_color;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_texcoord1;
+
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
 
 void calcAtmospherics(vec3 inPositionEye);
 
@@ -32,19 +48,18 @@ uniform vec4 origin;
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform();
-	
-	vec4 pos = (gl_ModelViewMatrix * gl_Vertex);
-	vec3 norm = normalize(gl_NormalMatrix * gl_Normal);
+	vec4 vert = vec4(position.xyz,1.0);
+	passTextureIndex();
+	vec4 pos = (modelview_matrix * vert);
+	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+		
+	vec3 norm = normalize(normal_matrix * normal);
+	vec3 ref = reflect(pos.xyz, -norm);
+
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+	vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz;
 
 	calcAtmospherics(pos.xyz);
-	
-	gl_FrontColor = gl_Color;
-	
-	vec3 ref = reflect(pos.xyz, -norm);
-	
-	gl_TexCoord[0] = gl_TextureMatrix[0]*vec4(ref,1.0);
-	
-	gl_FogFragCoord = pos.z;
-}
 
+	vertex_color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.0));	
+}
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..706627e175696a2a3ad75f66fddb49e1754acf06
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl
@@ -0,0 +1,57 @@
+/** 
+ * @file simpleNoColorV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+void calcAtmospherics(vec3 inPositionEye);
+
+void main()
+{
+	//transform vertex
+	vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0));
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+		
+	vec3 norm = normalize(normal_matrix * normal);
+
+	calcAtmospherics(pos.xyz);
+
+	vec4 color = calcLighting(pos.xyz, norm, vec4(1,1,1,1), vec4(0.));
+	vertex_color = color;
+
+	
+}
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..cb80697d154a7dcb3c8eeef3c51f895e71651a9f
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl
@@ -0,0 +1,61 @@
+/** 
+ * @file simpleNonIndexedV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 diffuse_color;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+void calcAtmospherics(vec3 inPositionEye);
+
+void main()
+{
+	//transform vertex
+	vec4 vert = vec4(position.xyz,1.0);
+	
+	gl_Position = modelview_projection_matrix*vert;
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0, 0, 1)).xy;
+	
+	vec4 pos = (modelview_matrix * vert);
+	
+	vec3 norm = normalize(normal_matrix * normal);
+
+	calcAtmospherics(pos.xyz);
+
+	vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
+	vertex_color = color;
+
+	
+}
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl
index ad171f7b4318234a4240479954d4cd2440ebff58..1c6e53b1879c1a84e6a8b0bf9e12b4476530ed55 100644
--- a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl
@@ -22,6 +22,17 @@
  * $/LicenseInfo$
  */
 
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 
 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
@@ -31,24 +42,24 @@ mat4 getObjectSkinnedTransform();
 void main()
 {
 	//transform vertex
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 	
 	mat4 mat = getObjectSkinnedTransform();
 	
-	mat = gl_ModelViewMatrix * mat;
-	vec3 pos = (mat*gl_Vertex).xyz;
+	mat = modelview_matrix * mat;
+	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
 	
-	vec4 norm = gl_Vertex;
-	norm.xyz += gl_Normal.xyz;
+	vec4 norm = vec4(position.xyz, 1.0);
+	norm.xyz += normal.xyz;
 	norm.xyz = (mat*norm).xyz;
 	norm.xyz = normalize(norm.xyz-pos.xyz);
 		
 	calcAtmospherics(pos.xyz);
 
-	vec4 color = calcLighting(pos.xyz, norm.xyz, gl_Color, vec4(0.));
-	gl_FrontColor = color;
+	vec4 color = calcLighting(pos.xyz, norm.xyz, diffuse_color, vec4(0.));
+	vertex_color = color;
+	
+	gl_Position = projection_matrix*vec4(pos, 1.0);
 	
-	gl_Position = gl_ProjectionMatrix*vec4(pos, 1.0);
 	
-	gl_FogFragCoord = pos.z;
 }
diff --git a/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl
similarity index 60%
rename from indra/newview/app_settings/shaders/class2/environment/terrainV.glsl
rename to indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl
index 36d0c99b63b42539a506548c55024f08dcaace98..d4dee78793eeebd502a4775969d41373f5d1f74e 100644
--- a/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl
@@ -1,5 +1,5 @@
-/**
- * @file terrainV.glsl
+/** 
+ * @file simpleV.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -22,12 +22,26 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
 
-void calcAtmospherics(vec3 inPositionEye);
+ATTRIBUTE vec3 position;
+void passTextureIndex();
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec3 normal;
+
+uniform vec4 color;
+uniform vec4 object_plane_t;
+uniform vec4 object_plane_s;
 
 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+void calcAtmospherics(vec3 inPositionEye);
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 vec4 texgen_object(vec4  vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1)
 {
@@ -46,27 +60,18 @@ vec4 texgen_object(vec4  vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1)
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform();
-
-	vec4 pos = gl_ModelViewMatrix * gl_Vertex;
-	vec3 norm = normalize(gl_NormalMatrix * gl_Normal);
+	vec4 vert = vec4(position.xyz,1.0);
+	passTextureIndex();
+	vec4 pos = (modelview_matrix * vert);
+	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+	vary_texcoord0.xy = texgen_object(vec4(position.xyz, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy;
+		
+	vec3 norm = normalize(normal_matrix * normal);
 
-	/// Potentially better without it for water.
-	pos /= pos.w;
+	calcAtmospherics(pos.xyz);
 
-	calcAtmospherics((gl_ModelViewMatrix * gl_Vertex).xyz);
+	vec4 color = calcLighting(pos.xyz, norm, color, vec4(0.));
+	vertex_color = color;
 
-	vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0));
 	
-	gl_FrontColor = color;
-
-	// Transform and pass tex coords
- 	gl_TexCoord[0].xy = texgen_object(gl_Vertex, gl_MultiTexCoord0, gl_TextureMatrix[0], gl_ObjectPlaneS[0], gl_ObjectPlaneT[0]).xy;
-	
-	vec4 t = gl_MultiTexCoord1;
-	
-	gl_TexCoord[0].zw = t.xy;
-	gl_TexCoord[1].xy = t.xy-vec2(2.0, 0.0);
-	gl_TexCoord[1].zw = t.xy-vec2(1.0, 0.0);
 }
-
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
index dc1794e132ff216b70221940f85bf593d197e06c..37a20383e2c8499eaba3d370b63f7edab9958de9 100644
--- a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
@@ -22,26 +22,43 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+void passTextureIndex();
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 diffuse_color;
 
 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
 void calcAtmospherics(vec3 inPositionEye);
 
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform();
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+	vec4 vert = vec4(position.xyz,1.0);
+	passTextureIndex();
+	vec4 pos = (modelview_matrix * vert);
+	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0, 0, 1)).xy;
+	
 	
-	vec4 pos = (gl_ModelViewMatrix * gl_Vertex);
 	
-	vec3 norm = normalize(gl_NormalMatrix * gl_Normal);
+	vec3 norm = normalize(normal_matrix * normal);
 
 	calcAtmospherics(pos.xyz);
 
-	vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.));
-	gl_FrontColor = color;
+	vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
+	vertex_color = color;
 
-	gl_FogFragCoord = pos.z;
+	
 }
diff --git a/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/treeV.glsl
similarity index 64%
rename from indra/newview/app_settings/shaders/class2/objects/shinyV.glsl
rename to indra/newview/app_settings/shaders/class1/objects/treeV.glsl
index 44c711701bf8890b1b23c475c14b4ab2392d31f4..fa01a27ec0aea2fdc9acfb17536a72617661057e 100644
--- a/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/treeV.glsl
@@ -1,5 +1,5 @@
-/**
- * @file shinyV.glsl
+/** 
+ * @file treeV.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -22,34 +22,39 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
 
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec3 normal;
 
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
 void calcAtmospherics(vec3 inPositionEye);
 
-varying float vary_texture_index;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
-uniform vec4 origin;
 
 void main()
 {
 	//transform vertex
-	vec4 vert = vec4(gl_Vertex.xyz,1.0);
-	vary_texture_index = gl_Vertex.w;
-	gl_Position = gl_ModelViewProjectionMatrix*vert;
+	vec4 vert = vec4(position.xyz,1.0);
 	
-	vec4 pos = (gl_ModelViewMatrix * vert);
-	vec3 norm = normalize(gl_NormalMatrix * gl_Normal);
-	vec3 ref = reflect(pos.xyz, -norm);
-
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
-	gl_TexCoord[1] = gl_TextureMatrix[1]*vec4(ref,1.0);
+	gl_Position = modelview_projection_matrix*vert;
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0, 0, 1)).xy;
+	
+	vec4 pos = (modelview_matrix * vert);
+	
+	vec3 norm = normalize(normal_matrix * normal);
 
 	calcAtmospherics(pos.xyz);
 
-	gl_FrontColor = calcLighting(pos.xyz, norm, gl_Color, vec4(0.0));
+	vec4 color = calcLighting(pos.xyz, norm, vec4(1,1,1,1), vec4(0.));
+	vertex_color = color;
 
-	gl_FogFragCoord = pos.z;
+	
 }
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
index 15738e37e82bb7faeb47e950c3d8bce4b9a7d8f5..89b6a52909a30821f2350156f702feceed2b5e51 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
@@ -23,21 +23,22 @@
  * $/LicenseInfo$
  */
  
-
+uniform vec4 sunlight_color;
+uniform vec4 light_ambient;
 
 vec3 atmosAmbient(vec3 light)
 {
-	return gl_LightModel.ambient.rgb + light;
+	return light + light_ambient.rgb;
 }
 
 vec3 atmosAffectDirectionalLight(float lightIntensity)
 {
-	return gl_LightSource[0].diffuse.rgb * lightIntensity;
+	return sunlight_color.rgb * lightIntensity;
 }
 
 vec3 atmosGetDiffuseSunlightColor()
 {
-	return gl_LightSource[0].diffuse.rgb;
+	return sunlight_color.rgb;
 }
 
 vec3 scaleDownLight(vec3 light)
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
index dbacf286371601d862a7341cff2ccf7c4ab1d209..8bdae328bde8a0c6b79abf657384757a5e9ed0dd 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
@@ -24,10 +24,7 @@
  */
  
 
-
-varying vec3 vary_PositionEye;
-
 vec3 getPositionEye()
 {
-	return vary_PositionEye;
+	return vec3(0,0,0);
 }
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
index e051ac9851eb4270502bf5a3113723f0831fee79..8ec9ae617caf4d97face8cd387d178424575d288 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
@@ -25,15 +25,12 @@
  
 
 
-varying vec3 vary_PositionEye;
-
-
 vec3 getPositionEye()
 {
-	return vary_PositionEye;
+	return vec3(0,0,0);
 }
 
 void setPositionEye(vec3 v)
 {
-	vary_PositionEye = v;
+	
 }
diff --git a/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
similarity index 85%
rename from indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl
rename to indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
index 25806cd91426810d613f5b3c5391b429975882c7..636d4af006f164fba5d97f7471ef97c9394e4843 100644
--- a/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
@@ -1,5 +1,5 @@
-/**
- * @file drawQuadV.glsl
+/** 
+ * @file atmosphericVarsWaterF.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -24,11 +24,10 @@
  */
  
 
+VARYING vec3 vary_PositionEye;
 
-void main(void)
+vec3 getPositionEye()
 {
-	//transform vertex
-	gl_Position = ftransform();
-	gl_TexCoord[0] = gl_MultiTexCoord0;
-	gl_TexCoord[1] = gl_MultiTexCoord1;
+	return vary_PositionEye;
 }
+
diff --git a/indra/newview/app_settings/shaders/class2/deferred/edgeV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
similarity index 80%
rename from indra/newview/app_settings/shaders/class2/deferred/edgeV.glsl
rename to indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
index 9deff7bb2aed71f6719ccde610bd7ae6f394b2c2..ef34c5c85387fba5a8f013ccfb5f34ced408a70c 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/edgeV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
@@ -1,5 +1,5 @@
 /** 
- * @file edgeV.glsl
+ * @file atmosphericVarsWaterV.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -23,15 +23,17 @@
  * $/LicenseInfo$
  */
  
+ 
+VARYING vec3 vary_PositionEye;
+VARYING float fog_depth;
 
+vec3 getPositionEye()
+{
+	return vary_PositionEye;
+}
 
-varying vec2 vary_fragcoord;
-uniform vec2 screen_res;
-
-void main()
+void setPositionEye(vec3 v)
 {
-	//transform vertex
-	gl_Position = ftransform(); 
-	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
-	vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
+	vary_PositionEye = v;
+	fog_depth = v.z;
 }
diff --git a/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl b/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl
index f9f376c2b7308d933f32a08feb5f11dba6fc6ab8..5af9f5c902b3ee23e27cf7c1ad63808644fdbfa2 100644
--- a/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl
+++ b/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl
@@ -22,7 +22,19 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 
 vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol);
@@ -31,20 +43,20 @@ void calcAtmospherics(vec3 inPositionEye);
 void main()
 {
 	//transform vertex
-	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
-	
-	vec3 pos = (gl_ModelViewMatrix * gl_Vertex).xyz;
-	vec3 norm = normalize(gl_NormalMatrix * gl_Normal);
+	vec3 pos = (modelview_matrix * vec4(position.xyz, 1.0)).xyz;
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+		
+	vec3 norm = normalize(normal_matrix * normal);
 
 	calcAtmospherics(pos.xyz);
 	
 	// vec4 specular = specularColor;
 	vec4 specular = vec4(1.0);
-	vec4 color = calcLightingSpecular(pos, norm, gl_Color, specular, vec4(0.0));
+	vec4 color = calcLightingSpecular(pos, norm, diffuse_color, specular, vec4(0.0));
 			
-	gl_FrontColor = color;
-	gl_FogFragCoord = pos.z;
+	vertex_color = color;
+	
 
 }
 
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
index 839606cdcb888aa1bae9d1ea0a9e7b070e64bcf5..8d88e93698f6d390a0c35b9b320eba4966fb12a1 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
@@ -22,11 +22,16 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
-
 
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
 uniform sampler2DRectShadow shadowMap0;
 uniform sampler2DRectShadow shadowMap1;
 uniform sampler2DRectShadow shadowMap2;
@@ -41,11 +46,11 @@ uniform vec2 shadow_res;
 vec3 atmosLighting(vec3 light);
 vec3 scaleSoftClip(vec3 light);
 
-varying vec3 vary_ambient;
-varying vec3 vary_directional;
-varying vec3 vary_fragcoord;
-varying vec3 vary_position;
-varying vec3 vary_pointlight_col;
+VARYING vec3 vary_ambient;
+VARYING vec3 vary_directional;
+VARYING vec3 vary_fragcoord;
+VARYING vec3 vary_position;
+VARYING vec3 vary_pointlight_col;
 
 uniform float shadow_bias;
 
@@ -122,9 +127,9 @@ void main()
 		}
 	}
 	
-	vec4 diff = diffuseLookup(gl_TexCoord[0].xy);
+	vec4 diff = diffuseLookup(vary_texcoord0.xy);
 
-	vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, gl_Color.a);
+	vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, vertex_color.a);
 	vec4 color = diff * col;
 	
 	color.rgb = atmosLighting(color.rgb);
@@ -133,10 +138,6 @@ void main()
 
 	color.rgb += diff.rgb * vary_pointlight_col.rgb;
 
-	//gl_FragColor = gl_Color;
 	gl_FragColor = color;
-	//gl_FragColor.r = 0.0;
-	//gl_FragColor = vec4(1,shadow,1,1);
-	
 }
 
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl
index 84e49a5f8f1c33a5eca72e424822f7ee2a64d13c..0df557f2aad81915a0fe5c17598699732a081663 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl
@@ -23,10 +23,12 @@
  * $/LicenseInfo$
  */
  
-
-
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform sampler2DRectShadow shadowMap0;
 uniform sampler2DRectShadow shadowMap1;
 uniform sampler2DRectShadow shadowMap2;
@@ -42,11 +44,13 @@ uniform vec2 shadow_res;
 vec3 atmosLighting(vec3 light);
 vec3 scaleSoftClip(vec3 light);
 
-varying vec3 vary_ambient;
-varying vec3 vary_directional;
-varying vec3 vary_fragcoord;
-varying vec3 vary_position;
-varying vec3 vary_pointlight_col;
+VARYING vec3 vary_ambient;
+VARYING vec3 vary_directional;
+VARYING vec3 vary_fragcoord;
+VARYING vec3 vary_position;
+VARYING vec3 vary_pointlight_col;
+VARYING vec2 vary_texcoord0;
+VARYING vec4 vertex_color;
 
 uniform float shadow_bias;
 
@@ -123,9 +127,9 @@ void main()
 		}
 	}
 	
-	vec4 diff = texture2D(diffuseMap,gl_TexCoord[0].xy);
+	vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
 
-	vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, gl_Color.a);
+	vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, vertex_color.a);
 	vec4 color = diff * col;
 	
 	color.rgb = atmosLighting(color.rgb);
@@ -134,10 +138,6 @@ void main()
 
 	color.rgb += diff.rgb * vary_pointlight_col.rgb;
 
-	//gl_FragColor = gl_Color;
-	gl_FragColor = color;
-	//gl_FragColor.r = 0.0;
-	//gl_FragColor = vec4(1,shadow,1,1);
-	
+	gl_FragColor = color;	
 }
 
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..331dbc70793868cda044e8dbcf8cb607ed6fc809
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl
@@ -0,0 +1,142 @@
+/** 
+ * @file alphaNonIndexedNoColorF.glsl
+ *
+ * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2005, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+ 
+#extension GL_ARB_texture_rectangle : enable
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
+uniform sampler2DRectShadow shadowMap0;
+uniform sampler2DRectShadow shadowMap1;
+uniform sampler2DRectShadow shadowMap2;
+uniform sampler2DRectShadow shadowMap3;
+uniform sampler2DRect depthMap;
+uniform sampler2D diffuseMap;
+
+uniform mat4 shadow_matrix[6];
+uniform vec4 shadow_clip;
+uniform vec2 screen_res;
+uniform vec2 shadow_res;
+
+vec3 atmosLighting(vec3 light);
+vec3 scaleSoftClip(vec3 light);
+
+VARYING vec3 vary_ambient;
+VARYING vec3 vary_directional;
+VARYING vec3 vary_fragcoord;
+VARYING vec3 vary_position;
+VARYING vec3 vary_pointlight_col;
+VARYING vec2 vary_texcoord0;
+
+uniform float shadow_bias;
+
+uniform mat4 inv_proj;
+
+vec4 getPosition(vec2 pos_screen)
+{
+	float depth = texture2DRect(depthMap, pos_screen.xy).a;
+	vec2 sc = pos_screen.xy*2.0;
+	sc /= screen_res;
+	sc -= vec2(1.0,1.0);
+	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
+	vec4 pos = inv_proj * ndc;
+	pos.xyz /= pos.w;
+	pos.w = 1.0;
+	return pos;
+}
+
+float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl)
+{
+	stc.xyz /= stc.w;
+	stc.z += shadow_bias;
+	
+	float cs = shadow2DRect(shadowMap, stc.xyz).x;
+	float shadow = cs;
+
+	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, scl, 0.0)).x, cs);
+	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, -scl, 0.0)).x, cs);
+	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, scl, 0.0)).x, cs);
+	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, -scl, 0.0)).x, cs);
+			
+	return shadow/5.0;
+}
+
+
+void main() 
+{
+	vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
+	frag *= screen_res;
+	
+	float shadow = 1.0;
+	vec4 pos = vec4(vary_position, 1.0);
+	
+	vec4 spos = pos;
+		
+	if (spos.z > -shadow_clip.w)
+	{	
+		vec4 lpos;
+		
+		if (spos.z < -shadow_clip.z)
+		{
+			lpos = shadow_matrix[3]*spos;
+			lpos.xy *= shadow_res;
+			shadow = pcfShadow(shadowMap3, lpos, 1.5);
+			shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
+		}
+		else if (spos.z < -shadow_clip.y)
+		{
+			lpos = shadow_matrix[2]*spos;
+			lpos.xy *= shadow_res;
+			shadow = pcfShadow(shadowMap2, lpos, 1.5);
+		}
+		else if (spos.z < -shadow_clip.x)
+		{
+			lpos = shadow_matrix[1]*spos;
+			lpos.xy *= shadow_res;
+			shadow = pcfShadow(shadowMap1, lpos, 1.5);
+		}
+		else
+		{
+			lpos = shadow_matrix[0]*spos;
+			lpos.xy *= shadow_res;
+			shadow = pcfShadow(shadowMap0, lpos, 1.5);
+		}
+	}
+	
+	vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
+
+	vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, 1.0);
+	vec4 color = diff * col;
+	
+	color.rgb = atmosLighting(color.rgb);
+
+	color.rgb = scaleSoftClip(color.rgb);
+
+	color.rgb += diff.rgb * vary_pointlight_col.rgb;
+
+	gl_FragColor = color;
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl
index 20121da52d2403eed6b850724ee7f02215c7f248..5a3955ef009da2d95457cb8259afd20db74ae0a3 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl
@@ -21,8 +21,16 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 projection_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+ 
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
 
 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
 void calcAtmospherics(vec3 inPositionEye);
@@ -34,16 +42,25 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);
 vec3 scaleDownLight(vec3 light);
 vec3 scaleUpLight(vec3 light);
 
-varying vec3 vary_ambient;
-varying vec3 vary_directional;
-varying vec3 vary_fragcoord;
-varying vec3 vary_position;
-varying vec3 vary_pointlight_col;
+VARYING vec3 vary_ambient;
+VARYING vec3 vary_directional;
+VARYING vec3 vary_fragcoord;
+VARYING vec3 vary_position;
+VARYING vec3 vary_pointlight_col;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
 
 uniform float near_clip;
 uniform float shadow_offset;
 uniform float shadow_bias;
 
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec3 light_attenuation[8]; 
+uniform vec3 light_diffuse[8];
+
 float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
 {
 	//get light vector
@@ -76,56 +93,56 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
 
 void main()
 {
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 	
 	mat4 mat = getObjectSkinnedTransform();
 	
-	mat = gl_ModelViewMatrix * mat;
+	mat = modelview_matrix * mat;
 	
-	vec3 pos = (mat*gl_Vertex).xyz;
+	vec3 pos = (mat*vec4(position, 1.0)).xyz;
 	
-	gl_Position = gl_ProjectionMatrix * vec4(pos, 1.0);
+	gl_Position = projection_matrix * vec4(pos, 1.0);
 	
-	vec4 n = gl_Vertex;
-	n.xyz += gl_Normal.xyz;
+	vec4 n = vec4(position, 1.0);
+	n.xyz += normal.xyz;
 	n.xyz = (mat*n).xyz;
 	n.xyz = normalize(n.xyz-pos.xyz);
 	
 	vec3 norm = n.xyz;
 	
-	float dp_directional_light = max(0.0, dot(norm, gl_LightSource[0].position.xyz));
-	vary_position = pos.xyz + gl_LightSource[0].position.xyz * (1.0-dp_directional_light)*shadow_offset;
+	float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));
+	vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset;
 			
 	calcAtmospherics(pos.xyz);
 
-	//vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.));
-	vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);
+	//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
+	vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
 
 	// Collect normal lights
-	col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation, gl_LightSource[2].specular.a);
-	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation ,gl_LightSource[3].specular.a);
-	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation, gl_LightSource[4].specular.a);
-	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].quadraticAttenuation, gl_LightSource[5].specular.a);
-	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].quadraticAttenuation, gl_LightSource[6].specular.a);
-	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].quadraticAttenuation, gl_LightSource[7].specular.a);
+	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
+	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
+	col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
+	col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
+	col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
+	col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
 	
-	vary_pointlight_col = col.rgb*gl_Color.rgb;
+	vary_pointlight_col = col.rgb*diffuse_color.rgb;
 
 	col.rgb = vec3(0,0,0);
 
 	// Add windlight lights
 	col.rgb = atmosAmbient(vec3(0.));
 		
-	vary_ambient = col.rgb*gl_Color.rgb;
-	vary_directional.rgb = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a)));
+	vary_ambient = col.rgb*diffuse_color.rgb;
+	vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
 	
-	col.rgb = min(col.rgb*gl_Color.rgb, 1.0);
+	col.rgb = min(col.rgb*diffuse_color.rgb, 1.0);
 	
-	gl_FrontColor = col;
+	vertex_color = col;
 
-	gl_FogFragCoord = pos.z;
 	
-	pos.xyz = (gl_ModelViewProjectionMatrix * gl_Vertex).xyz;
+	
+	pos.xyz = (modelview_projection_matrix * vec4(position.xyz, 1.0)).xyz;
 	vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
 	
 }
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl
index 307ae300987dac18bb6c0c4f90293d8384c2f5a8..9540ddd2e84ef69496d924754fead6e9a7a161cc 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl
@@ -22,8 +22,17 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+void passTextureIndex();
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
 
 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
 void calcAtmospherics(vec3 inPositionEye);
@@ -35,17 +44,25 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);
 vec3 scaleDownLight(vec3 light);
 vec3 scaleUpLight(vec3 light);
 
-varying vec3 vary_ambient;
-varying vec3 vary_directional;
-varying vec3 vary_fragcoord;
-varying vec3 vary_position;
-varying vec3 vary_pointlight_col;
-varying float vary_texture_index;
+VARYING vec3 vary_ambient;
+VARYING vec3 vary_directional;
+VARYING vec3 vary_fragcoord;
+VARYING vec3 vary_position;
+VARYING vec3 vary_pointlight_col;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
 
 uniform float near_clip;
 uniform float shadow_offset;
 uniform float shadow_bias;
 
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec3 light_attenuation[8]; 
+uniform vec3 light_diffuse[8];
+
 float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
 {
 	//get light vector
@@ -79,48 +96,49 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
 void main()
 {
 	//transform vertex
-	vec4 vert = vec4(gl_Vertex.xyz, 1.0);
-	vary_texture_index = gl_Vertex.w;
-	gl_Position = gl_ModelViewProjectionMatrix * vert; 
-	
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+	vec4 vert = vec4(position.xyz, 1.0);
+	passTextureIndex();
+	vec4 pos = (modelview_matrix * vert);
+	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
 	
-	vec4 pos = (gl_ModelViewMatrix * vert);
-	vec3 norm = normalize(gl_NormalMatrix * gl_Normal);
+	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+		
+	vec3 norm = normalize(normal_matrix * normal);
 	
-	float dp_directional_light = max(0.0, dot(norm, gl_LightSource[0].position.xyz));
-	vary_position = pos.xyz + gl_LightSource[0].position.xyz * (1.0-dp_directional_light)*shadow_offset;
+	float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));
+	vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset;
 		
 	calcAtmospherics(pos.xyz);
 
-	//vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.));
-	vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);
+	//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
+	vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
 
-	// Collect normal lights
-	col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation, gl_LightSource[2].specular.a);
-	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation ,gl_LightSource[3].specular.a);
-	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation, gl_LightSource[4].specular.a);
-	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].quadraticAttenuation, gl_LightSource[5].specular.a);
-	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].quadraticAttenuation, gl_LightSource[6].specular.a);
-	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].quadraticAttenuation, gl_LightSource[7].specular.a);
 	
-	vary_pointlight_col = col.rgb*gl_Color.rgb;
+	// Collect normal lights
+	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
+	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
+	col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
+	col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
+	col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
+	col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
+
+	vary_pointlight_col = col.rgb*diffuse_color.rgb;
 
 	col.rgb = vec3(0,0,0);
 
 	// Add windlight lights
 	col.rgb = atmosAmbient(vec3(0.));
 	
-	vary_ambient = col.rgb*gl_Color.rgb;
-	vary_directional.rgb = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a)));
+	vary_ambient = col.rgb*diffuse_color.rgb;
+	vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
 	
-	col.rgb = col.rgb*gl_Color.rgb;
+	col.rgb = col.rgb*diffuse_color.rgb;
 	
-	gl_FrontColor = col;
+	vertex_color = col;
 
-	gl_FogFragCoord = pos.z;
 	
-	pos = gl_ModelViewProjectionMatrix * vert;
+	
+	pos = modelview_projection_matrix * vert;
 	vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
 	
 }
diff --git a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl
index 80f386ecb03a24514c26cbd1f133e6b48b34435d..63c7a6b13d3214562494b99bacb5433e522e7b2c 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl
@@ -23,7 +23,11 @@
  * $/LicenseInfo$
  */
  
+uniform mat4 projection_matrix;
 
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
 
 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
 mat4 getSkinnedTransform();
@@ -37,16 +41,24 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);
 vec3 scaleDownLight(vec3 light);
 vec3 scaleUpLight(vec3 light);
 
-varying vec3 vary_position;
-varying vec3 vary_ambient;
-varying vec3 vary_directional;
-varying vec3 vary_fragcoord;
-varying vec3 vary_pointlight_col;
+VARYING vec3 vary_position;
+VARYING vec3 vary_ambient;
+VARYING vec3 vary_directional;
+VARYING vec3 vary_fragcoord;
+VARYING vec3 vary_pointlight_col;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
 
 uniform float near_clip;
 uniform float shadow_offset;
 uniform float shadow_bias;
 
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec3 light_attenuation[8]; 
+uniform vec3 light_diffuse[8];
+
 float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
 {
 	//get light vector
@@ -79,56 +91,55 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
 
 void main()
 {
-	gl_TexCoord[0] = gl_MultiTexCoord0;
+	vary_texcoord0 = texcoord0;
 				
 	vec4 pos;
 	vec3 norm;
 	
 	mat4 trans = getSkinnedTransform();
-	pos.x = dot(trans[0], gl_Vertex);
-	pos.y = dot(trans[1], gl_Vertex);
-	pos.z = dot(trans[2], gl_Vertex);
+	vec4 pos_in = vec4(position.xyz, 1.0);
+	pos.x = dot(trans[0], pos_in);
+	pos.y = dot(trans[1], pos_in);
+	pos.z = dot(trans[2], pos_in);
 	pos.w = 1.0;
 	
-	norm.x = dot(trans[0].xyz, gl_Normal);
-	norm.y = dot(trans[1].xyz, gl_Normal);
-	norm.z = dot(trans[2].xyz, gl_Normal);
+	norm.x = dot(trans[0].xyz, normal);
+	norm.y = dot(trans[1].xyz, normal);
+	norm.z = dot(trans[2].xyz, normal);
 	norm = normalize(norm);
 		
-	gl_Position = gl_ProjectionMatrix * pos;
+	gl_Position = projection_matrix * pos;
 	
-	float dp_directional_light = max(0.0, dot(norm, gl_LightSource[0].position.xyz));
-	vary_position = pos.xyz + gl_LightSource[0].position.xyz * (1.0-dp_directional_light)*shadow_offset;
+	float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));
+	vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset;
 	
 	calcAtmospherics(pos.xyz);
 
-	//vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.));
-
-	vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);
+	vec4 col = vec4(0.0, 0.0, 0.0, 1.0);
 
 	// Collect normal lights
-	col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation, gl_LightSource[2].specular.a);
-	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation ,gl_LightSource[3].specular.a);
-	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation, gl_LightSource[4].specular.a);
-	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].quadraticAttenuation, gl_LightSource[5].specular.a);
-	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].quadraticAttenuation, gl_LightSource[6].specular.a);
-	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].quadraticAttenuation, gl_LightSource[7].specular.a);
+	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
+	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
+	col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
+	col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
+	col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
+	col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
 	
-	vary_pointlight_col = col.rgb*gl_Color.rgb;
+	vary_pointlight_col = col.rgb;
 
 	col.rgb = vec3(0,0,0);
 
 	// Add windlight lights
 	col.rgb = atmosAmbient(vec3(0.));
 	
-	vary_ambient = col.rgb*gl_Color.rgb;
-	vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a)));
+	vary_ambient = col.rgb;
+	vary_directional = atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), 0.0));
 	
-	col.rgb = min(col.rgb*gl_Color.rgb, 1.0);
+	col.rgb = min(col.rgb, 1.0);
 	
-	gl_FrontColor = col;
+	vertex_color = col;
 
-	gl_FogFragCoord = pos.z;
+	
 	vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
 }
 
diff --git a/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl b/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl
deleted file mode 100644
index d9eafb6ebadaf1188940f7d6da702a89076c8069..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl
+++ /dev/null
@@ -1,81 +0,0 @@
-/** 
- * @file edgeF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-#extension GL_ARB_texture_rectangle : enable
-
-uniform sampler2DRect depthMap;
-uniform sampler2DRect normalMap;
-
-varying vec2 vary_fragcoord;
-
-uniform float depth_cutoff;
-uniform float norm_cutoff;
-
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-float getDepth(vec2 pos_screen)
-{
-	float z = texture2DRect(depthMap, pos_screen.xy).r;
-	z = z*2.0-1.0;
-	vec4 ndc = vec4(0.0, 0.0, z, 1.0);
-	vec4 p = inv_proj*ndc;
-	return p.z/p.w;
-}
-
-void main() 
-{
-	vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz;
-	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
-	float depth = getDepth(vary_fragcoord.xy);
-	
-	vec2 tc = vary_fragcoord.xy;
-	
-	float sc = 0.75;
-	
-	vec2 de;
-	de.x = (depth-getDepth(tc+vec2(sc, sc))) + (depth-getDepth(tc+vec2(-sc, -sc)));
-	de.y = (depth-getDepth(tc+vec2(-sc, sc))) + (depth-getDepth(tc+vec2(sc, -sc)));
-	de /= depth;
-	de *= de;
-	de = step(depth_cutoff, de);
-	
-	vec2 ne;
-	vec3 nexnorm = texture2DRect(normalMap, tc+vec2(-sc,-sc)).rgb;
-	nexnorm = vec3((nexnorm.xy-0.5)*2.0,nexnorm.z); // unpack norm
-	ne.x = dot(nexnorm, norm);
-	vec3 neynorm = texture2DRect(normalMap, tc+vec2(sc,sc)).rgb;
-	neynorm = vec3((neynorm.xy-0.5)*2.0,neynorm.z); // unpack norm
-	ne.y = dot(neynorm, norm);
-	
-	ne = 1.0-ne;
-	
-	ne = step(norm_cutoff, ne);
-	
-	gl_FragColor.a = dot(de,de)+dot(ne,ne);
-	//gl_FragColor.a = dot(de,de);
-}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/edgeMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/edgeMSF.glsl
deleted file mode 100644
index a84fdd5dc139acfc158558c0fc7ba8e19e829ac9..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/edgeMSF.glsl
+++ /dev/null
@@ -1,92 +0,0 @@
-/** 
- * @file edgeF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_texture_multisample : enable
-
-uniform sampler2DMS depthMap;
-uniform sampler2DMS normalMap;
-
-varying vec2 vary_fragcoord;
-
-uniform float depth_cutoff;
-uniform float norm_cutoff;
-
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-float getDepth(ivec2 pos_screen, int sample)
-{
-	float z = texelFetch(depthMap, pos_screen, sample).r;
-	z = z*2.0-1.0;
-	vec4 ndc = vec4(0.0, 0.0, z, 1.0);
-	vec4 p = inv_proj*ndc;
-	return p.z/p.w;
-}
-
-void main() 
-{
-	float e = 0;
-	
-	ivec2 itc = ivec2(vary_fragcoord.xy);
-
-	for (int i = 0; i < samples; i++)
-	{	
-		vec3 norm = texelFetch(normalMap, itc, i).xyz;
-		norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
-		float depth = getDepth(itc, i);
-	
-		vec2 tc = vary_fragcoord.xy;
-	
-		int sc = 1;
-	
-		vec2 de;
-		de.x = (depth-getDepth(itc+ivec2(sc, sc),i)) + (depth-getDepth(itc+ivec2(-sc, -sc), i));
-		de.y = (depth-getDepth(itc+ivec2(-sc, sc),i)) + (depth-getDepth(itc+ivec2(sc, -sc), i));
-		de /= depth;
-		de *= de;
-		de = step(depth_cutoff, de);
-	
-		vec2 ne;
-		vec3 nexnorm = texelFetch(normalMap, itc+ivec2(-sc,-sc), i).rgb;
-		nexnorm = vec3((nexnorm.xy-0.5)*2.0,nexnorm.z); // unpack norm
-		ne.x = dot(nexnorm, norm);
-		vec3 neynorm = texelFetch(normalMap, itc+ivec2(sc,sc), i).rgb;
-		neynorm = vec3((neynorm.xy-0.5)*2.0,neynorm.z); // unpack norm
-		ne.y = dot(neynorm, norm);
-	
-		ne = 1.0-ne;
-	
-		ne = step(norm_cutoff, ne);
-
-		e += dot(de,de)+dot(ne,ne);
-	}
-
-	e /= samples;
-	
-	gl_FragColor.a = e;
-}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
index 0b31cbefd18282b5b63800f66292913f3eb74c8a..14a683971a47792c73403501358d749a5eed07c5 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
@@ -22,11 +22,13 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
-
-
-
+ 
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform sampler2DRect diffuseRect;
 uniform sampler2DRect specularRect;
 uniform sampler2DRect depthMap;
@@ -34,7 +36,6 @@ uniform sampler2DRect normalMap;
 uniform samplerCube environmentMap;
 uniform sampler2DRect lightMap;
 uniform sampler2D noiseMap;
-uniform sampler2D lightFunc;
 uniform sampler2D projectionMap;
 
 uniform mat4 proj_mat; //screen space to light space
@@ -54,9 +55,12 @@ uniform float sun_wash;
 uniform int proj_shadow_idx;
 uniform float shadow_fade;
 
-varying vec4 vary_light;
+uniform vec3 center;
+uniform float size;
+uniform vec3 color;
+uniform float falloff;
 
-varying vec4 vary_fragcoord;
+VARYING vec4 vary_fragcoord;
 uniform vec2 screen_res;
 
 uniform mat4 inv_proj;
@@ -128,9 +132,9 @@ void main()
 	frag.xy *= screen_res;
 	
 	vec3 pos = getPosition(frag.xy).xyz;
-	vec3 lv = vary_light.xyz-pos.xyz;
+	vec3 lv = center.xyz-pos.xyz;
 	float dist2 = dot(lv,lv);
-	dist2 /= vary_light.w;
+	dist2 /= size;
 	if (dist2 > 1.0)
 	{
 		discard;
@@ -161,7 +165,7 @@ void main()
 	
 	proj_tc.xyz /= proj_tc.w;
 	
-	float fa = gl_Color.a+1.0;
+	float fa = falloff+1.0;
 	float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
 	if (dist_atten <= 0.0)
 	{
@@ -193,7 +197,7 @@ void main()
 			
 			vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
 		
-			vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a;
+			vec3 lcol = color.rgb * plcol.rgb * plcol.a;
 			
 			lit = da * dist_atten * noise;
 			
@@ -210,7 +214,7 @@ void main()
 			
 		amb_da = min(amb_da, 1.0-lit);
 			
-		col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
+		col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
 	}
 	
 	
@@ -243,7 +247,7 @@ void main()
 					stc.y > 0.0)
 				{
 					vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
-					col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow;
+					col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb*shadow;
 				}
 			}
 		}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightMSF.glsl
deleted file mode 100644
index 1afa9a9fb40c3cce6972f81e3ec8faaec417eab3..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightMSF.glsl
+++ /dev/null
@@ -1,262 +0,0 @@
-/** 
- * @file multiSpotLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_texture_multisample : enable
-
-uniform sampler2DMS diffuseRect;
-uniform sampler2DMS specularRect;
-uniform sampler2DMS depthMap;
-uniform sampler2DMS normalMap;
-uniform sampler2DRect lightMap;
-uniform sampler2D noiseMap;
-uniform sampler2D lightFunc;
-uniform sampler2D projectionMap;
-
-uniform mat4 proj_mat; //screen space to light space
-uniform float proj_near; //near clip for projection
-uniform vec3 proj_p; //plane projection is emitting from (in screen space)
-uniform vec3 proj_n;
-uniform float proj_focus; //distance from plane to begin blurring
-uniform float proj_lod;  //(number of mips in proj map)
-uniform float proj_range; //range between near clip and far clip plane of projection
-uniform float proj_ambient_lod;
-uniform float proj_ambiance;
-uniform float near_clip;
-uniform float far_clip;
-
-uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
-uniform float sun_wash;
-uniform int proj_shadow_idx;
-uniform float shadow_fade;
-
-varying vec4 vary_light;
-
-varying vec4 vary_fragcoord;
-uniform vec2 screen_res;
-
-uniform mat4 inv_proj;
-
-vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
-{
-	vec4 ret = texture2DLod(projectionMap, tc, lod);
-	
-	vec2 dist = tc-vec2(0.5);
-	
-	float det = max(1.0-lod/(proj_lod*0.5), 0.0);
-	
-	float d = dot(dist,dist);
-		
-	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0);
-	
-	return ret;
-}
-
-vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
-{
-	vec4 ret = texture2DLod(projectionMap, tc, lod);
-	
-	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-	
-	float det = min(lod/(proj_lod*0.5), 1.0);
-	
-	float d = min(dist.x, dist.y);
-	
-	float edge = 0.25*det;
-		
-	ret *= clamp(d/edge, 0.0, 1.0);
-	
-	return ret;
-}
-
-vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
-{
-	vec4 ret = texture2DLod(projectionMap, tc, lod);
-	
-	vec2 dist = tc-vec2(0.5);
-	
-	float d = dot(dist,dist);
-		
-	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
-	
-	return ret;
-}
-
-
-vec4 getPosition(ivec2 pos_screen, int sample)
-{
-	float depth = texelFetch(depthMap, pos_screen, sample).r;
-	vec2 sc = vec2(pos_screen.xy)*2.0;
-	sc /= screen_res;
-	sc -= vec2(1.0,1.0);
-	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
-	vec4 pos = inv_proj * ndc;
-	pos /= pos.w;
-	pos.w = 1.0;
-	return pos;
-}
-
-void main() 
-{
-	int wght = 0;
-
-	vec3 fcol = vec3(0,0,0);
-
-	vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res;
-	
-	ivec2 itc = ivec2(frag.xy);
-
-	float shadow = 1.0;
-
-	if (proj_shadow_idx >= 0)
-	{
-		vec4 shd = texture2DRect(lightMap, frag);
-		float sh[2];
-		sh[0] = shd.b;
-		sh[1] = shd.a;
-		shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
-	}
-		
-	for (int i = 0; i < samples; i++)
-	{
-		vec3 pos = getPosition(itc, i).xyz;
-		vec3 lv = vary_light.xyz-pos.xyz;
-		float dist2 = dot(lv,lv);
-		dist2 /= vary_light.w;
-		if (dist2 <= 1.0)
-		{
-			vec3 norm = texelFetch(normalMap, itc, i).xyz;
-			norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
-	
-			norm = normalize(norm);
-			float l_dist = -dot(lv, proj_n);
-	
-			vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
-			if (proj_tc.z >= 0.0)
-			{
-				proj_tc.xyz /= proj_tc.w;
-	
-				float fa = gl_Color.a+1.0;
-				float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
-				if (dist_atten > 0.0)
-				{
-					lv = proj_origin-pos.xyz;
-					lv = normalize(lv);
-					float da = dot(norm, lv);
-		
-					vec3 col = vec3(0,0,0);
-		
-					vec3 diff_tex = texelFetch(diffuseRect, itc, i).rgb;
-		
-					float noise = texture2D(noiseMap, frag.xy/128.0).b;
-					if (proj_tc.z > 0.0 &&
-						proj_tc.x < 1.0 &&
-						proj_tc.y < 1.0 &&
-						proj_tc.x > 0.0 &&
-						proj_tc.y > 0.0)
-					{
-						float lit = 0.0;
-						float amb_da = proj_ambiance;
-		
-						if (da > 0.0)
-						{
-							float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
-							float lod = diff * proj_lod;
-			
-							vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
-		
-							vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a;
-			
-							lit = da * dist_atten * noise;
-			
-							col = lcol*lit*diff_tex*shadow;
-							amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
-						}
-		
-						//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
-						vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
-							
-						amb_da += (da*da*0.5+0.5)*proj_ambiance;
-				
-						amb_da *= dist_atten * noise;
-			
-						amb_da = min(amb_da, 1.0-lit);
-			
-						col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
-					}
-	
-	
-					vec4 spec = texelFetch(specularRect, itc, i);
-					if (spec.a > 0.0)
-					{
-						vec3 ref = reflect(normalize(pos), norm);
-		
-						//project from point pos in direction ref to plane proj_p, proj_n
-						vec3 pdelta = proj_p-pos;
-						float ds = dot(ref, proj_n);
-		
-						if (ds < 0.0)
-						{
-							vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
-			
-							vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
-
-							if (stc.z > 0.0)
-							{
-								stc.xy /= stc.w;
-
-								float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
-				
-								stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
-								
-								if (stc.x < 1.0 &&
-									stc.y < 1.0 &&
-									stc.x > 0.0 &&
-									stc.y > 0.0)
-								{
-									vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
-									col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow;
-								}
-							}
-						}
-					}
-
-					fcol += col;
-					wght++;
-				}
-			}
-		}
-	}
-	
-	if (wght <= 0)
-	{
-		discard;
-	}
-
-	gl_FragColor.rgb = fcol/samples;	
-	gl_FragColor.a = 0.0;
-}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index d7407332e53f0ebba5b2831be2a65a2c7d09aa11..eb367d4ad6d05b032a380a827b48ef8d9ef41246 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -23,10 +23,12 @@
  * $/LicenseInfo$
  */
  
-
-
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 uniform sampler2DRect diffuseRect;
 uniform sampler2DRect specularRect;
 uniform sampler2DRect normalMap;
@@ -65,8 +67,9 @@ uniform mat3 ssao_effect_mat;
 uniform mat4 inv_proj;
 uniform vec2 screen_res;
 
-varying vec4 vary_light;
-varying vec2 vary_fragcoord;
+uniform vec3 sun_dir;
+
+VARYING vec2 vary_fragcoord;
 
 vec3 vary_PositionEye;
 
@@ -145,10 +148,6 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
 	vec3 P = inPositionEye;
 	setPositionEye(P);
 	
-	//(TERRAIN) limit altitude
-	if (P.y > max_y.x) P *= (max_y.x / P.y);
-	if (P.y < -max_y.x) P *= (-max_y.x / P.y);
-
 	vec3 tmpLightnorm = lightnorm.xyz;
 
 	vec3 Pn = normalize(P);
@@ -282,7 +281,7 @@ void main()
 	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
 	//vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz;
 	
-	float da = max(dot(norm.xyz, vary_light.xyz), 0.0);
+	float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
 	
 	vec4 diffuse = texture2DRect(diffuseRect, tc);
 
@@ -309,8 +308,8 @@ void main()
 			// the old infinite-sky shiny reflection
 			//
 			vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-			float sa = dot(refnormpersp, vary_light.xyz);
-			vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a;
+			float sa = dot(refnormpersp, sun_dir.xyz);
+			vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).r;
 
 			// add the two types of shiny together
 			vec3 spec_contrib = dumbshiny * spec.rgb;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl
deleted file mode 100644
index 12442944514de15c44def731f4a069c21a2661a7..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl
+++ /dev/null
@@ -1,337 +0,0 @@
-/** 
- * @file softenLightMSF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_texture_multisample : enable
-
-uniform sampler2DMS diffuseRect;
-uniform sampler2DMS specularRect;
-uniform sampler2DMS normalMap;
-uniform sampler2DRect lightMap;
-uniform sampler2DMS depthMap;
-uniform sampler2D	  noiseMap;
-uniform samplerCube environmentMap;
-uniform sampler2D	  lightFunc;
-uniform vec3 gi_quad;
-
-uniform float blur_size;
-uniform float blur_fidelity;
-
-// Inputs
-uniform vec4 morphFactor;
-uniform vec3 camPosLocal;
-//uniform vec4 camPosWorld;
-uniform vec4 gamma;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 ambient;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
-uniform vec4 haze_horizon;
-uniform vec4 haze_density;
-uniform vec4 cloud_shadow;
-uniform vec4 density_multiplier;
-uniform vec4 distance_multiplier;
-uniform vec4 max_y;
-uniform vec4 glow;
-uniform float scene_light_strength;
-uniform vec3 env_mat[3];
-uniform vec4 shadow_clip;
-uniform mat3 ssao_effect_mat;
-
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-varying vec4 vary_light;
-varying vec2 vary_fragcoord;
-
-vec3 vary_PositionEye;
-
-vec3 vary_SunlitColor;
-vec3 vary_AmblitColor;
-vec3 vary_AdditiveColor;
-vec3 vary_AtmosAttenuation;
-
-vec4 getPosition_d(vec2 pos_screen, float depth)
-{
-	vec2 sc = pos_screen.xy*2.0;
-	sc /= screen_res;
-	sc -= vec2(1.0,1.0);
-	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
-	vec4 pos = inv_proj * ndc;
-	pos /= pos.w;
-	pos.w = 1.0;
-	return pos;
-}
-
-vec3 getPositionEye()
-{
-	return vary_PositionEye;
-}
-vec3 getSunlitColor()
-{
-	return vary_SunlitColor;
-}
-vec3 getAmblitColor()
-{
-	return vary_AmblitColor;
-}
-vec3 getAdditiveColor()
-{
-	return vary_AdditiveColor;
-}
-vec3 getAtmosAttenuation()
-{
-	return vary_AtmosAttenuation;
-}
-
-
-void setPositionEye(vec3 v)
-{
-	vary_PositionEye = v;
-}
-
-void setSunlitColor(vec3 v)
-{
-	vary_SunlitColor = v;
-}
-
-void setAmblitColor(vec3 v)
-{
-	vary_AmblitColor = v;
-}
-
-void setAdditiveColor(vec3 v)
-{
-	vary_AdditiveColor = v;
-}
-
-void setAtmosAttenuation(vec3 v)
-{
-	vary_AtmosAttenuation = v;
-}
-
-void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
-
-	vec3 P = inPositionEye;
-	setPositionEye(P);
-	
-	//(TERRAIN) limit altitude
-	if (P.y > max_y.x) P *= (max_y.x / P.y);
-	if (P.y < -max_y.x) P *= (-max_y.x / P.y);
-
-	vec3 tmpLightnorm = lightnorm.xyz;
-
-	vec3 Pn = normalize(P);
-	float Plen = length(P);
-
-	vec4 temp1 = vec4(0);
-	vec3 temp2 = vec3(0);
-	vec4 blue_weight;
-	vec4 haze_weight;
-	vec4 sunlight = sunlight_color;
-	vec4 light_atten;
-
-	//sunlight attenuation effect (hue and brightness) due to atmosphere
-	//this is used later for sunlight modulation at various altitudes
-	light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x);
-		//I had thought blue_density and haze_density should have equal weighting,
-		//but attenuation due to haze_density tends to seem too strong
-
-	temp1 = blue_density + vec4(haze_density.r);
-	blue_weight = blue_density / temp1;
-	haze_weight = vec4(haze_density.r) / temp1;
-
-	//(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
-	temp2.y = max(0.0, tmpLightnorm.y);
-	temp2.y = 1. / temp2.y;
-	sunlight *= exp( - light_atten * temp2.y);
-
-	// main atmospheric scattering line integral
-	temp2.z = Plen * density_multiplier.x;
-
-	// Transparency (-> temp1)
-	// ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati
-	// compiler gets confused.
-	temp1 = exp(-temp1 * temp2.z * distance_multiplier.x);
-
-	//final atmosphere attenuation factor
-	setAtmosAttenuation(temp1.rgb);
-	
-	//compute haze glow
-	//(can use temp2.x as temp because we haven't used it yet)
-	temp2.x = dot(Pn, tmpLightnorm.xyz);
-	temp2.x = 1. - temp2.x;
-		//temp2.x is 0 at the sun and increases away from sun
-	temp2.x = max(temp2.x, .03);	//was glow.y
-		//set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
-	temp2.x *= glow.x;
-		//higher glow.x gives dimmer glow (because next step is 1 / "angle")
-	temp2.x = pow(temp2.x, glow.z);
-		//glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
-	//add "minimum anti-solar illumination"
-	temp2.x += .25;
-	
-	//increase ambient when there are more clouds
-	vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5;
-	
-	/*  decrease value and saturation (that in HSV, not HSL) for occluded areas
-	 * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
-	 * // The following line of code performs the equivalent of:
-	 * float ambAlpha = tmpAmbient.a;
-	 * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
-	 * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
-	 * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
-	 */
-	tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
-
-	//haze color
-	setAdditiveColor(
-		vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient)
-	  + (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x
-		  + tmpAmbient)));
-
-	//brightness of surface both sunlight and ambient
-	setSunlitColor(vec3(sunlight * .5));
-	setAmblitColor(vec3(tmpAmbient * .25));
-	setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
-}
-
-vec3 atmosLighting(vec3 light)
-{
-	light *= getAtmosAttenuation().r;
-	light += getAdditiveColor();
-	return (2.0 * light);
-}
-
-vec3 atmosTransport(vec3 light) {
-	light *= getAtmosAttenuation().r;
-	light += getAdditiveColor() * 2.0;
-	return light;
-}
-vec3 atmosGetDiffuseSunlightColor()
-{
-	return getSunlitColor();
-}
-
-vec3 scaleDownLight(vec3 light)
-{
-	return (light / scene_light_strength );
-}
-
-vec3 scaleUpLight(vec3 light)
-{
-	return (light * scene_light_strength);
-}
-
-vec3 atmosAmbient(vec3 light)
-{
-	return getAmblitColor() + light / 2.0;
-}
-
-vec3 atmosAffectDirectionalLight(float lightIntensity)
-{
-	return getSunlitColor() * lightIntensity;
-}
-
-vec3 scaleSoftClip(vec3 light)
-{
-	//soft clip effect:
-	light = 1. - clamp(light, vec3(0.), vec3(1.));
-	light = 1. - pow(light, gamma.xxx);
-
-	return light;
-}
-
-void main() 
-{
-	vec2 tc = vary_fragcoord.xy;
-	ivec2 itc = ivec2(tc);
-
-	vec4 fcol = vec4(0,0,0,0);
-
-	vec2 scol_ambocc = texture2DRect(lightMap, tc).rg;
-	float ambocc = scol_ambocc.g;
-
-	for (int i = 0; i < samples; ++i)
-	{
-		float depth = texelFetch(depthMap, itc.xy, i).r;
-		vec3 pos = getPosition_d(tc, depth).xyz;
-		vec3 norm = texelFetch(normalMap, itc, i).xyz;
-		norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
-			
-		float da = max(dot(norm.xyz, vary_light.xyz), 0.0);
-	
-		vec4 diffuse = texelFetch(diffuseRect, itc, i);
-		vec3 col;
-		float bloom = 0.0;
-		if (diffuse.a < 0.9)
-		{
-			vec4 spec = texelFetch(specularRect, itc, i);
-	
-			float amb = 0;
-
-			float scol = max(scol_ambocc.r, diffuse.a); 
-			amb += ambocc;
-
-			calcAtmospherics(pos.xyz, ambocc);
-	
-			col = atmosAmbient(vec3(0));
-			col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a));
-	
-			col *= diffuse.rgb;
-	
-			if (spec.a > 0.0) // specular reflection
-			{
-				// the old infinite-sky shiny reflection
-				//
-				vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-				float sa = dot(refnormpersp, vary_light.xyz);
-				vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a;
-
-				// add the two types of shiny together
-				vec3 spec_contrib = dumbshiny * spec.rgb;
-				bloom = dot(spec_contrib, spec_contrib);
-				col += spec_contrib;
-			}
-	
-			col = atmosLighting(col);
-			col = scaleSoftClip(col);
-
-			col = mix(col, diffuse.rgb, diffuse.a);
-		}
-		else
-		{
-			col = diffuse.rgb;
-		}
-
-		fcol += vec4(col, bloom);
-	}
-		
-	gl_FragColor = fcol/samples; 
-}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl
index fed238510a0281a7f4b81520f4c81b9a3972fe89..c840d727843a95a9f2049dcf827eccb93d6519f3 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl
@@ -22,23 +22,21 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
 
 uniform vec2 screen_res;
 
-varying vec4 vary_light;
-varying vec2 vary_fragcoord;
+VARYING vec2 vary_fragcoord;
+
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform(); 
+	vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	gl_Position = pos; 
 	
-	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
-	vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
-		
-	vec4 tex = gl_MultiTexCoord0;
-	tex.w = 1.0;
 	
-	vary_light = gl_MultiTexCoord0;
+	vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
 }
diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
index 25270f49392c809a438f506d08bb6eeb2360c827..31bd0c79dab7a1ec5fc04116edaa20ffa8817207 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
@@ -23,9 +23,13 @@
  * $/LicenseInfo$
  */
  
+#extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
-#extension GL_ARB_texture_rectangle : enable
+VARYING vec4 vertex_color;
 
 uniform sampler2DRect diffuseRect;
 uniform sampler2DRect specularRect;
@@ -34,7 +38,6 @@ uniform sampler2DRect normalMap;
 uniform samplerCube environmentMap;
 uniform sampler2DRect lightMap;
 uniform sampler2D noiseMap;
-uniform sampler2D lightFunc;
 uniform sampler2D projectionMap;
 
 uniform mat4 proj_mat; //screen space to light space
@@ -53,9 +56,9 @@ uniform float sun_wash;
 uniform int proj_shadow_idx;
 uniform float shadow_fade;
 
-varying vec4 vary_light;
+VARYING vec4 vary_light;
 
-varying vec4 vary_fragcoord;
+VARYING vec4 vary_fragcoord;
 uniform vec2 screen_res;
 
 uniform mat4 inv_proj;
@@ -114,7 +117,7 @@ void main()
 	
 	proj_tc.xyz /= proj_tc.w;
 	
-	float fa = gl_Color.a+1.0;
+	float fa = vertex_color.a+1.0;
 	float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
 	
 	lv = proj_origin-pos.xyz;
@@ -140,7 +143,7 @@ void main()
 			
 			vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
 		
-			vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a;
+			vec3 lcol = vertex_color.rgb * plcol.rgb * plcol.a;
 			
 			lit = da * dist_atten * noise;
 			
@@ -163,7 +166,7 @@ void main()
 		
 		amb_da = min(amb_da, 1.0-lit);
 		
-		col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
+		col += amb_da*vertex_color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
 	}
 	
 	
@@ -192,7 +195,7 @@ void main()
 					stc.y > 0.0)
 				{
 					vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
-					col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow;
+					col += dist_atten*scol.rgb*vertex_color.rgb*scol.a*spec.rgb*shadow;
 				}
 			}
 		}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl
deleted file mode 100644
index 4962e73e390c3cc6e3b5e2fec2fb550a2da1a350..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl
+++ /dev/null
@@ -1,263 +0,0 @@
-/** 
- * @file multiSpotLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_texture_multisample : enable
-
-uniform sampler2DMS diffuseRect;
-uniform sampler2DMS specularRect;
-uniform sampler2DMS depthMap;
-uniform sampler2DMS normalMap;
-uniform sampler2DRect lightMap;
-uniform sampler2D noiseMap;
-uniform sampler2D lightFunc;
-uniform sampler2D projectionMap;
-
-uniform mat4 proj_mat; //screen space to light space
-uniform float proj_near; //near clip for projection
-uniform vec3 proj_p; //plane projection is emitting from (in screen space)
-uniform vec3 proj_n;
-uniform float proj_focus; //distance from plane to begin blurring
-uniform float proj_lod;  //(number of mips in proj map)
-uniform float proj_range; //range between near clip and far clip plane of projection
-uniform float proj_ambient_lod;
-uniform float proj_ambiance;
-uniform float near_clip;
-uniform float far_clip;
-
-uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
-uniform float sun_wash;
-uniform int proj_shadow_idx;
-uniform float shadow_fade;
-
-varying vec4 vary_light;
-
-varying vec4 vary_fragcoord;
-uniform vec2 screen_res;
-
-uniform mat4 inv_proj;
-
-vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
-{
-	vec4 ret = texture2DLod(projectionMap, tc, lod);
-	
-	vec2 dist = tc-vec2(0.5);
-	
-	float det = max(1.0-lod/(proj_lod*0.5), 0.0);
-	
-	float d = dot(dist,dist);
-		
-	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0);
-	
-	return ret;
-}
-
-vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
-{
-	vec4 ret = texture2DLod(projectionMap, tc, lod);
-	
-	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-	
-	float det = min(lod/(proj_lod*0.5), 1.0);
-	
-	float d = min(dist.x, dist.y);
-	
-	float edge = 0.25*det;
-		
-	ret *= clamp(d/edge, 0.0, 1.0);
-	
-	return ret;
-}
-
-vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
-{
-	vec4 ret = texture2DLod(projectionMap, tc, lod);
-	
-	vec2 dist = tc-vec2(0.5);
-	
-	float d = dot(dist,dist);
-		
-	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
-	
-	return ret;
-}
-
-
-vec4 getPosition(ivec2 pos_screen, int sample)
-{
-	float depth = texelFetch(depthMap, pos_screen, sample).r;
-	vec2 sc = vec2(pos_screen.xy)*2.0;
-	sc /= screen_res;
-	sc -= vec2(1.0,1.0);
-	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
-	vec4 pos = inv_proj * ndc;
-	pos /= pos.w;
-	pos.w = 1.0;
-	return pos;
-}
-
-void main() 
-{
-	vec4 frag = vary_fragcoord;
-	frag.xyz /= frag.w;
-	frag.xyz = frag.xyz*0.5+0.5;
-	frag.xy *= screen_res;
-	ivec2 itc = ivec2(frag.xy);
-	
-	vec3 fcol = vec3(0,0,0);
-	int wght = 0;
-
-	float shadow = 1.0;
-	
-	if (proj_shadow_idx >= 0)
-	{
-		vec4 shd = texture2DRect(lightMap, frag.xy);
-		float sh[2];
-		sh[0] = shd.b;
-		sh[1] = shd.a;
-		shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
-	}
-	
-	for (int i = 0; i < samples; i++)
-	{
-		vec3 pos = getPosition(itc, i).xyz;
-		vec3 lv = vary_light.xyz-pos.xyz;
-		float dist2 = dot(lv,lv);
-		dist2 /= vary_light.w;
-		if (dist2 <= 1.0)
-		{
-			vec3 norm = texelFetch(normalMap, itc, i).xyz;
-			norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
-	
-			norm = normalize(norm);
-			float l_dist = -dot(lv, proj_n);
-	
-			vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
-			if (proj_tc.z >= 0.0)
-			{
-				proj_tc.xyz /= proj_tc.w;
-	
-				float fa = gl_Color.a+1.0;
-				float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
-				if (dist_atten > 0.0)
-				{
-					lv = proj_origin-pos.xyz;
-					lv = normalize(lv);
-					float da = dot(norm, lv);
-		
-					vec3 col = vec3(0,0,0);
-		
-					vec3 diff_tex = texelFetch(diffuseRect, itc, i).rgb;
-		
-					float noise = texture2D(noiseMap, frag.xy/128.0).b;
-					if (proj_tc.z > 0.0 &&
-						proj_tc.x < 1.0 &&
-						proj_tc.y < 1.0 &&
-						proj_tc.x > 0.0 &&
-						proj_tc.y > 0.0)
-					{
-						float lit = 0.0;
-						float amb_da = proj_ambiance;
-		
-						if (da > 0.0)
-						{
-							float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
-							float lod = diff * proj_lod;
-			
-							vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
-		
-							vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a;
-			
-							lit = da * dist_atten * noise;
-			
-							col = lcol*lit*diff_tex*shadow;
-							amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
-						}
-		
-						//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
-						vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
-							
-						amb_da += (da*da*0.5+0.5)*proj_ambiance;
-				
-						amb_da *= dist_atten * noise;
-			
-						amb_da = min(amb_da, 1.0-lit);
-			
-						col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
-					}
-	
-	
-					vec4 spec = texelFetch(specularRect, itc, i);
-					if (spec.a > 0.0)
-					{
-						vec3 ref = reflect(normalize(pos), norm);
-		
-						//project from point pos in direction ref to plane proj_p, proj_n
-						vec3 pdelta = proj_p-pos;
-						float ds = dot(ref, proj_n);
-		
-						if (ds < 0.0)
-						{
-							vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
-			
-							vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
-
-							if (stc.z > 0.0)
-							{
-								stc.xy /= stc.w;
-
-								float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
-				
-								stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
-								
-								if (stc.x < 1.0 &&
-									stc.y < 1.0 &&
-									stc.x > 0.0 &&
-									stc.y > 0.0)
-								{
-									vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
-									col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow;
-								}
-							}
-						}
-					}
-
-					fcol += col;
-					wght++;
-				}
-			}
-		}
-	}
-	
-	if (wght <= 0)
-	{
-		discard;
-	}
-
-	gl_FragColor.rgb = fcol/wght;	
-	gl_FragColor.a = 0.0;
-}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
index 1809cff1e5d32c79a5e492e51e838124dbe46a1b..7e62012b5dafc6feb995371ce5806783321b196f 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
@@ -22,11 +22,13 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
-
 
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 //class 2, shadows, no SSAO
 
 uniform sampler2DRect depthMap;
@@ -47,13 +49,13 @@ uniform float ssao_max_radius;
 uniform float ssao_factor;
 uniform float ssao_factor_inv;
 
-varying vec2 vary_fragcoord;
-varying vec4 vary_light;
+VARYING vec2 vary_fragcoord;
 
 uniform mat4 inv_proj;
 uniform vec2 screen_res;
 uniform vec2 shadow_res;
 uniform vec2 proj_shadow_res;
+uniform vec3 sun_dir;
 
 uniform float shadow_bias;
 uniform float shadow_offset;
@@ -97,15 +99,15 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl)
 	stc.xyz /= stc.w;
 	stc.z += spot_shadow_bias*scl;
 	
-	float cs = shadow2D(shadowMap, stc.xyz).x;
+	float cs = shadow2D(shadowMap, stc.xyz);
 	float shadow = cs;
 
 	vec2 off = 1.5/proj_shadow_res;
 	
-	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs);
-	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs);
-	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs);
-	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs);
+	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)), cs);
+	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)), cs);
+	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)), cs);
+	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)), cs);
 				
 	return shadow/5.0;
 	
@@ -132,10 +134,10 @@ void main()
 	}*/
 	
 	float shadow = 1.0;
-	float dp_directional_light = max(0.0, dot(norm, vary_light.xyz));
+	float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));
 
 	vec3 shadow_pos = pos.xyz + displace*norm;
-	vec3 offset = vary_light.xyz * (1.0-dp_directional_light);
+	vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
 	
 	vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
 	
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightMSF.glsl
deleted file mode 100644
index ac4fe52655993877f94c10244a78f300f4ec41c1..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightMSF.glsl
+++ /dev/null
@@ -1,220 +0,0 @@
-/** 
- * @file sunLightMSF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_texture_multisample : enable
-
-//class 2, shadows, no SSAO
-
-uniform sampler2DMS depthMap;
-uniform sampler2DMS normalMap;
-uniform sampler2DRectShadow shadowMap0;
-uniform sampler2DRectShadow shadowMap1;
-uniform sampler2DRectShadow shadowMap2;
-uniform sampler2DRectShadow shadowMap3;
-uniform sampler2DShadow shadowMap4;
-uniform sampler2DShadow shadowMap5;
-
-
-// Inputs
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-uniform float ssao_radius;
-uniform float ssao_max_radius;
-uniform float ssao_factor;
-uniform float ssao_factor_inv;
-
-varying vec2 vary_fragcoord;
-varying vec4 vary_light;
-
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-uniform vec2 shadow_res;
-uniform vec2 proj_shadow_res;
-
-uniform float shadow_bias;
-uniform float shadow_offset;
-
-uniform float spot_shadow_bias;
-uniform float spot_shadow_offset;
-
-vec4 getPosition(ivec2 pos_screen, int sample)
-{
-	float depth = texelFetch(depthMap, pos_screen.xy, sample).r;
-	vec2 sc = vec2(pos_screen.xy)*2.0;
-	sc /= screen_res;
-	sc -= vec2(1.0,1.0);
-	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
-	vec4 pos = inv_proj * ndc;
-	pos /= pos.w;
-	pos.w = 1.0;
-	return pos;
-}
-
-float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl)
-{
-	stc.xyz /= stc.w;
-	stc.z += shadow_bias*scl;
-	
-	float cs = shadow2DRect(shadowMap, stc.xyz).x;
-	float shadow = cs;
-
-	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, 1.5, 0.0)).x, cs);
-	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, -1.5, 0.0)).x, cs);
-	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, 1.5, 0.0)).x, cs);
-	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, -1.5, 0.0)).x, cs);
-			
-	return shadow/5.0;
-	
-	//return shadow;
-}
-
-float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl)
-{
-	stc.xyz /= stc.w;
-	stc.z += spot_shadow_bias*scl;
-	
-	float cs = shadow2D(shadowMap, stc.xyz).x;
-	float shadow = cs;
-
-	vec2 off = 1.5/proj_shadow_res;
-	
-	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs);
-	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs);
-	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs);
-	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs);
-				
-	return shadow/5.0;
-	
-	//return shadow;
-}
-
-void main() 
-{
-	vec2 pos_screen = vary_fragcoord.xy;
-	ivec2 itc = ivec2(pos_screen);
-
-	//try doing an unproject here
-	
-	vec4 fcol = vec4(0,0,0,0);
-
-	for (int i = 0; i < samples; i++)
-	{
-		vec4 pos = getPosition(itc, i);
-	
-		vec4 nmap4 = texelFetch(normalMap, itc, i);
-		nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm
-		float displace = nmap4.w;
-		vec3 norm = nmap4.xyz;
-	
-		/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL
-		{
-			gl_FragColor = vec4(0.0); // doesn't matter
-			return;
-		}*/
-	
-		float shadow = 1.0;
-		float dp_directional_light = max(0.0, dot(norm, vary_light.xyz));
-
-		vec3 shadow_pos = pos.xyz + displace*norm;
-		vec3 offset = vary_light.xyz * (1.0-dp_directional_light);
-	
-		vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
-	
-		if (spos.z > -shadow_clip.w)
-		{	
-			if (dp_directional_light == 0.0)
-			{
-				// if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup
-				shadow = 0.0;
-			}
-			else
-			{
-				vec4 lpos;
-			
-				if (spos.z < -shadow_clip.z)
-				{
-					lpos = shadow_matrix[3]*spos;
-					lpos.xy *= shadow_res;
-					shadow = pcfShadow(shadowMap3, lpos, 0.25);
-					shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
-				}
-				else if (spos.z < -shadow_clip.y)
-				{
-					lpos = shadow_matrix[2]*spos;
-					lpos.xy *= shadow_res;
-					shadow = pcfShadow(shadowMap2, lpos, 0.5);
-				}
-				else if (spos.z < -shadow_clip.x)
-				{
-					lpos = shadow_matrix[1]*spos;
-					lpos.xy *= shadow_res;
-					shadow = pcfShadow(shadowMap1, lpos, 0.75);
-				}
-				else
-				{
-					lpos = shadow_matrix[0]*spos;
-					lpos.xy *= shadow_res;
-					shadow = pcfShadow(shadowMap0, lpos, 1.0);
-				}
-		
-				// take the most-shadowed value out of these two:
-				//  * the blurred sun shadow in the light (shadow) map
-				//  * an unblurred dot product between the sun and this norm
-				// the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting
-				shadow = min(shadow, dp_directional_light);
-			
-				//lpos.xy /= lpos.w*32.0;
-				//if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1)
-				//{
-				//	shadow = 0.0;
-				//}
-			
-			}
-		}
-		else
-		{
-			// more distant than the shadow map covers
-			shadow = 1.0;
-		}
-	
-		fcol[0] += shadow;
-		fcol[1] += 1.0;
-
-		spos = vec4(shadow_pos+norm*spot_shadow_offset, 1.0);
-	
-		//spotlight shadow 1
-		vec4 lpos = shadow_matrix[4]*spos;
-		fcol[2] += pcfShadow(shadowMap4, lpos, 0.8); 
-	
-		//spotlight shadow 2
-		lpos = shadow_matrix[5]*spos;
-		fcol[3] += pcfShadow(shadowMap5, lpos, 0.8); 
-	}
-
-	gl_FragColor = fcol/samples;
-}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
index 681186d6b2320999f8de1b12943ebbe7d4ebc4a4..025ff481091d2c729d789c1ab1da816ae72cb25e 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
@@ -22,10 +22,12 @@
  * $/LicenseInfo$
  */
  
-
-
 #extension GL_ARB_texture_rectangle : enable
 
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
+
 //class 2 -- shadows and SSAO
 
 uniform sampler2DRect depthMap;
@@ -46,8 +48,8 @@ uniform float ssao_max_radius;
 uniform float ssao_factor;
 uniform float ssao_factor_inv;
 
-varying vec2 vary_fragcoord;
-varying vec4 vary_light;
+VARYING vec2 vary_fragcoord;
+uniform vec3 sun_dir;
 
 uniform mat4 inv_proj;
 uniform vec2 screen_res;
@@ -148,15 +150,15 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl)
 	stc.xyz /= stc.w;
 	stc.z += spot_shadow_bias*scl;
 	
-	float cs = shadow2D(shadowMap, stc.xyz).x;
+	float cs = shadow2D(shadowMap, stc.xyz);
 	float shadow = cs;
 
 	vec2 off = 1.5/proj_shadow_res;
 	
-	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs);
-	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs);
-	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs);
-	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs);
+	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)), cs);
+	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)), cs);
+	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)), cs);
+	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)), cs);
 	
 			
 	return shadow/5.0;
@@ -184,10 +186,10 @@ void main()
 	}*/
 	
 	float shadow = 1.0;
-	float dp_directional_light = max(0.0, dot(norm, vary_light.xyz));
+	float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));
 
 	vec3 shadow_pos = pos.xyz + displace*norm;
-	vec3 offset = vary_light.xyz * (1.0-dp_directional_light);
+	vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
 	
 	vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
 	
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOMSF.glsl
deleted file mode 100644
index 0fd7b7525dc996f0690252ed88ad24c5a89f544b..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOMSF.glsl
+++ /dev/null
@@ -1,258 +0,0 @@
-/** 
- * @file sunLightSSAOF.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_texture_multisample : enable
-
-//class 2 -- shadows and SSAO
-
-uniform sampler2DMS depthMap;
-uniform sampler2DMS normalMap;
-uniform sampler2DRectShadow shadowMap0;
-uniform sampler2DRectShadow shadowMap1;
-uniform sampler2DRectShadow shadowMap2;
-uniform sampler2DRectShadow shadowMap3;
-uniform sampler2DShadow shadowMap4;
-uniform sampler2DShadow shadowMap5;
-uniform sampler2D noiseMap;
-
-// Inputs
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-uniform float ssao_radius;
-uniform float ssao_max_radius;
-uniform float ssao_factor;
-uniform float ssao_factor_inv;
-
-varying vec2 vary_fragcoord;
-varying vec4 vary_light;
-
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-uniform vec2 shadow_res;
-uniform vec2 proj_shadow_res;
-
-uniform float shadow_bias;
-uniform float shadow_offset;
-
-uniform float spot_shadow_bias;
-uniform float spot_shadow_offset;
-
-vec4 getPosition(ivec2 pos_screen, int sample)
-{
-	float depth = texelFetch(depthMap, pos_screen, sample).r;
-	vec2 sc = vec2(pos_screen.xy)*2.0;
-	sc /= screen_res;
-	sc -= vec2(1.0,1.0);
-	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
-	vec4 pos = inv_proj * ndc;
-	pos /= pos.w;
-	pos.w = 1.0;
-	return pos;
-}
-
-//calculate decreases in ambient lighting when crowded out (SSAO)
-float calcAmbientOcclusion(vec4 pos, vec3 norm, int sample)
-{
-	float ret = 1.0;
-
-	vec2 kern[8];
-	// exponentially (^2) distant occlusion samples spread around origin
-	kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
-	kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
-	kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
-	kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
-	kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
-	kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
-	kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
-	kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
-
-	vec2 pos_screen = vary_fragcoord.xy;
-	vec3 pos_world = pos.xyz;
-	vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy;
-		
-	float angle_hidden = 0.0;
-	int points = 0;
-		
-	float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
-		
-	// it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?)
-	for (int i = 0; i < 8; i++)
-	{
-		ivec2 samppos_screen = ivec2(pos_screen + scale * reflect(kern[i], noise_reflect));
-		vec3 samppos_world = getPosition(samppos_screen, sample).xyz; 
-			
-		vec3 diff = pos_world - samppos_world;
-		float dist2 = dot(diff, diff);
-			
-		// assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
-		// --> solid angle shrinking by the square of distance
-		//radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
-		//(k should vary inversely with # of samples, but this is taken care of later)
-			
-		angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv);
-			
-		// 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion" 
-		points = points + int(diff.z > -1.0);
-	}
-		
-	angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0);
-		
-	ret = (1.0 - (float(points != 0) * angle_hidden));
-	
-	return min(ret, 1.0);
-}
-
-float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl)
-{
-	stc.xyz /= stc.w;
-	stc.z += shadow_bias*scl;
-	
-	float cs = shadow2DRect(shadowMap, stc.xyz).x;
-	float shadow = cs;
-
-	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, 1.5, 0.0)).x, cs);
-	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, -1.5, 0.0)).x, cs);
-	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, 1.5, 0.0)).x, cs);
-	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, -1.5, 0.0)).x, cs);
-			
-	return shadow/5.0;
-	
-	//return shadow;
-}
-
-float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl)
-{
-	stc.xyz /= stc.w;
-	stc.z += spot_shadow_bias*scl;
-	
-	float cs = shadow2D(shadowMap, stc.xyz).x;
-	float shadow = cs;
-
-	vec2 off = 1.5/proj_shadow_res;
-	
-	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs);
-	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs);
-	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs);
-	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs);
-	
-			
-	return shadow/5.0;
-	
-	//return shadow;
-}
-
-void main() 
-{
-	vec2 pos_screen = vary_fragcoord.xy;
-	ivec2 itc = ivec2(pos_screen);
-	vec4 fcol = vec4(0,0,0,0);
-
-	for (int i = 0; i < samples; i++)
-	{
-		vec4 pos = getPosition(itc, i);
-	
-		vec4 nmap4 = texelFetch(normalMap, itc, i);
-		nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm
-		float displace = nmap4.w;
-		vec3 norm = nmap4.xyz;
-	
-		float shadow = 1.0;
-		float dp_directional_light = max(0.0, dot(norm, vary_light.xyz));
-
-		vec3 shadow_pos = pos.xyz + displace*norm;
-		vec3 offset = vary_light.xyz * (1.0-dp_directional_light);
-	
-		vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
-	
-		if (spos.z > -shadow_clip.w)
-		{	
-			if (dp_directional_light == 0.0)
-			{
-				// if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup
-				shadow = 0.0;
-			}
-			else
-			{
-				vec4 lpos;
-			
-				if (spos.z < -shadow_clip.z)
-				{
-					lpos = shadow_matrix[3]*spos;
-					lpos.xy *= shadow_res;
-					shadow = pcfShadow(shadowMap3, lpos, 0.25);
-					shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
-				}
-				else if (spos.z < -shadow_clip.y)
-				{
-					lpos = shadow_matrix[2]*spos;
-					lpos.xy *= shadow_res;
-					shadow = pcfShadow(shadowMap2, lpos, 0.5);
-				}
-				else if (spos.z < -shadow_clip.x)
-				{
-					lpos = shadow_matrix[1]*spos;
-					lpos.xy *= shadow_res;
-					shadow = pcfShadow(shadowMap1, lpos, 0.75);
-				}
-				else
-				{
-					lpos = shadow_matrix[0]*spos;
-					lpos.xy *= shadow_res;
-					shadow = pcfShadow(shadowMap0, lpos, 1.0);
-				}
-		
-				// take the most-shadowed value out of these two:
-				//  * the blurred sun shadow in the light (shadow) map
-				//  * an unblurred dot product between the sun and this norm
-				// the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting
-				shadow = min(shadow, dp_directional_light);
-			
-			}
-		}
-		else
-		{
-			// more distant than the shadow map covers
-			shadow = 1.0;
-		}
-	
-		
-		fcol[0] += shadow;
-		fcol[1] += calcAmbientOcclusion(pos, norm, i);
-
-		spos.xyz = shadow_pos+offset*spot_shadow_offset;
-	
-		//spotlight shadow 1
-		vec4 lpos = shadow_matrix[4]*spos;
-		fcol[2] += pcfShadow(shadowMap4, lpos, 0.8); 
-	
-		//spotlight shadow 2
-		lpos = shadow_matrix[5]*spos;
-		fcol[3] += pcfShadow(shadowMap5, lpos, 0.8); 
-	}
-		
-	gl_FragColor = fcol / samples;
-}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl
index e7ab11c6ed2866e939c32c39def4d78d7a430dd6..bc5eb5181d0317864c5982fc27b17366760462e6 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl
@@ -1,5 +1,5 @@
 /** 
- * @file sunLightF.glsl
+ * @file sunLightV.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -22,24 +22,20 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 modelview_projection_matrix;
 
-varying vec4 vary_light;
-varying vec2 vary_fragcoord;
+ATTRIBUTE vec3 position;
+
+VARYING vec2 vary_fragcoord;
 
 uniform vec2 screen_res;
 
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform(); 
-	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
-	vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res;	
-	vec4 tex = gl_MultiTexCoord0;
-	tex.w = 1.0;
+	vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	gl_Position = pos; 
 	
-	vary_light = gl_MultiTexCoord0;
-		
-	gl_FrontColor = gl_Color;
+	vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res;	
 }
diff --git a/indra/newview/app_settings/shaders/class2/effects/blurF.glsl b/indra/newview/app_settings/shaders/class2/effects/blurF.glsl
deleted file mode 100644
index 35411db04b3579202ac5d6d9b1514411beef6126..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/effects/blurF.glsl
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * @file blurf.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-uniform sampler2DRect RenderTexture;
-uniform float bloomStrength;
-
-varying vec4 gl_TexCoord[gl_MaxTextureCoords];
-void main(void) 
-{
-	float blurWeights[7];
-	blurWeights[0] = 0.05;
-	blurWeights[1] = 0.1;
-	blurWeights[2] = 0.2;
-	blurWeights[3] = 0.3;
-	blurWeights[4] = 0.2;
-	blurWeights[5] = 0.1;
-	blurWeights[6] = 0.05;
-	
-	vec3 color = vec3(0,0,0);
-	for (int i = 0; i < 7; i++){
-		color += vec3(texture2DRect(RenderTexture, gl_TexCoord[i].st)) * blurWeights[i];
-	}
-
-	color *= bloomStrength;
-
-	gl_FragColor = vec4(color, 1.0);
-}
diff --git a/indra/newview/app_settings/shaders/class2/effects/blurV.glsl b/indra/newview/app_settings/shaders/class2/effects/blurV.glsl
deleted file mode 100644
index 3e47ed15fe44bc68f2d92ec583c896ee040ab712..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/effects/blurV.glsl
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * @file blurV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-uniform vec2 texelSize;
-uniform vec2 blurDirection;
-uniform float blurWidth;
-
-void main(void)
-{
-	// Transform vertex
-	gl_Position = ftransform();
-	
-	vec2 blurDelta = texelSize * blurDirection * vec2(blurWidth, blurWidth);
-	vec2 s = gl_MultiTexCoord0.st - (blurDelta * 3.0);
-	
-	// for (int i = 0; i < 7; i++) {
-		// gl_TexCoord[i].st = s + (i * blurDelta);
-	// }
-
-	// MANUALLY UNROLL
-	gl_TexCoord[0].st = s;
-	gl_TexCoord[1].st = s + blurDelta;
-	gl_TexCoord[2].st = s + (2. * blurDelta);
-	gl_TexCoord[3].st = s + (3. * blurDelta);
-	gl_TexCoord[4].st = s + (4. * blurDelta);
-	gl_TexCoord[5].st = s + (5. * blurDelta);
-	gl_TexCoord[6].st = s + (6. * blurDelta);
-
-	// gl_TexCoord[0].st = s;
-	// gl_TexCoord[1].st = blurDelta;
-}
diff --git a/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl b/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl
deleted file mode 100644
index 42ab8d40e88529da650c0638566f360a4c27c234..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * @file colorFilterF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-uniform sampler2DRect RenderTexture;
-uniform float brightness;
-uniform float contrast;
-uniform vec3  contrastBase;
-uniform float saturation;
-uniform vec3  lumWeights;
-
-const float gamma = 2.0;
-
-void main(void) 
-{
-	vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st));
-
-	/// Modulate brightness
-	color *= brightness;
-
-	/// Modulate contrast
-	color = mix(contrastBase, color, contrast);
-
-	/// Modulate saturation
-	color = mix(vec3(dot(color, lumWeights)), color, saturation);
-
-	gl_FragColor = vec4(color, 1.0);
-}
diff --git a/indra/newview/app_settings/shaders/class2/effects/extractF.glsl b/indra/newview/app_settings/shaders/class2/effects/extractF.glsl
deleted file mode 100644
index 9187c8ec313aff5f6c033ed1e5b31191263b8896..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/effects/extractF.glsl
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * @file extractF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-uniform sampler2DRect RenderTexture;
-uniform float extractLow;
-uniform float extractHigh;
-uniform vec3 lumWeights;
-
-void main(void) 
-{
-	/// Get scene color
-	vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st));
-	
-	/// Extract luminance and scale up by night vision brightness
-	float lum = smoothstep(extractLow, extractHigh, dot(color, lumWeights));
-
-	gl_FragColor = vec4(vec3(lum), 1.0);
-}
diff --git a/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl b/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl
deleted file mode 100644
index 76b675a9bdfe044f97f9256e1e598111270981cf..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * @file nightVisionF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-uniform sampler2DRect RenderTexture;
-uniform sampler2D NoiseTexture;
-uniform float brightMult;
-uniform float noiseStrength;
-
-float luminance(vec3 color)
-{
-	/// CALCULATING LUMINANCE (Using NTSC lum weights)
-	/// http://en.wikipedia.org/wiki/Luma_%28video%29
-	return dot(color, vec3(0.299, 0.587, 0.114));
-}
-
-void main(void) 
-{
-	/// Get scene color
-	vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st));
-	
-	/// Extract luminance and scale up by night vision brightness
-	float lum = luminance(color) * brightMult;
-
-	/// Convert into night vision color space
-	/// Newer NVG colors (crisper and more saturated)
-	vec3 outColor = (lum * vec3(0.91, 1.21, 0.9)) + vec3(-0.07, 0.1, -0.12); 
-
-	/// Add noise
-	float noiseValue = texture2D(NoiseTexture, gl_TexCoord[1].st).r;
-	noiseValue = (noiseValue - 0.5) * noiseStrength;
-
-	/// Older NVG colors (more muted)
-	// vec3 outColor = (lum * vec3(0.82, 0.75, 0.83)) + vec3(0.05, 0.32, -0.11); 
-	
-	outColor += noiseValue;
-
-	gl_FragColor = vec4(outColor, 1.0);
-}
diff --git a/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl b/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl
deleted file mode 100644
index df08fce0daa5237571c7352a10c6cbf37b4d8ca3..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @file terrainF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-uniform sampler2D detail_0;
-uniform sampler2D detail_1;
-uniform sampler2D detail_2;
-uniform sampler2D detail_3;
-uniform sampler2D alpha_ramp;
-
-vec3 atmosLighting(vec3 light);
-
-vec3 scaleSoftClip(vec3 color);
-
-void main()
-{
-	/// Note: This should duplicate the blending functionality currently used for the terrain rendering.
-	
-	/// TODO Confirm tex coords and bind them appropriately in vert shader.
-	vec4 color0 = texture2D(detail_0, gl_TexCoord[0].xy);
-	vec4 color1 = texture2D(detail_1, gl_TexCoord[0].xy);
-	vec4 color2 = texture2D(detail_2, gl_TexCoord[0].xy);
-	vec4 color3 = texture2D(detail_3, gl_TexCoord[0].xy);
-
-	float alpha1 = texture2D(alpha_ramp, gl_TexCoord[0].zw).a;
-	float alpha2 = texture2D(alpha_ramp,gl_TexCoord[1].xy).a;
-	float alphaFinal = texture2D(alpha_ramp, gl_TexCoord[1].zw).a;
-	vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal );
-	
-	/// Add WL Components
-	outColor.rgb = atmosLighting(outColor.rgb * gl_Color.rgb);
-	
-	gl_FragColor = vec4(scaleSoftClip(outColor.rgb), 1.0);
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl b/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl
deleted file mode 100644
index 90468b45a227c2f5e09cc23c2b8c7cecabae695f..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * @file terrainWaterF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-uniform sampler2D detail_0;
-uniform sampler2D detail_1;
-uniform sampler2D detail_2;
-uniform sampler2D detail_3;
-uniform sampler2D alpha_ramp;
-
-vec3 atmosLighting(vec3 light);
-
-vec4 applyWaterFog(vec4 color);
-
-void main()
-{
-	/// Note: This should duplicate the blending functionality currently used for the terrain rendering.
-	
-	/// TODO Confirm tex coords and bind them appropriately in vert shader.
-	vec4 color0 = texture2D(detail_0, gl_TexCoord[0].xy);
-	vec4 color1 = texture2D(detail_1, gl_TexCoord[0].xy);
-	vec4 color2 = texture2D(detail_2, gl_TexCoord[0].xy);
-	vec4 color3 = texture2D(detail_3, gl_TexCoord[0].xy);
-
-	float alpha1 = texture2D(alpha_ramp, gl_TexCoord[0].zw).a;
-	float alpha2 = texture2D(alpha_ramp,gl_TexCoord[1].xy).a;
-	float alphaFinal = texture2D(alpha_ramp, gl_TexCoord[1].zw).a;
-	vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal );
-	
-	/// Add WL Components
-	outColor.rgb = atmosLighting(outColor.rgb * gl_Color.rgb);
-	
-	outColor = applyWaterFog(outColor);
-	gl_FragColor = outColor;
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl
deleted file mode 100644
index f947aa4be10120774213c6db507607f377158ca0..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * @file underWaterF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-uniform sampler2D diffuseMap;
-uniform sampler2D bumpMap;   
-uniform sampler2D screenTex;
-uniform sampler2D refTex;
-uniform sampler2D screenDepth;
-
-uniform vec4 fogCol;
-uniform vec3 lightDir;
-uniform vec3 specular;
-uniform float lightExp;
-uniform vec2 fbScale;
-uniform float refScale;
-uniform float znear;
-uniform float zfar;
-uniform float kd;
-uniform vec4 waterPlane;
-uniform vec3 eyeVec;
-uniform vec4 waterFogColor;
-uniform float waterFogDensity;
-uniform float waterFogKS;
-uniform vec2 screenRes;
-
-//bigWave is (refCoord.w, view.w);
-varying vec4 refCoord;
-varying vec4 littleWave;
-varying vec4 view;
-
-vec4 applyWaterFog(vec4 color, vec3 viewVec)
-{
-	//normalize view vector
-	vec3 view = normalize(viewVec);
-	float es = -view.z;
-
-	//find intersection point with water plane and eye vector
-	
-	//get eye depth
-	float e0 = max(-waterPlane.w, 0.0);
-	
-	//get object depth
-	float depth = length(viewVec);
-		
-	//get "thickness" of water
-	float l = max(depth, 0.1);
-
-	float kd = waterFogDensity;
-	float ks = waterFogKS;
-	vec4 kc = waterFogColor;
-	
-	float F = 0.98;
-	
-	float t1 = -kd * pow(F, ks * e0);
-	float t2 = kd + ks * es;
-	float t3 = pow(F, t2*l) - 1.0;
-	
-	float L = min(t1/t2*t3, 1.0);
-	
-	float D = pow(0.98, l*kd);
-	//return vec4(1.0, 0.0, 1.0, 1.0);
-	return color * D + kc * L;
-	//depth /= 10.0;
-	//return vec4(depth,depth,depth,0.0);
-}
-
-void main() 
-{
-	vec4 color;
-	    
-	//get detail normals
-	vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
-	vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
-	vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;    
-	vec3 wavef = normalize(wave1+wave2+wave3);
-	
-	//figure out distortion vector (ripply)   
-	vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
-	distort = distort+wavef.xy*refScale;
-		
-	vec4 fb = texture2D(screenTex, distort);
-	
-	gl_FragColor = applyWaterFog(fb,view.xyz);
-}
diff --git a/indra/newview/app_settings/shaders/class2/environment/waterF.glsl b/indra/newview/app_settings/shaders/class2/environment/waterF.glsl
deleted file mode 100644
index dc543b2231a13ddc95b02c357916ed4ef2b5d0ea..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/environment/waterF.glsl
+++ /dev/null
@@ -1,137 +0,0 @@
-/** 
- * @file waterF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-vec3 scaleSoftClip(vec3 inColor);
-vec3 atmosTransport(vec3 inColor);
-
-uniform sampler2D bumpMap;   
-uniform sampler2D screenTex;
-uniform sampler2D refTex;
-
-uniform float sunAngle;
-uniform float sunAngle2;
-uniform vec3 lightDir;
-uniform vec3 specular;
-uniform float lightExp;
-uniform float refScale;
-uniform float kd;
-uniform vec2 screenRes;
-uniform vec3 normScale;
-uniform float fresnelScale;
-uniform float fresnelOffset;
-uniform float blurMultiplier;
-
-
-//bigWave is (refCoord.w, view.w);
-varying vec4 refCoord;
-varying vec4 littleWave;
-varying vec4 view;
-
-void main() 
-{
-	vec4 color;
-	
-	float dist = length(view.xy);
-	
-	//normalize view vector
-	vec3 viewVec = normalize(view.xyz);
-	
-	//get wave normals
-	vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
-	vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
-	vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
-	//get base fresnel components	
-	
-	vec3 df = vec3(
-					dot(viewVec, wave1),
-					dot(viewVec, (wave2 + wave3) * 0.5),
-					dot(viewVec, wave3)
-				 ) * fresnelScale + fresnelOffset;
-	df *= df;
-		    
-	vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
-	
-	float dist2 = dist;
-	dist = max(dist, 5.0);
-	
-	float dmod = sqrt(dist);
-	
-	vec2 dmod_scale = vec2(dmod*dmod, dmod);
-	
-	//get reflected color
-	vec2 refdistort1 = wave1.xy*normScale.x;
-	vec2 refvec1 = distort+refdistort1/dmod_scale;
-	vec4 refcol1 = texture2D(refTex, refvec1);
-	
-	vec2 refdistort2 = wave2.xy*normScale.y;
-	vec2 refvec2 = distort+refdistort2/dmod_scale;
-	vec4 refcol2 = texture2D(refTex, refvec2);
-	
-	vec2 refdistort3 = wave3.xy*normScale.z;
-	vec2 refvec3 = distort+refdistort3/dmod_scale;
-	vec4 refcol3 = texture2D(refTex, refvec3);
-
-	vec4 refcol = refcol1 + refcol2 + refcol3;
-	float df1 = df.x + df.y + df.z;
-	refcol *= df1 * 0.333;
-	
-	vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
-	
-	wavef.z *= max(-viewVec.z, 0.1);
-	wavef = normalize(wavef);
-	
-	float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
-	
-	vec2 refdistort4 = wavef.xy*0.125;
-	refdistort4.y -= abs(refdistort4.y);
-	vec2 refvec4 = distort+refdistort4/dmod;
-	float dweight = min(dist2*blurMultiplier, 1.0);
-	vec4 baseCol = texture2D(refTex, refvec4);
-	refcol = mix(baseCol*df2, refcol, dweight);
-
-	//get specular component
-	float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
-		
-	//harden specular
-	spec = pow(spec, 128.0);
-
-	//figure out distortion vector (ripply)   
-	vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
-		
-	vec4 fb = texture2D(screenTex, distort2);
-	
-	//mix with reflection
-	// Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug
-	color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
-	color.rgb += spec * specular;
-	
-	color.rgb = atmosTransport(color.rgb);
-	color.rgb = scaleSoftClip(color.rgb);
-	color.a = spec * sunAngle2;
-
-	gl_FragColor = color;
-}
diff --git a/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl
deleted file mode 100644
index 4bdfce9260c77145dcb244b561d87ce1a4230ea7..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * @file waterFogF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-uniform vec4 lightnorm;
-uniform vec4 waterPlane;
-uniform vec4 waterFogColor;
-uniform float waterFogDensity;
-uniform float waterFogKS;
-
-vec3 getPositionEye();
-
-vec4 applyWaterFog(vec4 color)
-{
-	//normalize view vector
-	vec3 view = normalize(getPositionEye());
-	float es = -(dot(view, waterPlane.xyz));
-
-	//find intersection point with water plane and eye vector
-	
-	//get eye depth
-	float e0 = max(-waterPlane.w, 0.0);
-	
-	vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
-	
-	//get object depth
-	float depth = length(getPositionEye() - int_v);
-		
-	//get "thickness" of water
-	float l = max(depth, 0.1);
-
-	float kd = waterFogDensity;
-	float ks = waterFogKS;
-	vec4 kc = waterFogColor;
-	
-	float F = 0.98;
-	
-	float t1 = -kd * pow(F, ks * e0);
-	float t2 = kd + ks * es;
-	float t3 = pow(F, t2*l) - 1.0;
-	
-	float L = min(t1/t2*t3, 1.0);
-	
-	float D = pow(0.98, l*kd);
-	
-	color.rgb = color.rgb * D + kc.rgb * L;
-	color.a = kc.a + color.a;
-	
-	return color;
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl
deleted file mode 100644
index d2bc912edb2ae3887e3b8ab2cc0095d73305a8a6..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl
+++ /dev/null
@@ -1,49 +0,0 @@
-/** 
- * @file lightFullbrightShinyF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-uniform samplerCube environmentMap;
-
-vec3 fullbrightShinyAtmosTransport(vec3 light);
-vec3 fullbrightScaleSoftClip(vec3 light);
-
-void fullbright_shiny_lighting()
-{
-	vec4 color = diffuseLookup(gl_TexCoord[0].xy);
-	color.rgb *= gl_Color.rgb;
-	
-	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	
-	color.rgb = mix(color.rgb, envColor.rgb, gl_Color.a);
-
-	color.rgb = fullbrightShinyAtmosTransport(color.rgb);
-
-	color.rgb = fullbrightScaleSoftClip(color.rgb);
-
-	color.a = max(color.a, gl_Color.a);
-
-	gl_FragColor = color;
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl
deleted file mode 100644
index e9dab85095886b93d820be8b98cdc220e462f879..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl
+++ /dev/null
@@ -1,48 +0,0 @@
-/** 
- * @file lightFullbrightShinyWaterF.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-
-uniform samplerCube environmentMap;
-
-vec3 fullbrightShinyAtmosTransport(vec3 light);
-vec3 fullbrightScaleSoftClip(vec3 light);
-vec4 applyWaterFog(vec4 color);
-
-void fullbright_shiny_lighting_water()
-{
-	vec4 color = diffuseLookup(gl_TexCoord[0].xy);
-	color.rgb *= gl_Color.rgb;
-	
-	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	
-	color.rgb = mix(color.rgb, envColor.rgb, gl_Color.a);
-
-	color.rgb = fullbrightShinyAtmosTransport(color.rgb);
-	color.rgb = fullbrightScaleSoftClip(color.rgb);
-	color.a = max(color.a, gl_Color.a);
-
-	gl_FragColor = applyWaterFog(color);
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl
deleted file mode 100644
index 20ff3712af52e86c29023eb303ee16e794d1722a..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl
+++ /dev/null
@@ -1,41 +0,0 @@
-/** 
- * @file lightFullbrightWaterF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-vec4 diffuseLookup(vec2 texcoord);
-
-vec3 fullbrightAtmosTransport(vec3 light);
-vec4 applyWaterFog(vec4 color);
-
-void fullbright_lighting_water()
-{
-	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;
-
-	color.rgb = fullbrightAtmosTransport(color.rgb);
-	
-	gl_FragColor = applyWaterFog(color);
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl
deleted file mode 100644
index ba4cd949d6ab0d7c59e438c9248161de57fc4b69..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl
+++ /dev/null
@@ -1,49 +0,0 @@
-/** 
- * @file lightShinyF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-
-uniform samplerCube environmentMap;
-
-vec3 scaleSoftClip(vec3 light);
-vec3 atmosLighting(vec3 light);
-vec4 applyWaterFog(vec4 color);
-
-void shiny_lighting()
-{
-	vec4 color = diffuseLookup(gl_TexCoord[0].xy);
-	color.rgb *= gl_Color.rgb;
-	
-	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	
-	color.rgb = mix(color.rgb, envColor.rgb, gl_Color.a);
-
-	color.rgb = atmosLighting(color.rgb);
-
-	color.rgb = scaleSoftClip(color.rgb);
-	color.a = max(color.a, gl_Color.a);
-	gl_FragColor = color;
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl
deleted file mode 100644
index c451e68763c7c2191519de27714fb45566063ccc..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl
+++ /dev/null
@@ -1,46 +0,0 @@
-/** 
- * @file lightShinyWaterF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-
-uniform samplerCube environmentMap;
-
-vec3 atmosLighting(vec3 light);
-vec4 applyWaterFog(vec4 color);
-
-void shiny_lighting_water()
-{
-	vec4 color = diffuseLookup(gl_TexCoord[0].xy);
-	color.rgb *= gl_Color.rgb;
-	
-	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	
-	color.rgb = mix(color.rgb, envColor.rgb, gl_Color.a);
-
-	color.rgb = atmosLighting(color.rgb);
-	color.a = max(color.a, gl_Color.a);
-	gl_FragColor = applyWaterFog(color);
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl
deleted file mode 100644
index 24bf9b3cee5168a8cfc7928b545eddc39e8a9736..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl
+++ /dev/null
@@ -1,36 +0,0 @@
-/** 
- * @file lightSpecularV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-// All lights, no specular highlights
-
-vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol);
-
-vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol)
-{
-	return sumLightsSpecular(pos, norm, color, specularColor, baseCol);
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl
deleted file mode 100644
index 8045809b82c6cc6e18b4fdfeefa9ec26ed35c706..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl
+++ /dev/null
@@ -1,36 +0,0 @@
-/** 
- * @file lightV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-// All lights, no specular highlights
-
-vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight);
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseLight)
-{
-	return sumLights(pos, norm, color, baseLight);
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl
deleted file mode 100644
index ae7be4d231d6a1823e24f04b67c1d61be99bdb23..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl
+++ /dev/null
@@ -1,39 +0,0 @@
-/** 
- * @file lightWaterF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-vec3 atmosLighting(vec3 light);
-vec4 applyWaterFog(vec4 color);
-
-void default_lighting_water()
-{
-	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;
-
-	color.rgb = atmosLighting(color.rgb);
-
-	gl_FragColor = applyWaterFog(color);
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl
index d0a12479db3343b85ace9ab7d6a58b4946682a34..3acf9fe883fa0644defbe7c297c0e44304faef11 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl
+++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl
@@ -33,6 +33,10 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);
 vec3 atmosGetDiffuseSunlightColor();
 vec3 scaleDownLight(vec3 light);
 
+uniform vec4 light_position[8];
+uniform vec3 light_attenuation[8]; 
+uniform vec3 light_diffuse[8];
+
 vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol)
 {
 	vec4 col = vec4(0.0, 0.0, 0.0, color.a);
@@ -43,15 +47,14 @@ vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor
 	vec4 specularSum = vec4(0.0);
 	
 	// Collect normal lights (need to be divided by two, as we later multiply by 2)
-	col.rgb += gl_LightSource[1].diffuse.rgb * calcDirectionalLightSpecular(specularColor, view, norm, gl_LightSource[1].position.xyz, gl_LightSource[1].diffuse.rgb, 1.0);
-	col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, gl_LightSource[2].position.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation, gl_LightSource[2].diffuse.rgb);
-	col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, gl_LightSource[3].position.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation, gl_LightSource[3].diffuse.rgb);
-	//col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, gl_LightSource[4].position.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation, gl_LightSource[4].diffuse.rgb);
+	col.rgb += light_diffuse[1].rgb * calcDirectionalLightSpecular(specularColor, view, norm, light_position[1].xyz,light_diffuse[1].rgb, 1.0);
+	col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, light_position[2].xyz, light_attenuation[2].x, light_attenuation[2].y, light_diffuse[2].rgb); 
+	col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, light_position[3].xyz, light_attenuation[3].x, light_attenuation[3].y, light_diffuse[3].rgb); 
 	col.rgb = scaleDownLight(col.rgb);
 						
 	// Add windlight lights
 	col.rgb += atmosAmbient(baseCol.rgb);
-	col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, gl_LightSource[0].position.xyz, atmosGetDiffuseSunlightColor()*baseCol.a, 1.0));
+	col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, light_position[0].xyz,atmosGetDiffuseSunlightColor()*baseCol.a, 1.0));
 
 	col.rgb = min(col.rgb*color.rgb, 1.0);
 	specularColor.rgb = min(specularColor.rgb*specularSum.rgb, 1.0);
diff --git a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
index ad045a305805a167564caea00f536cffaaa33ef2..c9987ef3b946e5f317ec5cc5a42bab1e28410f1f 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
@@ -23,8 +23,6 @@
  * $/LicenseInfo$
  */
  
-
-
 float calcDirectionalLight(vec3 n, vec3 l);
 float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
 
@@ -32,21 +30,26 @@ vec3 atmosAmbient(vec3 light);
 vec3 atmosAffectDirectionalLight(float lightIntensity);
 vec3 scaleDownLight(vec3 light);
 
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec3 light_attenuation[8]; 
+uniform vec3 light_diffuse[8];
+
 vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight)
 {
 	vec4 col = vec4(0.0, 0.0, 0.0, color.a);
 	
 	// Collect normal lights (need to be divided by two, as we later multiply by 2)
-	col.rgb += gl_LightSource[1].diffuse.rgb * calcDirectionalLight(norm, gl_LightSource[1].position.xyz);
+	col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
+
+	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
+	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
 
-	col.rgb += gl_LightSource[2].diffuse.rgb * calcPointLightOrSpotLight(pos, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a);
-	col.rgb += gl_LightSource[3].diffuse.rgb * calcPointLightOrSpotLight(pos, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a);
-	//col.rgb += gl_LightSource[4].diffuse.rgb * calcPointLightOrSpotLight(pos, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a);
 	col.rgb = scaleDownLight(col.rgb);
 
 	// Add windlight lights
 	col.rgb += atmosAmbient(baseLight.rgb);
-	col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, gl_LightSource[0].position.xyz));
+	col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, light_position[0].xyz));
 				
 	col.rgb = min(col.rgb*color.rgb, 1.0);
 	
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
index be990c17579b617e8d2916eefff19590775e46f2..6a83be1426d8337aa6469e8bc57c17ad7e35141b 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
@@ -25,7 +25,7 @@
  
 
 
-// varying param funcs
+// VARYING param funcs
 void setSunlitColor(vec3 v);
 void setAmblitColor(vec3 v);
 void setAdditiveColor(vec3 v);
@@ -34,8 +34,8 @@ void setPositionEye(vec3 v);
 
 vec3 getAdditiveColor();
 
-//varying vec4 vary_CloudUVs;
-//varying float vary_CloudDensity;
+//VARYING vec4 vary_CloudUVs;
+//VARYING float vary_CloudDensity;
 
 // Inputs
 uniform vec4 morphFactor;
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl
index a98c04b25932a8137fe0dd59c4bbad55234679d3..e8e56e12c1b9a36d47f3bada95d4d90d9a6528ff 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl
@@ -24,25 +24,17 @@
  */
  
 
+VARYING vec3 vary_SunlitColor;
+VARYING vec3 vary_AdditiveColor;
+VARYING float vary_AtmosAttenuation;
 
-varying vec3 vary_PositionEye;
-
-varying vec3 vary_SunlitColor;
-varying vec3 vary_AmblitColor;
-varying vec3 vary_AdditiveColor;
-varying vec3 vary_AtmosAttenuation;
-
-vec3 getPositionEye()
-{
-	return vary_PositionEye;
-}
 vec3 getSunlitColor()
 {
-	return vary_SunlitColor;
+	return vec3(0,0,0);
 }
 vec3 getAmblitColor()
 {
-	return vary_AmblitColor;
+	return vec3(0,0,0);
 }
 vec3 getAdditiveColor()
 {
@@ -50,5 +42,5 @@ vec3 getAdditiveColor()
 }
 vec3 getAtmosAttenuation()
 {
-	return vary_AtmosAttenuation;
+	return vec3(vary_AtmosAttenuation);
 }
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl
index 7c3cb88b3ce73900075b3fa93cea44e7ef34da33..01605e5b251510fffa20a39c1813ec61579a8794 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl
@@ -24,49 +24,50 @@
  */
  
 
+VARYING vec3 vary_AdditiveColor;
+VARYING float vary_AtmosAttenuation;
 
-varying vec3 vary_PositionEye;
+vec3 atmos_attenuation;
+vec3 sunlit_color;
+vec3 amblit_color;
+vec3 position_eye;
 
-varying vec3 vary_SunlitColor;
-varying vec3 vary_AmblitColor;
-varying vec3 vary_AdditiveColor;
-varying vec3 vary_AtmosAttenuation;
-
-vec3 getPositionEye()
-{
-	return vary_PositionEye;
-}
 vec3 getSunlitColor()
 {
-	return vary_SunlitColor;
+	return sunlit_color;
 }
 vec3 getAmblitColor()
 {
-	return vary_AmblitColor;
+	return amblit_color;
 }
+
 vec3 getAdditiveColor()
 {
 	return vary_AdditiveColor;
 }
 vec3 getAtmosAttenuation()
 {
-	return vary_AtmosAttenuation;
+	return atmos_attenuation;
 }
 
+vec3 getPositionEye()
+{
+	return position_eye;
+}
 
 void setPositionEye(vec3 v)
 {
-	vary_PositionEye = v;
+	position_eye = v;
 }
 
 void setSunlitColor(vec3 v)
 {
-	vary_SunlitColor = v;
+	sunlit_color  = v;
 }
 
 void setAmblitColor(vec3 v)
 {
-	vary_AmblitColor = v;
+	amblit_color = v;
 }
 
 void setAdditiveColor(vec3 v)
@@ -76,5 +77,6 @@ void setAdditiveColor(vec3 v)
 
 void setAtmosAttenuation(vec3 v)
 {
-	vary_AtmosAttenuation = v;
+	atmos_attenuation = v;
+	vary_AtmosAttenuation = v.r;
 }
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl
similarity index 68%
rename from indra/newview/app_settings/shaders/class2/lighting/lightF.glsl
rename to indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl
index d12d88f1c5cc9e1a58b0724aa00d8ea9f11a6c06..23046f990dabd585b0a4f1d17f2bc01d551073d5 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl
@@ -1,5 +1,5 @@
 /** 
- * @file lightF.glsl
+ * @file atmosphericVarsWaterF.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -23,19 +23,29 @@
  * $/LicenseInfo$
  */
  
+VARYING vec3 vary_PositionEye;
+VARYING vec3 vary_SunlitColor;
+VARYING vec3 vary_AdditiveColor;
+VARYING float vary_AtmosAttenuation;
 
-
-vec3 atmosLighting(vec3 light);
-vec3 scaleSoftClip(vec3 light);
-
-void default_lighting() 
+vec3 getSunlitColor()
 {
-	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;
-	
-	color.rgb = atmosLighting(color.rgb);
-
-	color.rgb = scaleSoftClip(color.rgb);
-
-	gl_FragColor = color;
+	return vec3(0,0,0);
+}
+vec3 getAmblitColor()
+{
+	return vec3(0,0,0);
+}
+vec3 getAdditiveColor()
+{
+	return vary_AdditiveColor;
+}
+vec3 getAtmosAttenuation()
+{
+	return vec3(vary_AtmosAttenuation);
+}
+vec3 getPositionEye()
+{
+	return vary_PositionEye;
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFMSF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl
similarity index 55%
rename from indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFMSF.glsl
rename to indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl
index 41849858e7d9ec2f447b619a6c9923faec1b6c6e..279c4dd981528f6aecb4e5da88ceef26b23290ac 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFMSF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl
@@ -1,5 +1,5 @@
 /** 
- * @file postDeferredF.glsl
+ * @file atmosphericVarsWaterV.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -23,33 +23,59 @@
  * $/LicenseInfo$
  */
  
+VARYING vec3 vary_PositionEye;
+VARYING vec3 vary_AdditiveColor;
+VARYING float vary_AtmosAttenuation;
 
+vec3 atmos_attenuation;
+vec3 sunlit_color;
+vec3 amblit_color;
 
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_texture_multisample : enable
+vec3 getSunlitColor()
+{
+	return sunlit_color;
+}
+vec3 getAmblitColor()
+{
+	return amblit_color;
+}
 
-uniform sampler2DMS diffuseRect;
-uniform sampler2D bloomMap;
+vec3 getAdditiveColor()
+{
+	return vary_AdditiveColor;
+}
+vec3 getAtmosAttenuation()
+{
+	return atmos_attenuation;
+}
 
-uniform vec2 screen_res;
-varying vec2 vary_fragcoord;
+vec3 getPositionEye()
+{
+	return vary_PositionEye;
+}
 
-vec4 texture2DMS(sampler2DMS tex, ivec2 tc)
+void setPositionEye(vec3 v)
 {
-	vec4 ret = vec4(0,0,0,0);
+	vary_PositionEye = v;
+}
 
-	for (int i = 0; i < samples; ++i)
-	{
-		 ret += texelFetch(tex,tc,i);
-	}
+void setSunlitColor(vec3 v)
+{
+	sunlit_color  = v;
+}
 
-	return ret/samples;
+void setAmblitColor(vec3 v)
+{
+	amblit_color = v;
 }
 
-void main() 
+void setAdditiveColor(vec3 v)
 {
-	vec4 diff = texture2DMS(diffuseRect, ivec2(vary_fragcoord.xy));
+	vary_AdditiveColor = v;
+}
 
-	vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res);
-	gl_FragColor = diff + bloom;
+void setAtmosAttenuation(vec3 v)
+{
+	atmos_attenuation = v;
+	vary_AtmosAttenuation = v.r;
 }
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
index b90cec119b73f72f108efd8cc62efbf958c4522c..4ab06c6e21fbc0bea8c90e85591f50f4882e5db5 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
@@ -23,15 +23,21 @@
  * $/LicenseInfo$
  */
  
-
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
 /////////////////////////////////////////////////////////////////////////
 // The fragment shader for the sky
 /////////////////////////////////////////////////////////////////////////
 
-varying vec4 vary_CloudColorSun;
-varying vec4 vary_CloudColorAmbient;
-varying float vary_CloudDensity;
+VARYING vec4 vary_CloudColorSun;
+VARYING vec4 vary_CloudColorAmbient;
+VARYING float vary_CloudDensity;
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
+VARYING vec2 vary_texcoord3;
 
 uniform sampler2D cloud_noise_texture;
 uniform vec4 cloud_pos_density1;
@@ -50,14 +56,14 @@ vec3 scaleSoftClip(vec3 light) {
 void main()
 {
 	// Set variables
-	vec2 uv1 = gl_TexCoord[0].xy;
-	vec2 uv2 = gl_TexCoord[1].xy;
+	vec2 uv1 = vary_texcoord0.xy;
+	vec2 uv2 = vary_texcoord1.xy;
 
 	vec4 cloudColorSun = vary_CloudColorSun;
 	vec4 cloudColorAmbient = vary_CloudColorAmbient;
 	float cloudDensity = vary_CloudDensity;
-	vec2 uv3 = gl_TexCoord[2].xy;
-	vec2 uv4 = gl_TexCoord[3].xy;
+	vec2 uv3 = vary_texcoord2.xy;
+	vec2 uv4 = vary_texcoord3.xy;
 
 	// Offset texture coords
 	uv1 += cloud_pos_density1.xy;	//large texture, visible density
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
index c175a834c23386c0e5c866fdf0aaf57efd74b078..c5bb52169cc7110e04ba90e9ccd4ffbb2d7abe71 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
@@ -22,17 +22,24 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
 
 //////////////////////////////////////////////////////////////////////////
 // The vertex shader for creating the atmospheric sky
 ///////////////////////////////////////////////////////////////////////////////
 
 // Output parameters
-varying vec4 vary_CloudColorSun;
-varying vec4 vary_CloudColorAmbient;
-varying float vary_CloudDensity;
+VARYING vec4 vary_CloudColorSun;
+VARYING vec4 vary_CloudColorAmbient;
+VARYING float vary_CloudDensity;
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
+VARYING vec2 vary_texcoord3;
 
 // Inputs
 uniform vec3 camPosLocal;
@@ -59,12 +66,12 @@ void main()
 {
 
 	// World / view / projection
-	gl_Position = ftransform();
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
 
-	gl_TexCoord[0] = gl_MultiTexCoord0;
+	vary_texcoord0 = texcoord0;
 
 	// Get relative position
-	vec3 P = gl_Vertex.xyz - camPosLocal.xyz + vec3(0,50,0);
+	vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0);
 
 	// Set altitude
 	if (P.y > 0.)
@@ -160,17 +167,17 @@ void main()
 
 
 	// Texture coords
-	gl_TexCoord[0] = gl_MultiTexCoord0;
-	gl_TexCoord[0].xy -= 0.5;
-	gl_TexCoord[0].xy /= cloud_scale.x;
-	gl_TexCoord[0].xy += 0.5;
+	vary_texcoord0 = texcoord0;
+	vary_texcoord0.xy -= 0.5;
+	vary_texcoord0.xy /= cloud_scale.x;
+	vary_texcoord0.xy += 0.5;
 
-	gl_TexCoord[1] = gl_TexCoord[0];
-	gl_TexCoord[1].x += lightnorm.x * 0.0125;
-	gl_TexCoord[1].y += lightnorm.z * 0.0125;
+	vary_texcoord1 = vary_texcoord0;
+	vary_texcoord1.x += lightnorm.x * 0.0125;
+	vary_texcoord1.y += lightnorm.z * 0.0125;
 
-	gl_TexCoord[2] = gl_TexCoord[0] * 16.;
-	gl_TexCoord[3] = gl_TexCoord[1] * 16.;
+	vary_texcoord2 = vary_texcoord0 * 16.;
+	vary_texcoord3 = vary_texcoord1 * 16.;
 
 	// Combine these to minimize register use
 	vary_CloudColorAmbient += oHazeColorBelowCloud;
diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
index ac569e8257864da5b0bef882a73329c8deacb08a..c9d96b2cf4624f167a7c7bf5b62636b973207eb6 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
@@ -23,13 +23,15 @@
  * $/LicenseInfo$
  */
  
-
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 gl_FragColor;
+#endif
 
 /////////////////////////////////////////////////////////////////////////
 // The fragment shader for the sky
 /////////////////////////////////////////////////////////////////////////
 
-varying vec4 vary_HazeColor;
+VARYING vec4 vary_HazeColor;
 
 uniform sampler2D cloud_noise_texture;
 uniform vec4 gamma;
diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
index 3a44bb6d261af16a1a9fc5f87539a66c9edc32ea..b768cc9cf364008a43d6e5f1b084276746ed467a 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
@@ -23,14 +23,18 @@
  * $/LicenseInfo$
  */
  
+uniform mat4 modelview_projection_matrix;
 
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
 
 // SKY ////////////////////////////////////////////////////////////////////////
 // The vertex shader for creating the atmospheric sky
 ///////////////////////////////////////////////////////////////////////////////
 
 // Output parameters
-varying vec4 vary_HazeColor;
+VARYING vec4 vary_HazeColor;
+VARYING vec2 vary_texcoord0;
 
 // Inputs
 uniform vec3 camPosLocal;
@@ -57,12 +61,12 @@ void main()
 {
 
 	// World / view / projection
-	gl_Position = ftransform();
-	gl_TexCoord[0] = gl_MultiTexCoord0;
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	vary_texcoord0 = texcoord0;
 
 	// Get relative position
-	vec3 P = gl_Vertex.xyz - camPosLocal.xyz + vec3(0,50,0);
-	//vec3 P = gl_Vertex.xyz + vec3(0,50,0);
+	vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0);
+	//vec3 P = position.xyz + vec3(0,50,0);
 
 	// Set altitude
 	if (P.y > 0.)
diff --git a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl b/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
index 151602dbc089d06f0dfdaf048033aac3460dd023..7fb3cb65529660348e9fdb289df73ef744c5106a 100644
--- a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
+++ b/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
@@ -22,39 +22,45 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform mat4 projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec4 clothing; 
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
 
 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
 mat4 getSkinnedTransform();
 void calcAtmospherics(vec3 inPositionEye);
 
-attribute vec4 clothing; //4
-
-attribute vec4 gWindDir;		//7
-attribute vec4 gSinWaveParams; //3
-attribute vec4 gGravity;		//5
+uniform vec4 gWindDir;		
+uniform vec4 gSinWaveParams; 
+uniform vec4 gGravity;		
 
 const vec4 gMinMaxConstants = vec4(1.0, 0.166666, 0.0083143, .00018542);	 // #minimax-generated coefficients
 const vec4 gPiConstants	= vec4(0.159154943, 6.28318530, 3.141592653, 1.5707963); //	# {1/2PI, 2PI, PI, PI/2}
 
 void main()
 {
-	gl_TexCoord[0] = gl_MultiTexCoord0;
+	vary_texcoord0 = texcoord0;
 		
 	vec4 pos;
 	mat4 trans = getSkinnedTransform();
 		
 	vec3 norm;
-	norm.x = dot(trans[0].xyz, gl_Normal);
-	norm.y = dot(trans[1].xyz, gl_Normal);
-	norm.z = dot(trans[2].xyz, gl_Normal);
+	norm.x = dot(trans[0].xyz, normal);
+	norm.y = dot(trans[1].xyz, normal);
+	norm.z = dot(trans[2].xyz, normal);
 	norm = normalize(norm);
 		
 	//wind
 	vec4 windEffect;
 	windEffect = vec4(dot(norm, gWindDir.xyz));	
-	pos.x = dot(trans[2].xyz, gl_Vertex.xyz);
+	pos.x = dot(trans[2].xyz, position.xyz);
 	windEffect.xyz = pos.x * vec3(0.015, 0.015, 0.015)
 						+ windEffect.xyz;
 	windEffect.w = windEffect.w * 2.0 + 1.0;				// move wind offset value to [-1, 3]
@@ -101,7 +107,7 @@ void main()
 	sinWave.xyz = max(sinWave.xyz, vec3(-1.0, -1.0, -1.0));	// clamp to underlying body shape
 	offsetPos = clothing * sinWave.x;						// multiply wind effect times clothing displacement
 	temp2 = gWindDir*sinWave.z + vec4(norm,0);				// calculate normal offset due to wind oscillation
-	offsetPos = vec4(1.0,1.0,1.0,0.0)*offsetPos+gl_Vertex;	// add to offset vertex position, and zero out effect from w
+	offsetPos = vec4(1.0,1.0,1.0,0.0)*offsetPos+vec4(position.xyz, 1.0);	// add to offset vertex position, and zero out effect from w
 	norm += temp2.xyz*2.0;									// add sin wave effect on normals (exaggerated)
 	
 	//add "backlighting" effect
@@ -119,12 +125,8 @@ void main()
 
 	calcAtmospherics(pos.xyz);
 	
-	vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.0));			
-	gl_FrontColor = color; 
+	vec4 color = calcLighting(pos.xyz, norm, vec4(1,1,1,1), vec4(0.0));			
+	vertex_color = color; 
 					
-	gl_Position = gl_ProjectionMatrix * pos;
-	
-	
-	gl_TexCoord[2] = vec4(pos.xyz, 1.0);
-
+	gl_Position = projection_matrix * pos;
 }
diff --git a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl
deleted file mode 100644
index 616ea5fe9e7fd06d0ada66c17a511223be2cd049..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl
+++ /dev/null
@@ -1,106 +0,0 @@
-/** 
- * @file giDownsampleF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-uniform sampler2DRect giLightMap;
-
-uniform vec2 kern[32];
-uniform float dist_factor;
-uniform float blur_size;
-uniform vec2 delta;
-uniform int kern_length;
-uniform float kern_scale;
-uniform vec3 blur_quad;
-
-varying vec2 vary_fragcoord;
-
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-vec4 getPosition(vec2 pos_screen)
-{
-	float depth = texture2DRect(depthMap, pos_screen.xy).a;
-	vec2 sc = pos_screen.xy*2.0;
-	sc /= screen_res;
-	sc -= vec2(1.0,1.0);
-	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
-	vec4 pos = inv_proj * ndc;
-	pos /= pos.w;
-	pos.w = 1.0;
-	return pos;
-}
-
-float getDepth(vec2 pos_screen)
-{
-	float z = texture2DRect(depthMap, pos_screen.xy).a;
-	z = z*2.0-1.0;
-	vec4 ndc = vec4(0.0, 0.0, z, 1.0);
-	vec4 p = inv_proj*ndc;
-	return p.z/p.w;
-}
-
-void main() 
-{
-	vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz;
-	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
-	float depth = getDepth(vary_fragcoord.xy);
-		
-	vec3 ccol = texture2DRect(giLightMap, vary_fragcoord.xy).rgb;
-	vec2 dlt = kern_scale * delta/(vec2(1.0,1.0)+norm.xy*norm.xy);
-	dlt /= clamp(-depth*blur_quad.x, 1.0, 3.0);
-	float defined_weight = kern[0].x;
-	vec3 col = ccol*kern[0].x;
-	
-	for (int i = 0; i < kern_length; i++)
-	{
-		vec2 tc = vary_fragcoord.xy + kern[i].y*dlt;
-		vec3 sampNorm = texture2DRect(normalMap, tc.xy).xyz;
-		sampNorm = vec3((sampNorm.xy-0.5)*2.0,sampNorm.z); // unpack norm
-		
-		float d = dot(norm.xyz, sampNorm);
-		
-		if (d > 0.5)
-		{
-			float sampdepth = getDepth(tc.xy);
-			sampdepth -= depth;
-			if (sampdepth*sampdepth < blur_quad.z)
-			{
-	    		col += texture2DRect(giLightMap, tc).rgb*kern[i].x;
-				defined_weight += kern[i].x;
-			}
-		}
-	}
-
-	col /= defined_weight;
-	
-	//col = ccol;
-	
-	col = col*blur_quad.y;
-	
-	gl_FragData[0].xyz = col;
-	
-	//gl_FragColor = ccol;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/giF.glsl b/indra/newview/app_settings/shaders/class3/deferred/giF.glsl
deleted file mode 100644
index 95913a502c4a852e3fc9ee7d1e3a18dad108cfd0..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/giF.glsl
+++ /dev/null
@@ -1,211 +0,0 @@
-/** 
- * @file giF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-#extension GL_ARB_texture_rectangle : enable
-
-uniform sampler2DRect depthMap;
-uniform sampler2DRect normalMap;
-uniform sampler2DRect lightMap;
-uniform sampler2DRect specularRect;
-
-uniform sampler2D noiseMap;
-
-uniform sampler2D		diffuseGIMap;
-uniform sampler2D		specularGIMap;
-uniform sampler2D		normalGIMap;
-uniform sampler2D		depthGIMap;
-
-uniform sampler2D		lightFunc;
-
-// Inputs
-varying vec2 vary_fragcoord;
-
-uniform vec2 screen_res;
-
-uniform vec4 sunlight_color;
-
-uniform mat4 inv_proj;
-uniform mat4 gi_mat;  //gPipeline.mGIMatrix - eye space to sun space
-uniform mat4 gi_mat_proj; //gPipeline.mGIMatrixProj - eye space to projected sun space
-uniform mat4 gi_norm_mat; //gPipeline.mGINormalMatrix - eye space normal to sun space normal matrix
-uniform mat4 gi_inv_proj; //gPipeline.mGIInvProj - projected sun space to sun space
-uniform float gi_sample_width;
-uniform float gi_noise;
-uniform float gi_attenuation;
-uniform float gi_range;
-
-vec4 getPosition(vec2 pos_screen)
-{
-	float depth = texture2DRect(depthMap, pos_screen.xy).a;
-	vec2 sc = pos_screen.xy*2.0;
-	sc /= screen_res;
-	sc -= vec2(1.0,1.0);
-	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
-	vec4 pos = inv_proj * ndc;
-	pos /= pos.w;
-	pos.w = 1.0;
-	return pos;
-}
-
-vec4 getGIPosition(vec2 gi_tc)
-{
-	float depth = texture2D(depthGIMap, gi_tc).a;
-	vec2 sc = gi_tc*2.0;
-	sc -= vec2(1.0, 1.0);
-	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
-	vec4 pos = gi_inv_proj*ndc;
-	pos.xyz /= pos.w;
-	pos.w = 1.0;
-	return pos;
-}
-
-vec3 giAmbient(vec3 pos, vec3 norm)
-{
-	vec4 gi_c = gi_mat_proj * vec4(pos, 1.0);
-	gi_c.xyz /= gi_c.w;
-
-	vec4 gi_pos = gi_mat*vec4(pos,1.0);
-	vec3 gi_norm = (gi_norm_mat*vec4(norm,1.0)).xyz;
-	gi_norm = normalize(gi_norm);
-	
-	vec4 c_spec = texture2DRect(specularRect, vary_fragcoord.xy);
-	vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).rgb;
-	gi_pos.xyz += nz.x*gi_noise*gi_norm.xyz;
-	vec2 tcx = gi_norm.xy;
-	vec2 tcy = gi_norm.yx;
-	
-	vec4 eye_pos = gi_mat*vec4(0,0,0,1.0);
-	
-	vec3 eye_dir = normalize(gi_pos.xyz-eye_pos.xyz);
-	vec3 eye_ref = reflect(eye_dir, gi_norm);
-	
-	float da = 0.0; //texture2DRect(lightMap, vary_fragcoord.xy).r*0.5;
-	vec3 fdiff = vec3(da);
-	float fda = da;
-	
-	vec3 rcol = vec3(0,0,0);
-	
-	float fsa = 0.0;
-	
-
-	for (int i = -1; i <= 1; i += 2 )
-	{
-		for (int j = -1; j <= 1; j+= 2)
-		{
-			vec2 tc = vec2(i, j)*0.75+gi_norm.xy*nz.z;
-			tc += nz.xy*2.0;
-			tc *= gi_sample_width*0.25;
-			tc += gi_c.xy;
-			
-			vec3 lnorm = -(texture2D(normalGIMap, tc.xy).xyz*2.0-1.0);
-			vec3 lpos = getGIPosition(tc.xy).xyz;
-							
-			vec3 at = lpos-gi_pos.xyz;
-			float dist = length(at);
-			float dist_atten = clamp(1.0/(gi_attenuation*dist), 0.0, 1.0);
-			
-						
-			if (dist_atten > 0.01)
-			{ //possible contribution of indirect light to this surface
-				vec3 ldir = at;
-				
-				float ld = -dot(ldir, lnorm);
-				
-				if (ld < 0.0)
-				{  					
-					float ang_atten = dot(ldir, gi_norm);
-				
-					if (ang_atten > 0.0)
-					{  
-						vec4 spec = texture2D(specularGIMap, tc.xy);
-						at = normalize(at);
-						vec3 diff;		
-						
-						float da = 0.0;
-												
-						//contribution from indirect source to visible pixel
-						vec3 ha = at;
-						ha.z -= 1.0;
-						ha = normalize(ha);
-						if (spec.a > 0.0)
-						{
-							float sa = dot(ha,lnorm);
-							da = texture2D(lightFunc, vec2(sa, spec.a)).a;
-						}
-						else
-						{
-							da = -lnorm.z;
-						}
-						
-						diff = texture2D(diffuseGIMap, tc.xy).rgb+spec.rgb*spec.a*2.0;
-												
-						if (da > 0.0)
-						{ //contribution from visible pixel to eye
-							vec3 ha = normalize(at-eye_dir);
-							if (c_spec.a > 0.0)
-							{
-								float sa = dot(ha, gi_norm);
-								da = dist_atten*texture2D(lightFunc, vec2(sa, c_spec.a)).a;
-							}
-							else
-							{
-								da = dist_atten*dot(gi_norm, normalize(ldir));
-							}
-							fda += da;
-							fdiff += da*(c_spec.rgb*c_spec.a*2.0+vec3(1,1,1))*diff.rgb;
-						}
-					}
-				}
-			}
-		}
-	}
-
-	fdiff *= sunlight_color.rgb;
-	
-	vec3 ret = fda*fdiff;
-	
-	return clamp(ret,vec3(0.0), vec3(1.0));
-}
-
-void main() 
-{
-	vec2 pos_screen = vary_fragcoord.xy;
-	vec4 pos = getPosition(pos_screen);
-	
-	float rad = gi_range*0.5;
-	
-	vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
-	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
-	float dist = max(length(pos.xyz)-rad, 0.0);
-	
-	float da = clamp(1.0-dist/rad, 0.0, 1.0);
-	
-	vec3 ambient = da > 0.0 ? giAmbient(pos.xyz, norm) : vec3(0);
-	
-		
-	gl_FragData[0].xyz = mix(vec3(0), ambient, da);
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl
deleted file mode 100644
index 0364da62584166af21506f656fa85caf28cdc9e1..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl
+++ /dev/null
@@ -1,100 +0,0 @@
-/** 
- * @file postDeferredF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-  
-
-
-#extension GL_ARB_texture_rectangle : enable
-
-uniform sampler2DRect diffuseRect;
-uniform sampler2DRect specularRect;
-
-uniform sampler2DRect localLightMap;
-uniform sampler2DRect sunLightMap;
-uniform sampler2DRect giLightMap;
-uniform sampler2DRect edgeMap;
-
-uniform sampler2D	  luminanceMap;
-
-uniform sampler2DRect lightMap;
-
-uniform sampler2D	  lightFunc;
-uniform sampler2D	  noiseMap;
-
-uniform float sun_lum_scale;
-uniform float sun_lum_offset;
-uniform float lum_scale;
-uniform float lum_lod;
-uniform vec4 ambient;
-uniform float gi_brightness;
-uniform float gi_luminance;
-
-uniform vec4 sunlight_color;
-
-uniform vec2 screen_res;
-varying vec2 vary_fragcoord;
-
-void main() 
-{
-	vec2 tc = vary_fragcoord.xy;
-	vec4 lcol = texture2DLod(luminanceMap, vec2(0.5, 0.5), lum_lod);
-	
-	vec3 gi_col = texture2DRect(giLightMap, vary_fragcoord.xy).rgb;
-	vec4 sun_col =	texture2DRect(sunLightMap, vary_fragcoord.xy);
-	vec3 local_col = texture2DRect(localLightMap, vary_fragcoord.xy).rgb;
-	
-	float scol = texture2DRect(lightMap, vary_fragcoord.xy).r;
-			
-	vec3 diff = texture2DRect(diffuseRect, vary_fragcoord.xy).rgb;
-	vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
-	
-	gi_col = gi_col*(diff.rgb+spec.rgb*spec.a);
-
-	float lum = 1.0-clamp(pow(lcol.r, gi_brightness)+sun_lum_offset, 0.0, 1.0);
-	
-	lum *= sun_lum_scale;
-	
-	sun_col *= 1.0+(lum*lum_scale*scol);
-					  
-	vec4 col;
-	col.rgb = gi_col+sun_col.rgb+local_col;
-	
-	col.a = sun_col.a;
-	
-	vec3 bcol = vec3(0,0,0);
-	float tweight = 0.0;
-	for (int i = 0; i < 16; i++)
-	{
-		float weight = (float(i)+1.0)/2.0;
-		bcol += texture2DLod(luminanceMap, vary_fragcoord.xy/screen_res, weight).rgb*weight*weight*weight;
-		tweight += weight*weight;
-	}
-	
-	bcol /= tweight;
-	bcol *= gi_luminance;
-	col.rgb += bcol*lum;
-	
-	gl_FragColor = col;
-	//gl_FragColor.rgb = texture2DRect(giLightMap, vary_fragcoord.xy).rgb;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl
deleted file mode 100644
index 009b5cc7439f76c8f7b49334f13aaf00ac68b755..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl
+++ /dev/null
@@ -1,89 +0,0 @@
-/** 
- * @file postgiF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-#extension GL_ARB_texture_rectangle : enable
-
-uniform sampler2DRect depthMap;
-uniform sampler2DRect normalMap;
-uniform sampler2DRect giLightMap;
-uniform sampler2D	noiseMap;
-uniform sampler2D	giMip;
-uniform sampler2DRect edgeMap;
-
-
-uniform vec2 delta;
-uniform float kern_scale;
-uniform float gi_edge_weight;
-uniform float gi_blur_brightness;
-
-varying vec2 vary_fragcoord;
-
-void main() 
-{
-	vec2 dlt = kern_scale*delta;
-	float defined_weight = 0.0; 
-	vec3 col = vec3(0.0); 
-	
-	float e = 1.0;
-	
-	for (int i = 1; i < 8; i++)
-	{
-		vec2 tc = vary_fragcoord.xy + float(i) * dlt;
-		
-		e = max(e, 0.0);
-		float wght = e;
-		
-	   	col += texture2DRect(giLightMap, tc).rgb*wght;
-		defined_weight += wght;
-				
-		e *= e;
-		e -=(texture2DRect(edgeMap, tc.xy-dlt*0.25).a+
-			texture2DRect(edgeMap, tc.xy+dlt*0.25).a)*gi_edge_weight;
-	}
-
-	e = 1.0;
-	
-	for (int i = 1; i < 8; i++)
-	{
-		vec2 tc = vary_fragcoord.xy - float(i) * dlt;
-		
-		e = max(e,0.0);
-		float wght = e;
-		
-	   	col += texture2DRect(giLightMap, tc).rgb*wght;
-		defined_weight += wght;
-	
-		e *= e;
-		e -= (texture2DRect(edgeMap, tc.xy-dlt*0.25).a+
-			texture2DRect(edgeMap, tc.xy+dlt*0.25).a)*gi_edge_weight;
-		
-	}
-	
-	col /= max(defined_weight, 0.01);
-
-	gl_FragColor.rgb = col * gi_blur_brightness;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl b/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl
deleted file mode 100644
index 6231ee68b75c69b50b1cbd480d448b468fd89833..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl
+++ /dev/null
@@ -1,37 +0,0 @@
-/** 
- * @file postgiV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-varying vec2 vary_fragcoord;
-uniform vec2 screen_res;
-
-void main()
-{
-	//transform vertex
-	gl_Position = ftransform(); 
-	vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
-	vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
deleted file mode 100644
index 1c02adea89bb3e8f90cd1d379a25f2db71e130e3..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ /dev/null
@@ -1,335 +0,0 @@
-/** 
- * @file softenLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
- 
-
-
-#extension GL_ARB_texture_rectangle : enable
-
-uniform sampler2DRect diffuseRect;
-uniform sampler2DRect specularRect;
-uniform sampler2DRect normalMap;
-uniform sampler2DRect lightMap;
-uniform sampler2D	  noiseMap;
-uniform samplerCube environmentMap;
-uniform sampler2D	  lightFunc;
-uniform vec3 gi_quad;
-
-uniform float blur_size;
-uniform float blur_fidelity;
-
-// Inputs
-uniform vec4 morphFactor;
-uniform vec3 camPosLocal;
-//uniform vec4 camPosWorld;
-uniform vec4 gamma;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 ambient;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
-uniform vec4 haze_horizon;
-uniform vec4 haze_density;
-uniform vec4 cloud_shadow;
-uniform vec4 density_multiplier;
-uniform vec4 distance_multiplier;
-uniform vec4 max_y;
-uniform vec4 glow;
-uniform float scene_light_strength;
-uniform vec3 env_mat[3];
-uniform vec4 shadow_clip;
-uniform mat3 ssao_effect_mat;
-
-uniform sampler2DRect depthMap;
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-varying vec4 vary_light;
-varying vec2 vary_fragcoord;
-
-vec3 vary_PositionEye;
-
-vec3 vary_SunlitColor;
-vec3 vary_AmblitColor;
-vec3 vary_AdditiveColor;
-vec3 vary_AtmosAttenuation;
-uniform float gi_ambiance;
-
-vec4 getPosition_d(vec2 pos_screen, float depth)
-{
-	vec2 sc = pos_screen.xy*2.0;
-	sc /= screen_res;
-	sc -= vec2(1.0,1.0);
-	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
-	vec4 pos = inv_proj * ndc;
-	pos /= pos.w;
-	pos.w = 1.0;
-	return pos;
-}
-
-vec4 getPosition(vec2 pos_screen)
-{ //get position in screen space (world units) given window coordinate and depth map
-	float depth = texture2DRect(depthMap, pos_screen.xy).a;
-	return getPosition_d(pos_screen, depth);
-}
-
-vec3 getPositionEye()
-{
-	return vary_PositionEye;
-}
-vec3 getSunlitColor()
-{
-	return vary_SunlitColor;
-}
-vec3 getAmblitColor()
-{
-	return vary_AmblitColor;
-}
-vec3 getAdditiveColor()
-{
-	return vary_AdditiveColor;
-}
-vec3 getAtmosAttenuation()
-{
-	return vary_AtmosAttenuation;
-}
-
-
-void setPositionEye(vec3 v)
-{
-	vary_PositionEye = v;
-}
-
-void setSunlitColor(vec3 v)
-{
-	vary_SunlitColor = v;
-}
-
-void setAmblitColor(vec3 v)
-{
-	vary_AmblitColor = v;
-}
-
-void setAdditiveColor(vec3 v)
-{
-	vary_AdditiveColor = v;
-}
-
-void setAtmosAttenuation(vec3 v)
-{
-	vary_AtmosAttenuation = v;
-}
-
-void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
-
-	vec3 P = inPositionEye;
-	setPositionEye(P);
-	
-	//(TERRAIN) limit altitude
-	if (P.y > max_y.x) P *= (max_y.x / P.y);
-	if (P.y < -max_y.x) P *= (-max_y.x / P.y);
-
-	vec3 tmpLightnorm = lightnorm.xyz;
-
-	vec3 Pn = normalize(P);
-	float Plen = length(P);
-
-	vec4 temp1 = vec4(0);
-	vec3 temp2 = vec3(0);
-	vec4 blue_weight;
-	vec4 haze_weight;
-	vec4 sunlight = sunlight_color;
-	vec4 light_atten;
-
-	//sunlight attenuation effect (hue and brightness) due to atmosphere
-	//this is used later for sunlight modulation at various altitudes
-	light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x);
-		//I had thought blue_density and haze_density should have equal weighting,
-		//but attenuation due to haze_density tends to seem too strong
-
-	temp1 = blue_density + vec4(haze_density.r);
-	blue_weight = blue_density / temp1;
-	haze_weight = vec4(haze_density.r) / temp1;
-
-	//(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
-	temp2.y = max(0.0, tmpLightnorm.y);
-	temp2.y = 1. / temp2.y;
-	sunlight *= exp( - light_atten * temp2.y);
-
-	// main atmospheric scattering line integral
-	temp2.z = Plen * density_multiplier.x;
-
-	// Transparency (-> temp1)
-	// ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati
-	// compiler gets confused.
-	temp1 = exp(-temp1 * temp2.z * distance_multiplier.x);
-
-	//final atmosphere attenuation factor
-	setAtmosAttenuation(temp1.rgb);
-	
-	//compute haze glow
-	//(can use temp2.x as temp because we haven't used it yet)
-	temp2.x = dot(Pn, tmpLightnorm.xyz);
-	temp2.x = 1. - temp2.x;
-		//temp2.x is 0 at the sun and increases away from sun
-	temp2.x = max(temp2.x, .03);	//was glow.y
-		//set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
-	temp2.x *= glow.x;
-		//higher glow.x gives dimmer glow (because next step is 1 / "angle")
-	temp2.x = pow(temp2.x, glow.z);
-		//glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
-	//add "minimum anti-solar illumination"
-	temp2.x += .25;
-	
-	//increase ambient when there are more clouds
-	vec4 tmpAmbient = ambient*gi_ambiance + (vec4(1.) - ambient*gi_ambiance) * cloud_shadow.x * 0.5;
-	
-	/*  decrease value and saturation (that in HSV, not HSL) for occluded areas
-	 * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
-	 * // The following line of code performs the equivalent of:
-	 * float ambAlpha = tmpAmbient.a;
-	 * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
-	 * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
-	 * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
-	 */
-	tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
-
-	//haze color
-	setAdditiveColor(
-		vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient)
-	  + (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x
-		  + tmpAmbient)));
-
-	//brightness of surface both sunlight and ambient
-	setSunlitColor(vec3(sunlight * .5));
-	setAmblitColor(vec3(tmpAmbient * .25));
-	setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
-}
-
-vec3 atmosLighting(vec3 light)
-{
-	light *= getAtmosAttenuation().r;
-	light += getAdditiveColor();
-	return (2.0 * light);
-}
-
-vec3 atmosTransport(vec3 light) {
-	light *= getAtmosAttenuation().r;
-	light += getAdditiveColor() * 2.0;
-	return light;
-}
-vec3 atmosGetDiffuseSunlightColor()
-{
-	return getSunlitColor();
-}
-
-vec3 scaleDownLight(vec3 light)
-{
-	return (light / scene_light_strength );
-}
-
-vec3 scaleUpLight(vec3 light)
-{
-	return (light * scene_light_strength);
-}
-
-vec3 atmosAmbient(vec3 light)
-{
-	return getAmblitColor() + light / 2.0;
-}
-
-vec3 atmosAffectDirectionalLight(float lightIntensity)
-{
-	return getSunlitColor() * lightIntensity;
-}
-
-vec3 scaleSoftClip(vec3 light)
-{
-	//soft clip effect:
-	light = 1. - clamp(light, vec3(0.), vec3(1.));
-	light = 1. - pow(light, gamma.xxx);
-
-	return light;
-}
-
-void main() 
-{
-	vec2 tc = vary_fragcoord.xy;
-	float depth = texture2DRect(depthMap, tc.xy).a;
-	vec3 pos = getPosition_d(tc, depth).xyz;
-	vec3 norm = texture2DRect(normalMap, tc).xyz;
-	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
-	//vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz;
-	
-	float da = max(dot(norm.xyz, vary_light.xyz), 0.0);
-	
-	vec4 diffuse = texture2DRect(diffuseRect, tc);
-	vec3 col;
-	float bloom = 0.0;
-
-	if (diffuse.a < 0.9)
-	{
-		vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
-	
-		da = texture2D(lightFunc, vec2(da, 0.0)).a;
-		
-		vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
-		float scol = max(scol_ambocc.r, diffuse.a); 
-		float ambocc = scol_ambocc.g;
-	
-		calcAtmospherics(pos.xyz, ambocc);
-	
-		col = atmosAmbient(vec3(0));
-		col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a));
-	
-		col *= diffuse.rgb;
-	
-		if (spec.a > 0.0) // specular reflection
-		{
-			// the old infinite-sky shiny reflection
-			//
-			vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-			float sa = dot(refnormpersp, vary_light.xyz);
-			vec3 dumbshiny = vary_SunlitColor*scol*texture2D(lightFunc, vec2(sa, spec.a)).a;
-		
-			// add the two types of shiny together
-			vec3 spec_contrib = dumbshiny * spec.rgb;
-			bloom = dot(spec_contrib, spec_contrib);
-			col += spec_contrib;		
-		}
-	
-		col = atmosLighting(col);
-		col = scaleSoftClip(col);
-
-		col = mix(col, diffuse.rgb, diffuse.a);
-	}
-	else
-	{
-		col = diffuse.rgb;
-	}
-		
-	gl_FragColor.rgb = col;
-	gl_FragColor.a = bloom;
-}
diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl
index 79bd017efc05500122fd48fa780d8165dbdeb2b9..e043ac873ebbbcf0fd1bb81ab33b310ec3cee997 100644
--- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl
+++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl
@@ -23,8 +23,6 @@
  * $/LicenseInfo$
  */
  
-
-
 float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da);
 vec3 calcPointLightSpecular(inout vec4 specular, vec3 view, vec3 v, vec3 n, vec3 l, float r, float pw, vec3 lightCol);
 
@@ -33,6 +31,10 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);
 vec3 atmosGetDiffuseSunlightColor();
 vec3 scaleDownLight(vec3 light);
 
+uniform vec4 light_position[8];
+uniform vec3 light_attenuation[8]; 
+uniform vec3 light_diffuse[8];
+
 vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol)
 {
 	vec4 col = vec4(0.0, 0.0, 0.0, color.a);
@@ -43,18 +45,18 @@ vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor
 	vec4 specularSum = vec4(0.0);
 	
 	// Collect normal lights (need to be divided by two, as we later multiply by 2)
-	col.rgb += gl_LightSource[1].diffuse.rgb * calcDirectionalLightSpecular(specularColor, view, norm, gl_LightSource[1].position.xyz,gl_LightSource[1].diffuse.rgb, 1.0);
-	col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, gl_LightSource[2].position.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation,gl_LightSource[2].diffuse.rgb);
-	col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, gl_LightSource[3].position.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation,gl_LightSource[3].diffuse.rgb);
-	col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, gl_LightSource[4].position.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation,gl_LightSource[4].diffuse.rgb);
-	col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, gl_LightSource[5].position.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].quadraticAttenuation,gl_LightSource[5].diffuse.rgb);
-	col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, gl_LightSource[6].position.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].quadraticAttenuation,gl_LightSource[6].diffuse.rgb);
-	col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, gl_LightSource[7].position.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].quadraticAttenuation,gl_LightSource[7].diffuse.rgb);
+	col.rgb += light_diffuse[1].rgb * calcDirectionalLightSpecular(specularColor, view, norm, light_position[1].xyz,light_diffuse[1].rgb, 1.0);
+	col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, light_position[2].xyz, light_attenuation[2].x, light_attenuation[2].y, light_diffuse[2].rgb); 
+	col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, light_position[3].xyz, light_attenuation[3].x, light_attenuation[3].y, light_diffuse[3].rgb); 
+	col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, light_position[4].xyz, light_attenuation[4].x, light_attenuation[4].y, light_diffuse[4].rgb); 
+	col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, light_position[5].xyz, light_attenuation[5].x, light_attenuation[5].y, light_diffuse[5].rgb); 
+	col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, light_position[6].xyz, light_attenuation[6].x, light_attenuation[6].y, light_diffuse[6].rgb); 
+	col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, light_position[7].xyz, light_attenuation[7].x, light_attenuation[7].y, light_diffuse[7].rgb); 
 	col.rgb = scaleDownLight(col.rgb);
 						
 	// Add windlight lights
 	col.rgb += atmosAmbient(baseCol.rgb);
-	col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, gl_LightSource[0].position.xyz,atmosGetDiffuseSunlightColor()*baseCol.a, 1.0));
+	col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, light_position[0].xyz,atmosGetDiffuseSunlightColor()*baseCol.a, 1.0));
 
 	col.rgb = min(col.rgb*color.rgb, 1.0);
 	specularColor.rgb = min(specularColor.rgb*specularSum.rgb, 1.0);
diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
index dcdc72ac024c2dd55969ba9fd0061f8a8756ebe2..dadff40933a1dc067f024741e0c41ceed4d3a24d 100644
--- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
+++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
@@ -24,7 +24,6 @@
  */
  
 
-
 float calcDirectionalLight(vec3 n, vec3 l);
 float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
 
@@ -33,22 +32,29 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);
 vec3 scaleDownLight(vec3 light);
 vec3 scaleUpLight(vec3 light);
 
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec3 light_attenuation[8]; 
+uniform vec3 light_diffuse[8];
+
 vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight)
 {
 	vec4 col = vec4(0.0, 0.0, 0.0, color.a);
 	
 	// Collect normal lights (need to be divided by two, as we later multiply by 2)
-	col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a);
-	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a);
-	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a);
-	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a);
-	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a);
-	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a);
-	col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);
+	
+	// Collect normal lights
+	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
+	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
+	col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].z);
+	col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].z);
+	col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].z);
+	col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].z);
+	col.rgb += light_diffuse[1].rgb*calcDirectionalLight(norm, light_position[1].xyz);
 	col.rgb = scaleDownLight(col.rgb);
 
 	// Add windlight lights
-	col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, gl_LightSource[0].position.xyz));
+	col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, light_position[0].xyz));
 	col.rgb += atmosAmbient(baseLight.rgb);
 
 	col.rgb = min(col.rgb*color.rgb, 1.0);
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index 9ad313a9a7508cb0f55af4a6636df7268360a35a..0f33d40ac3a1200e0ff5c683265a5be17e66bb79 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -69,6 +69,8 @@ RenderShadowDetail			1	2
 WatchdogDisabled				1	1
 RenderUseStreamVBO			1	1
 RenderFSAASamples			1	16
+RenderMaxTextureIndex		1	16
+
 
 //
 // Low Graphics Settings
@@ -159,7 +161,7 @@ WLSkyDetail					1	48
 RenderDeferred				1	0
 RenderDeferredSSAO			1	0
 RenderShadowDetail			1	0
-RenderFSAASamples			1	4
+RenderFSAASamples			1	2
 
 //
 // Ultra graphics (REALLY PURTY!)
@@ -188,7 +190,7 @@ WLSkyDetail					1	128
 RenderDeferred				1	1
 RenderDeferredSSAO			1	1
 RenderShadowDetail			1	2
-RenderFSAASamples			1	8
+RenderFSAASamples			1	2
 
 
 //
@@ -296,6 +298,7 @@ RenderVBOEnable				1	0
 
 list OpenGLPre30
 RenderDeferred				0	0
+RenderMaxTextureIndex		1	1
 
 list Intel
 RenderAnisotropic			1	0
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index 2dbdf3a76edb8f82005eecd2de607f2a4c61f196..8142311a550d280a8c724358ce7f2d2a28ab3272 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -67,6 +67,7 @@ RenderDeferred				1	1
 RenderDeferredSSAO			1	1
 RenderShadowDetail			1	2
 RenderFSAASamples			1	16
+RenderMaxTextureIndex		1	16
 
 //
 // Low Graphics Settings
@@ -157,7 +158,7 @@ WLSkyDetail					1	48
 RenderDeferred				1	0
 RenderDeferredSSAO			1	0
 RenderShadowDetail			1	0
-RenderFSAASamples			1	4
+RenderFSAASamples			1	2
 
 //
 // Ultra graphics (REALLY PURTY!)
@@ -187,7 +188,7 @@ WLSkyDetail					1	128
 RenderDeferred				1	1
 RenderDeferredSSAO			1	1
 RenderShadowDetail			1	2
-RenderFSAASamples			1	8
+RenderFSAASamples			1	2
 
 //
 // Class Unknown Hardware (unknown)
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 996e57435025730f702feb1f1191ae56aa20d6a2..803c22507a0eac43167fae1c7ce660a8c9a2a047 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -52,9 +52,9 @@ RenderTransparentWater			1	1
 RenderTreeLODFactor				1	1.0
 RenderUseImpostors				1	1
 RenderVBOEnable					1	0
-RenderVBOMappingDisable		1	0
+RenderVBOMappingDisable			1	1
 RenderVolumeLODFactor			1	2.0
-UseStartScreen				1	1
+UseStartScreen					1	1
 UseOcclusion					1	1
 VertexShaderEnable				1	1
 WindLightUseAtmosShaders		1	1
@@ -69,6 +69,7 @@ RenderShadowDetail			1	2
 WatchdogDisabled				1	1
 RenderUseStreamVBO			1	0
 RenderFSAASamples			1	16
+RenderMaxTextureIndex		1	16
 
 //
 // Low Graphics Settings
@@ -159,7 +160,7 @@ WLSkyDetail					1	48
 RenderDeferred				1	0
 RenderDeferredSSAO			1	0
 RenderShadowDetail			1	2
-RenderFSAASamples			1	4
+RenderFSAASamples			1	2
 
 //
 // Ultra graphics (REALLY PURTY!)
@@ -189,7 +190,7 @@ WLSkyDetail					1	128
 RenderDeferred				1	0
 RenderDeferredSSAO			1	0
 RenderShadowDetail			1	2
-RenderFSAASamples			1	8
+RenderFSAASamples			1	2
 
 //
 // Class Unknown Hardware (unknown)
diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt
index a53be10be138a0794d94cd4c6c4a7777ca95a981..278d6018600788b3da964d7a00af0943551173c9 100644
--- a/indra/newview/featuretable_xp.txt
+++ b/indra/newview/featuretable_xp.txt
@@ -69,6 +69,7 @@ RenderShadowDetail			1	0
 WatchdogDisabled				1	1
 RenderUseStreamVBO			1	1
 RenderFSAASamples			1	16
+RenderMaxTextureIndex		1	16
 
 //
 // Low Graphics Settings
@@ -159,7 +160,7 @@ WLSkyDetail					1	48
 RenderDeferred				1	0
 RenderDeferredSSAO			1	0
 RenderShadowDetail			1	2
-RenderFSAASamples			1	4
+RenderFSAASamples			1	2
 
 //
 // Ultra graphics (REALLY PURTY!)
@@ -189,7 +190,7 @@ WLSkyDetail					1	128
 RenderDeferred				1	0
 RenderDeferredSSAO			1	0
 RenderShadowDetail			1	2
-RenderFSAASamples			1	8
+RenderFSAASamples			1	2
 
 //
 // Class Unknown Hardware (unknown)
@@ -294,6 +295,7 @@ RenderVBOEnable				1	0
 
 list OpenGLPre30
 RenderDeferred				0	0
+RenderMaxTextureIndex		1	1
 
 list Intel
 RenderAnisotropic			1	0
diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt
index b7d951e01859a98dc9ccb185b9ea1da25c2ad44e..198e7024593af28e5b0fcf1ec7623cfdcb371eaf 100644
--- a/indra/newview/gpu_table.txt
+++ b/indra/newview/gpu_table.txt
@@ -112,8 +112,8 @@ ATI Mobility Radeon HD 545v		.*ATI.*Mobility.*HD *545v.*					2		1
 ATI Mobility Radeon HD 550v		.*ATI.*Mobility.*HD *550v.*					2		1
 ATI Mobility Radeon HD 560v		.*ATI.*Mobility.*HD *560v.*					2		1
 ATI Mobility Radeon HD 565v		.*ATI.*Mobility.*HD *565v.*					2		1
-ATI Mobility Radeon HD 2300		.*ATI.*Mobility.*HD *23.*					1		1
-ATI Mobility Radeon HD 2400		.*ATI.*Mobility.*HD *24.*					1		1
+ATI Mobility Radeon HD 2300		.*ATI.*Mobility.*HD *23.*					2		1
+ATI Mobility Radeon HD 2400		.*ATI.*Mobility.*HD *24.*					2		1
 ATI Mobility Radeon HD 2600		.*ATI.*Mobility.*HD *26.*					3		1
 ATI Mobility Radeon HD 2700		.*ATI.*Mobility.*HD *27.*					3		1
 ATI Mobility Radeon HD 3100		.*ATI.*Mobility.*HD *31.*					0		1
@@ -140,23 +140,23 @@ ATI Mobility Radeon HD 6600M	.*ATI.*Mobility.*HD *66.*					3		1
 ATI Mobility Radeon HD 6700M	.*ATI.*Mobility.*HD *67.*					3		1
 ATI Mobility Radeon HD 6800M	.*ATI.*Mobility.*HD *68.*					3		1
 ATI Mobility Radeon HD 6900M	.*ATI.*Mobility.*HD *69.*					3		1
-ATI Radeon HD 2300				.*ATI.*Radeon HD *23..						0		1
-ATI Radeon HD 2400				.*ATI.*Radeon HD *24..						1		1
+ATI Radeon HD 2300				.*ATI.*Radeon HD *23..						2		1
+ATI Radeon HD 2400				.*ATI.*Radeon HD *24..						2		1
 ATI Radeon HD 2600				.*ATI.*Radeon HD *26..						2		1
 ATI Radeon HD 2900				.*ATI.*Radeon HD *29..						3		1
 ATI Radeon HD 3000				.*ATI.*Radeon HD *30..						0		1
 ATI Radeon HD 3100				.*ATI.*Radeon HD *31..						1		1
 ATI Radeon HD 3200				.*ATI.*Radeon HD *32..						1		1
-ATI Radeon HD 3300				.*ATI.*Radeon HD *33..						1		1
-ATI Radeon HD 3400				.*ATI.*Radeon HD *34..						1		1
-ATI Radeon HD 3500				.*ATI.*Radeon HD *35..						1		1
+ATI Radeon HD 3300				.*ATI.*Radeon HD *33..						2		1
+ATI Radeon HD 3400				.*ATI.*Radeon HD *34..						2		1
+ATI Radeon HD 3500				.*ATI.*Radeon HD *35..						2		1
 ATI Radeon HD 3600				.*ATI.*Radeon HD *36..						3		1
 ATI Radeon HD 3700				.*ATI.*Radeon HD *37..						3		1
 ATI Radeon HD 3800				.*ATI.*Radeon HD *38..						3		1
 ATI Radeon HD 4100				.*ATI.*Radeon HD *41..						1		1
 ATI Radeon HD 4200				.*ATI.*Radeon HD *42..						1		1
-ATI Radeon HD 4300				.*ATI.*Radeon HD *43..						1		1
-ATI Radeon HD 4400				.*ATI.*Radeon HD *44..						1		1
+ATI Radeon HD 4300				.*ATI.*Radeon HD *43..						2		1
+ATI Radeon HD 4400				.*ATI.*Radeon HD *44..						2		1
 ATI Radeon HD 4500				.*ATI.*Radeon HD *45..						3		1
 ATI Radeon HD 4600				.*ATI.*Radeon HD *46..						3		1
 ATI Radeon HD 4700				.*ATI.*Radeon HD *47..						3		1
@@ -401,11 +401,11 @@ NVIDIA GeForce 7900				.*NVIDIA .*GeForce 79.*						2		1
 NVIDIA GeForce 8100				.*NVIDIA .*GeForce 81.*						1		1
 NVIDIA GeForce 8200M			.*NVIDIA .*GeForce 8200M.*					1		1
 NVIDIA GeForce 8200				.*NVIDIA .*GeForce 82.*						1		1
-NVIDIA GeForce 8300				.*NVIDIA .*GeForce 83.*						1		1
-NVIDIA GeForce 8400M			.*NVIDIA .*GeForce 8400M.*					1		1
-NVIDIA GeForce 8400				.*NVIDIA .*GeForce 84.*						1		1
+NVIDIA GeForce 8300				.*NVIDIA .*GeForce 83.*						2		1
+NVIDIA GeForce 8400M			.*NVIDIA .*GeForce 8400M.*					2		1
+NVIDIA GeForce 8400				.*NVIDIA .*GeForce 84.*						2		1
 NVIDIA GeForce 8500				.*NVIDIA .*GeForce 85.*						3		1
-NVIDIA GeForce 8600M			.*NVIDIA .*GeForce 8600M.*					1		1
+NVIDIA GeForce 8600M			.*NVIDIA .*GeForce 8600M.*					2		1
 NVIDIA GeForce 8600				.*NVIDIA .*GeForce 86.*						3		1
 NVIDIA GeForce 8700M			.*NVIDIA .*GeForce 8700M.*					3		1
 NVIDIA GeForce 8700				.*NVIDIA .*GeForce 87.*						3		1
@@ -415,10 +415,10 @@ NVIDIA GeForce 9100M			.*NVIDIA .*GeForce 9100M.*					0		1
 NVIDIA GeForce 9100				.*NVIDIA .*GeForce 91.*						0		1
 NVIDIA GeForce 9200M			.*NVIDIA .*GeForce 9200M.*					1		1
 NVIDIA GeForce 9200				.*NVIDIA .*GeForce 92.*						1		1
-NVIDIA GeForce 9300M			.*NVIDIA .*GeForce 9300M.*					1		1
-NVIDIA GeForce 9300				.*NVIDIA .*GeForce 93.*						1		1
-NVIDIA GeForce 9400M			.*NVIDIA .*GeForce 9400M.*					1		1
-NVIDIA GeForce 9400				.*NVIDIA .*GeForce 94.*						1		1
+NVIDIA GeForce 9300M			.*NVIDIA .*GeForce 9300M.*					2		1
+NVIDIA GeForce 9300				.*NVIDIA .*GeForce 93.*						2		1
+NVIDIA GeForce 9400M			.*NVIDIA .*GeForce 9400M.*					2		1
+NVIDIA GeForce 9400				.*NVIDIA .*GeForce 94.*						2		1
 NVIDIA GeForce 9500M			.*NVIDIA .*GeForce 9500M.*					2		1
 NVIDIA GeForce 9500				.*NVIDIA .*GeForce 95.*						2		1
 NVIDIA GeForce 9600M			.*NVIDIA .*GeForce 9600M.*					3		1
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index f8b204eca0eb6ceb3870114ee2124295d1e7118b..30573928a491f45be3f65184620cd51eb54aa1ae 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -4004,14 +4004,14 @@ void LLAgent::renderAutoPilotTarget()
 		F32 height_meters;
 		LLVector3d target_global;
 
-		glMatrixMode(GL_MODELVIEW);
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
 		gGL.pushMatrix();
 
 		// not textured
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 		// lovely green
-		glColor4f(0.f, 1.f, 1.f, 1.f);
+		gGL.color4f(0.f, 1.f, 1.f, 1.f);
 
 		target_global = mAutoPilotTargetGlobal;
 
@@ -4019,9 +4019,9 @@ void LLAgent::renderAutoPilotTarget()
 
 		height_meters = 1.f;
 
-		glScalef(height_meters, height_meters, height_meters);
+		gGL.scalef(height_meters, height_meters, height_meters);
 
-		gSphere.render(1500.f);
+		gSphere.render();
 
 		gGL.popMatrix();
 	}
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index ecfd101eebf2377263dccf11fd879829abff5270..5b435b187d06ba5acb7c98013513a5e787adab58 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -522,6 +522,8 @@ static void settings_to_globals()
 
 	LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize"));
 	
+	LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLCoreProfile");
+
 	LLImageGL::sGlobalUseAnisotropic	= gSavedSettings.getBOOL("RenderAnisotropic");
 	LLVOVolume::sLODFactor				= gSavedSettings.getF32("RenderVolumeLODFactor");
 	LLVOVolume::sDistanceFactor			= 1.f-LLVOVolume::sLODFactor * 0.1f;
@@ -590,7 +592,7 @@ static void settings_modify()
 	gSavedSettings.setBOOL("VectorizeSkin", FALSE);
 
 	// disable fullscreen mode, unsupported
-	gSavedSettings.setBOOL("WindowFullScreen", FALSE);
+	//gSavedSettings.setBOOL("WindowFullScreen", FALSE);
 #endif
 }
 
@@ -773,7 +775,7 @@ bool LLAppViewer::init()
 		LLViewerAssetStatsFF::init();
 	}
 
-    initThreads();
+	initThreads();
 	LL_INFOS("InitInfo") << "Threads initialized." << LL_ENDL ;
 
 	// Initialize settings early so that the defaults for ignorable dialogs are
@@ -2896,7 +2898,7 @@ bool LLAppViewer::initWindow()
 		VIEWER_WINDOW_CLASSNAME,
 		gSavedSettings.getS32("WindowX"), gSavedSettings.getS32("WindowY"),
 		gSavedSettings.getS32("WindowWidth"), gSavedSettings.getS32("WindowHeight"),
-		gSavedSettings.getBOOL("WindowFullScreen"), ignorePixelDepth);
+		gSavedSettings.getBOOL("FullScreen"), ignorePixelDepth);
 
 	LL_INFOS("AppInit") << "gViewerwindow created." << LL_ENDL;
 
diff --git a/indra/newview/llcylinder.cpp b/indra/newview/llcylinder.cpp
index 4901e29691689c91b7451369c34c2469763b48a4..f353851a251f3ddbac17a2ca39fa7cb2e1695955 100644
--- a/indra/newview/llcylinder.cpp
+++ b/indra/newview/llcylinder.cpp
@@ -37,261 +37,39 @@
 #include "llgl.h"
 #include "llglheaders.h"
 
-LLCylinder	gCylinder;
 LLCone		gCone;
 
-GLUquadricObj* gQuadObj = NULL;
-
-static const GLint SLICES[] = { 30, 20, 12, 6 };		// same as sphere slices
-static const GLint STACKS = 2;
-static const GLfloat RADIUS = 0.5f;
-	
-// draws a cylinder or cone
-// returns approximate number of triangles required
-U32 draw_cylinder_side(GLint slices, GLint stacks, GLfloat base_radius, GLfloat top_radius)
-{
-	U32 triangles = 0;
-	GLfloat height = 1.0f;
-
-	if (!gQuadObj)
-	{
-		gQuadObj = gluNewQuadric();
-		if (!gQuadObj) llerror("draw_cylindrical_body couldn't allocated quadric", 0);
-	}
-
-	gluQuadricDrawStyle(gQuadObj, GLU_FILL);
-	gluQuadricNormals(gQuadObj, GLU_SMOOTH);
-	gluQuadricOrientation(gQuadObj, GLU_OUTSIDE);
-	gluQuadricTexture(gQuadObj, GL_TRUE);
-	gluCylinder(gQuadObj, base_radius, top_radius, height, slices, stacks);
-	triangles += stacks * (slices * 2);
-	
-
-	return triangles;
-}
-
-
-// Returns number of triangles required to draw
-// Need to know if top or not to set lighting normals
-const BOOL TOP = TRUE;
-const BOOL BOTTOM = FALSE;
-U32 draw_cylinder_cap(GLint slices, GLfloat base_radius, BOOL is_top)
-{
-	U32 triangles = 0;
-
-	if (!gQuadObj)
-	{
-		gQuadObj = gluNewQuadric();
-		if (!gQuadObj) llerror("draw_cylinder_base couldn't allocated quadric", 0);
-	}
-
-	gluQuadricDrawStyle(gQuadObj, GLU_FILL);
-	gluQuadricNormals(gQuadObj, GLU_SMOOTH);
-	gluQuadricOrientation(gQuadObj, GLU_OUTSIDE);
-	gluQuadricTexture(gQuadObj, GL_TRUE);
-
-	// no hole in the middle of the disk, and just one ring
-	GLdouble inner_radius = 0.0;
-	GLint rings = 1;
-
-	// normals point in +z for top, -z for base
-	if (is_top)
-	{
-		gluQuadricOrientation(gQuadObj, GLU_OUTSIDE);
-	}
-	else
-	{
-		gluQuadricOrientation(gQuadObj, GLU_INSIDE);
-	}
-	gluDisk(gQuadObj, inner_radius, base_radius, slices, rings);
-	triangles += slices;
-
-	return triangles;
-}
-
-void LLCylinder::drawSide(S32 detail)
-{
-	draw_cylinder_side(SLICES[detail], STACKS, RADIUS, RADIUS);
-}
-
-void LLCylinder::drawTop(S32 detail)
-{
-	draw_cylinder_cap(SLICES[detail], RADIUS, TOP);
-}
-
-void LLCylinder::drawBottom(S32 detail)
-{
-	draw_cylinder_cap(SLICES[detail], RADIUS, BOTTOM);
-}
-
-void LLCylinder::prerender()
-{
-}
-
-void LLCylinder::cleanupGL()
-{
-	if (gQuadObj)
-	{
-		gluDeleteQuadric(gQuadObj);
-		gQuadObj = NULL;
-	}
-}
-
-void LLCylinder::render(F32 pixel_area)
-{
-	renderface(pixel_area, 0);
-	renderface(pixel_area, 1);
-	renderface(pixel_area, 2);
-}
-
-
-void LLCylinder::renderface(F32 pixel_area, S32 face)
-{
-	if (face < 0 || face > 2)
-	{
-		llerror("LLCylinder::renderface() invalid face number", face);
-		return;
-	}
-
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
-
-	S32 level_of_detail;
-
-	if (pixel_area > 20000.f)
-	{
-		level_of_detail = 0;
-	}
-	else if (pixel_area > 1600.f)
-	{
-		level_of_detail = 1;
-	}
-	else if (pixel_area > 200.f)
-	{
-		level_of_detail = 2;
-	}
-	else
-	{
-		level_of_detail = 3;
-	}
-
-	if (level_of_detail < 0 || CYLINDER_LEVELS_OF_DETAIL <= level_of_detail)
-	{
-		llerror("LLCylinder::renderface() invalid level of detail", level_of_detail);
-		return;
-	}
-
-	LLVertexBuffer::unbind();
-	
-	switch(face)
-	{
-	case 0:
-		glTranslatef(0.f, 0.f, -0.5f);
-		drawSide(level_of_detail);
-		break;
-	case 1:
-		glTranslatef(0.0f, 0.f, 0.5f);
-		drawTop(level_of_detail);
-		break;
-	case 2:
-		glTranslatef(0.0f, 0.f, -0.5f);
-		drawBottom(level_of_detail);
-		break;
-	default:
-		llerror("LLCylinder::renderface() fell out of switch", 0);
-		break;
-	}
-
-	glMatrixMode(GL_MODELVIEW);
-	glPopMatrix();
-}
-
-
 //
 // Cones
 //
 
-void LLCone::prerender()
+void LLCone::render(S32 sides)
 {
-}
+	gGL.begin(LLRender::TRIANGLE_FAN);
+	gGL.vertex3f(0,0,0);
 
-void LLCone::cleanupGL()
-{
-	if (gQuadObj)
+	for (U32 i = 0; i < sides; i++)
 	{
-		gluDeleteQuadric(gQuadObj);
-		gQuadObj = NULL;
+		F32 a = (F32) i/sides * F_PI*2.f;
+		F32 x = cosf(a)*0.5f;
+		F32 y = sinf(a)*0.5f;
+		gGL.vertex3f(x,y,-.5f);
 	}
-}
+	gGL.vertex3f(cosf(0.f)*0.5f, sinf(0.f)*0.5f, -0.5f);
 
-void LLCone::drawSide(S32 detail)
-{
-	draw_cylinder_side( SLICES[detail], STACKS, RADIUS, 0.f );	
-}
-
-void LLCone::drawBottom(S32 detail)
-{
-	draw_cylinder_cap( SLICES[detail], RADIUS, BOTTOM );
-}
-
-void LLCone::render(S32 level_of_detail)
-{
-	GLfloat height = 1.0f;
+	gGL.end();
 
-	if (level_of_detail < 0 || CONE_LEVELS_OF_DETAIL <= level_of_detail)
+	gGL.begin(LLRender::TRIANGLE_FAN);
+	gGL.vertex3f(0.f, 0.f, 0.5f);
+	for (U32 i = 0; i < sides; i++)
 	{
-		llerror("LLCone::render() invalid level of detail", level_of_detail);
-		return;
+		F32 a = (F32) i/sides * F_PI*2.f;
+		F32 x = cosf(a)*0.5f;
+		F32 y = sinf(a)*0.5f;
+		gGL.vertex3f(x,y,-0.5f);
 	}
+	gGL.vertex3f(cosf(0.f)*0.5f, sinf(0.f)*0.5f, -0.5f);
 
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
-
-	// center object at 0
-	glTranslatef(0.f, 0.f, - height / 2.0f);
-
-	drawSide(level_of_detail);
-	drawBottom(level_of_detail);
-
-	glMatrixMode(GL_MODELVIEW);
-	glPopMatrix();
+	gGL.end();
 }
 
-
-void LLCone::renderface(S32 level_of_detail, S32 face)
-{
-	if (face < 0 || face > 1)
-	{
-		llerror("LLCone::renderface() invalid face number", face);
-		return;
-	}
-
-	if (level_of_detail < 0 || CONE_LEVELS_OF_DETAIL <= level_of_detail)
-	{
-		llerror("LLCone::renderface() invalid level of detail", level_of_detail);
-		return;
-	}
-
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
-
-	LLVertexBuffer::unbind();
-	
-	switch(face)
-	{
-	case 0:
-		glTranslatef(0.f, 0.f, -0.5f);
-		drawSide(level_of_detail);
-		break;
-	case 1:
-		glTranslatef(0.f, 0.f, -0.5f);
-		drawBottom(level_of_detail);
-		break;
-	default:
-		llerror("LLCylinder::renderface() fell out of switch", 0);
-		break;
-	}
-
-	glMatrixMode(GL_MODELVIEW);
-	glPopMatrix();
-}
diff --git a/indra/newview/llcylinder.h b/indra/newview/llcylinder.h
index 40a669ceb6d82294deb56a464925f6e843bb851b..4369f06659d048ad3ba72c4edb89c59147f22fcd 100644
--- a/indra/newview/llcylinder.h
+++ b/indra/newview/llcylinder.h
@@ -30,45 +30,18 @@
 //#include "stdtypes.h"
 //#include "llgl.h"
 
-//
-// Cylinders
-//
-const S32 CYLINDER_LEVELS_OF_DETAIL = 4;
-const S32 CYLINDER_FACES = 3;
-
-class LLCylinder
-{
-public:
-	void prerender();
-	void drawTop(S32 detail);
-	void drawSide(S32 detail);
-	void drawBottom(S32 detail);
-	void cleanupGL();
-
-	void render(F32 pixel_area);
-	void renderface(F32 pixel_area, S32 face);
-};
-
+#include "llvertexbuffer.h"
 
 //
 // Cones
 //
 
-const S32 CONE_LOD_HIGHEST = 0;
-const S32 CONE_LEVELS_OF_DETAIL = 4;
-const S32 CONE_FACES = 2;
-
 class LLCone
 {	
 public:
-	void prerender();
-	void cleanupGL();
-	void drawSide(S32 detail);
-	void drawBottom(S32 detail);
-	void render(S32 level_of_detail);
-	void renderface(S32 level_of_detail, S32 face);
+	void render(S32 sides = 12);
 };
 
-extern LLCylinder gCylinder;
+
 extern LLCone gCone;
 #endif
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 286284f828e13af883bce36d6ce5dba52da5fd27..35f8a8579671ef3ac9ccaed54c22323a7d6dc032 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -384,7 +384,7 @@ BOOL LLFacePool::LLOverrideFaceColor::sOverrideFaceColor = FALSE;
 
 void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4& color)
 {
-	glColor4fv(color.mV);
+	gGL.diffuseColor4fv(color.mV);
 }
 
 void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4U& color)
@@ -394,7 +394,7 @@ void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4U& color)
 
 void LLFacePool::LLOverrideFaceColor::setColor(F32 r, F32 g, F32 b, F32 a)
 {
-	glColor4f(r,g,b,a);
+	gGL.diffuseColor4f(r,g,b,a);
 }
 
 
@@ -457,10 +457,10 @@ void LLRenderPass::applyModelMatrix(LLDrawInfo& params)
 	if (params.mModelMatrix != gGLLastMatrix)
 	{
 		gGLLastMatrix = params.mModelMatrix;
-		glLoadMatrixd(gGLModelView);
+		gGL.loadMatrix(gGLModelView);
 		if (params.mModelMatrix)
 		{
-			glMultMatrixf((GLfloat*) params.mModelMatrix->mMatrix);
+			gGL.multMatrix((GLfloat*) params.mModelMatrix->mMatrix);
 		}
 		gPipeline.mMatrixOpCount++;
 	}
@@ -494,8 +494,8 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
 				{
 					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++;
 				}
 			}
@@ -519,8 +519,8 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
 
 	if (tex_setup)
 	{
-		glLoadIdentity();
-		glMatrixMode(GL_MODELVIEW);
+		gGL.loadIdentity();
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
 	}
 }
 
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 9719140a37a52f26214fad5e6145cea7be7f68aa..230c4e2638dc619d291345dc5d16553859a17e27 100644
--- 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)
 {
@@ -175,11 +175,13 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass)
 	{
 		simple_shader = &gObjectSimpleWaterAlphaMaskProgram;
 		fullbright_shader = &gObjectFullbrightWaterAlphaMaskProgram;
+		emissive_shader = &gObjectEmissiveWaterProgram;
 	}
 	else
 	{
 		simple_shader = &gObjectSimpleAlphaMaskProgram;
 		fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
+		emissive_shader = &gObjectEmissiveProgram;
 	}
 
 	if (mVertexShaderLevel > 0)
@@ -319,20 +321,25 @@ void LLDrawPoolAlpha::render(S32 pass)
 		BOOL shaders = gPipeline.canUseVertexShaders();
 		if(shaders) 
 		{
-			gObjectFullbrightNonIndexedProgram.bind();
+			gHighlightProgram.bind();
 		}
 		else
 		{
 			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);
+
 		if(shaders) 
 		{
-			gObjectFullbrightNonIndexedProgram.unbind();
+			gHighlightProgram.unbind();
 		}
 	}
 }
@@ -472,8 +479,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
 						{
 							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++;
 						}
 					}
@@ -488,30 +495,34 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
 				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)
 
+					emissive_shader->bind();
+					
 					// glow doesn't use vertex colors from the mesh data
-					params.mVertexBuffer->setBuffer(mask & ~LLVertexBuffer::MAP_COLOR);
-					glColor4ubv(params.mGlowColor.mV);
-
+					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 (tex_setup)
 				{
 					gGL.getTexUnit(0)->activate();
-					glLoadIdentity();
-					glMatrixMode(GL_MODELVIEW);
+					gGL.loadIdentity();
+					gGL.matrixMode(LLRender::MM_MODELVIEW);
 				}
 			}
 		}
diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h
index 12a7ae92b12f9dbd60fd7dee206acf55776c8ae7..a4245e561d85cf3e70a377b59c73405b8f219805 100644
--- a/indra/newview/lldrawpoolalpha.h
+++ b/indra/newview/lldrawpoolalpha.h
@@ -78,6 +78,7 @@ class LLDrawPoolAlpha: public LLRenderPass
 	LLGLSLShader* target_shader;
 	LLGLSLShader* simple_shader;
 	LLGLSLShader* fullbright_shader;	
+	LLGLSLShader* emissive_shader;
 
 	// our 'normal' alpha blend function for this pass
 	LLRender::eBlendFactor mColorSFactor;
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 37ee81aeb545afdbde39a9e5c2bfeb4626bb540b..7290a48a1a578b5c8a55abd228e9e10dfc977b70 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -263,7 +263,6 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha()
 	gPipeline.bindDeferredShader(*sVertexProgram);
 	
 	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-	enable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]);
 }
 
 void LLDrawPoolAvatar::beginDeferredRiggedAlpha()
@@ -271,7 +270,6 @@ void LLDrawPoolAvatar::beginDeferredRiggedAlpha()
 	sVertexProgram = &gDeferredSkinnedAlphaProgram;
 	gPipeline.bindDeferredShader(*sVertexProgram);
 	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-	LLVertexBuffer::sWeight4Loc = sVertexProgram->getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT);
 	gPipeline.enableLightsDynamic();
 }
 
@@ -280,7 +278,6 @@ void LLDrawPoolAvatar::endDeferredRiggedAlpha()
 	LLVertexBuffer::unbind();
 	gPipeline.unbindDeferredShader(*sVertexProgram);
 	sDiffuseChannel = 0;
-	LLVertexBuffer::sWeight4Loc = -1;
 	sVertexProgram = NULL;
 }
 
@@ -314,8 +311,7 @@ void LLDrawPoolAvatar::endPostDeferredAlpha()
 	// if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done
 	sRenderingSkinned = FALSE;
 	sSkipOpaque = FALSE;
-	disable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]);
-	
+		
 	gPipeline.unbindDeferredShader(*sVertexProgram);
 	sDiffuseChannel = 0;
 	sShaderLevel = mVertexShaderLevel;
@@ -356,27 +352,22 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
 	if (pass == 0)
 	{
 		sVertexProgram = &gDeferredAvatarShadowProgram;
-		if (sShaderLevel > 0)
-		{
-			gAvatarMatrixParam = sVertexProgram->mUniform[LLViewerShaderMgr::AVATAR_MATRIX];
-		}
-		//gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.2f);
 		
-		glColor4f(1,1,1,1);
+		//gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.2f);		
 
 		if ((sShaderLevel > 0))  // for hardware blending
 		{
 			sRenderingSkinned = TRUE;
 			sVertexProgram->bind();
-			enable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]);
 		}
+
+		gGL.diffuseColor4f(1,1,1,1);
 	}
 	else
 	{
 		sVertexProgram = &gDeferredAttachmentShadowProgram;
 		sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
 		sVertexProgram->bind();
-		LLVertexBuffer::sWeight4Loc = sVertexProgram->getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT);
 	}
 }
 
@@ -389,14 +380,12 @@ void LLDrawPoolAvatar::endShadowPass(S32 pass)
 		{
 			sRenderingSkinned = FALSE;
 			sVertexProgram->unbind();
-			disable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]);
 		}
 	}
 	else
 	{
 		LLVertexBuffer::unbind();
 		sVertexProgram->unbind();
-		LLVertexBuffer::sWeight4Loc = -1;
 		sVertexProgram = NULL;
 	}
 }
@@ -430,11 +419,6 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
 	
 	if (pass == 0)
 	{
-		if (sShaderLevel > 0)
-		{
-			gAvatarMatrixParam = sVertexProgram->mUniform[LLViewerShaderMgr::AVATAR_MATRIX];
-		}
-
 		avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE);
 	}
 	else
@@ -492,11 +476,6 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass)
 	//reset vertex buffer mappings
 	LLVertexBuffer::unbind();
 
-	if (pass == 0)
-	{ //make sure no stale colors are left over from a previous render
-		glColor4f(1,1,1,1);
-	}
-
 	if (LLPipeline::sImpostorRender)
 	{ //impostor render does not have impostors or rigid rendering
 		pass += 2;
@@ -535,6 +514,11 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass)
 		beginRiggedGlow();
 		break;
 	}
+
+	if (pass == 0)
+	{ //make sure no stale colors are left over from a previous render
+		gGL.diffuseColor4f(1,1,1,1);
+	}
 }
 
 void LLDrawPoolAvatar::endRenderPass(S32 pass)
@@ -614,11 +598,11 @@ void LLDrawPoolAvatar::beginRigid()
 	{
 		if (LLPipeline::sUnderWaterRender)
 		{
-			sVertexProgram = &gObjectAlphaMaskNonIndexedWaterProgram;
+			sVertexProgram = &gObjectAlphaMaskNoColorWaterProgram;
 		}
 		else
 		{
-			sVertexProgram = &gObjectAlphaMaskNonIndexedProgram;
+			sVertexProgram = &gObjectAlphaMaskNoColorProgram;
 		}
 		
 		if (sVertexProgram != NULL)
@@ -672,9 +656,10 @@ void LLDrawPoolAvatar::endDeferredImpostor()
 
 void LLDrawPoolAvatar::beginDeferredRigid()
 {
-	sVertexProgram = &gDeferredNonIndexedDiffuseProgram;
+	sVertexProgram = &gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;
 				
 	sVertexProgram->bind();
+	sVertexProgram->setAlphaRange(0.2f, 1.f);
 }
 
 void LLDrawPoolAvatar::endDeferredRigid()
@@ -703,11 +688,11 @@ void LLDrawPoolAvatar::beginSkinned()
 	{
 		if (LLPipeline::sUnderWaterRender)
 		{
-			sVertexProgram = &gObjectAlphaMaskNonIndexedWaterProgram;
+			sVertexProgram = &gObjectAlphaMaskNoColorWaterProgram;
 		}
 		else
 		{
-			sVertexProgram = &gObjectAlphaMaskNonIndexedProgram;
+			sVertexProgram = &gObjectAlphaMaskNoColorProgram;
 		}
 	}
 	
@@ -716,17 +701,6 @@ void LLDrawPoolAvatar::beginSkinned()
 		sRenderingSkinned = TRUE;
 
 		sVertexProgram->bind();
-		if (sShaderLevel >= SHADER_LEVEL_CLOTH)
-		{
-			enable_cloth_weights(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_CLOTHING]);
-		}
-		enable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]);
-
-		if (sShaderLevel >= SHADER_LEVEL_BUMP)
-		{
-			enable_binormals(sVertexProgram->mAttribute[LLViewerShaderMgr::BINORMAL]);
-		}
-		
 		sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
 		gGL.getTexUnit(0)->activate();
 	}
@@ -754,16 +728,6 @@ void LLDrawPoolAvatar::endSkinned()
 		sRenderingSkinned = FALSE;
 		sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP);
 		gGL.getTexUnit(0)->activate();
-		disable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]);
-		if (sShaderLevel >= SHADER_LEVEL_BUMP)
-		{
-			disable_binormals(sVertexProgram->mAttribute[LLViewerShaderMgr::BINORMAL]);
-		}
-		if ((sShaderLevel >= SHADER_LEVEL_CLOTH))
-		{
-			disable_cloth_weights(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_CLOTHING]);
-		}
-
 		sVertexProgram->unbind();
 		sShaderLevel = mVertexShaderLevel;
 	}
@@ -809,7 +773,6 @@ void LLDrawPoolAvatar::beginRiggedSimple()
 	{
 		sDiffuseChannel = 0;
 		sVertexProgram->bind();
-		LLVertexBuffer::sWeight4Loc = sVertexProgram->getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT);
 	}
 }
 
@@ -820,7 +783,6 @@ void LLDrawPoolAvatar::endRiggedSimple()
 	{
 		sVertexProgram->unbind();
 		sVertexProgram = NULL;
-		LLVertexBuffer::sWeight4Loc = -1;
 	}
 }
 
@@ -847,7 +809,34 @@ void LLDrawPoolAvatar::endRiggedFullbrightAlpha()
 
 void LLDrawPoolAvatar::beginRiggedGlow()
 {
-	beginRiggedFullbright();
+	if (sShaderLevel > 0)
+	{
+		if (LLPipeline::sUnderWaterRender)
+		{
+			sVertexProgram = &gSkinnedObjectEmissiveWaterProgram;
+		}
+		else
+		{
+			sVertexProgram = &gSkinnedObjectEmissiveProgram;
+		}
+	}
+	else
+	{
+		if (LLPipeline::sUnderWaterRender)
+		{
+			sVertexProgram = &gObjectEmissiveNonIndexedWaterProgram;
+		}
+		else
+		{
+			sVertexProgram = &gObjectEmissiveNonIndexedProgram;
+		}
+	}
+
+	if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
+	{
+		sDiffuseChannel = 0;
+		sVertexProgram->bind();
+	}
 }
 
 void LLDrawPoolAvatar::endRiggedGlow()
@@ -884,7 +873,6 @@ void LLDrawPoolAvatar::beginRiggedFullbright()
 	{
 		sDiffuseChannel = 0;
 		sVertexProgram->bind();
-		LLVertexBuffer::sWeight4Loc = sVertexProgram->getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT);
 	}
 }
 
@@ -895,7 +883,6 @@ void LLDrawPoolAvatar::endRiggedFullbright()
 	{
 		sVertexProgram->unbind();
 		sVertexProgram = NULL;
-		LLVertexBuffer::sWeight4Loc = -1;
 	}
 }
 
@@ -928,7 +915,6 @@ void LLDrawPoolAvatar::beginRiggedShinySimple()
 	{
 		sVertexProgram->bind();
 		LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false);
-		LLVertexBuffer::sWeight4Loc = sVertexProgram->getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT);
 	}
 }
 
@@ -940,7 +926,6 @@ void LLDrawPoolAvatar::endRiggedShinySimple()
 		LLDrawPoolBump::unbindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false);
 		sVertexProgram->unbind();
 		sVertexProgram = NULL;
-		LLVertexBuffer::sWeight4Loc = -1;
 	}
 }
 
@@ -974,7 +959,6 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()
 	{
 		sVertexProgram->bind();
 		LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false);
-		LLVertexBuffer::sWeight4Loc = sVertexProgram->getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT);
 	}
 }
 
@@ -986,7 +970,6 @@ void LLDrawPoolAvatar::endRiggedFullbrightShiny()
 		LLDrawPoolBump::unbindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false);
 		sVertexProgram->unbind();
 		sVertexProgram = NULL;
-		LLVertexBuffer::sWeight4Loc = -1;
 	}
 }
 
@@ -996,14 +979,12 @@ void LLDrawPoolAvatar::beginDeferredRiggedSimple()
 	sVertexProgram = &gDeferredSkinnedDiffuseProgram;
 	sDiffuseChannel = 0;
 	sVertexProgram->bind();
-	LLVertexBuffer::sWeight4Loc = sVertexProgram->getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT);
 }
 
 void LLDrawPoolAvatar::endDeferredRiggedSimple()
 {
 	LLVertexBuffer::unbind();
 	sVertexProgram->unbind();
-	LLVertexBuffer::sWeight4Loc = -1;
 	sVertexProgram = NULL;
 }
 
@@ -1013,7 +994,6 @@ void LLDrawPoolAvatar::beginDeferredRiggedBump()
 	sVertexProgram->bind();
 	normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
 	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-	LLVertexBuffer::sWeight4Loc = sVertexProgram->getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT);
 }
 
 void LLDrawPoolAvatar::endDeferredRiggedBump()
@@ -1022,7 +1002,6 @@ void LLDrawPoolAvatar::endDeferredRiggedBump()
 	sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP);
 	sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
 	sVertexProgram->unbind();
-	LLVertexBuffer::sWeight4Loc = -1;
 	normal_channel = -1;
 	sDiffuseChannel = 0;
 	sVertexProgram = NULL;
@@ -1032,14 +1011,12 @@ void LLDrawPoolAvatar::beginDeferredSkinned()
 {
 	sShaderLevel = mVertexShaderLevel;
 	sVertexProgram = &gDeferredAvatarProgram;
-
 	sRenderingSkinned = TRUE;
 
 	sVertexProgram->bind();
+	sVertexProgram->setAlphaRange(0.2f, 1.f);
 	
 	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-	enable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]);
-
 	gGL.getTexUnit(0)->activate();
 }
 
@@ -1047,7 +1024,6 @@ void LLDrawPoolAvatar::endDeferredSkinned()
 {
 	// if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done
 	sRenderingSkinned = FALSE;
-	disable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]);
 	sVertexProgram->unbind();
 
 	sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
@@ -1161,10 +1137,10 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 		return;
 	}
 
-	if (single_avatar && avatarp->mSpecialRenderMode >= 1) // 1=anim preview, 2=image preview,  3=morph view
+	/*if (single_avatar && avatarp->mSpecialRenderMode >= 1) // 1=anim preview, 2=image preview,  3=morph view
 	{
 		gPipeline.enableLightsAvatarEdit(LLColor4(.5f, .5f, .5f, 1.f));
-	}
+	}*/
 	
 	if (pass == 1)
 	{
@@ -1255,11 +1231,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 		return;
 	}
 	
-	if (sShaderLevel > 0)
-	{
-		gAvatarMatrixParam = sVertexProgram->mUniform[LLViewerShaderMgr::AVATAR_MATRIX];
-	}
-    
 	if ((sShaderLevel >= SHADER_LEVEL_CLOTH))
 	{
 		LLMatrix4 rot_mat;
@@ -1273,16 +1244,16 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 		wind = wind * rot_mat;
 		wind.mV[VW] = avatarp->mWindVec.mV[VW];
 
-		sVertexProgram->vertexAttrib4fv(LLViewerShaderMgr::AVATAR_WIND, wind.mV);
+		sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_WIND, 1, wind.mV);
 		F32 phase = -1.f * (avatarp->mRipplePhase);
 
 		F32 freq = 7.f + (noise1(avatarp->mRipplePhase) * 2.f);
 		LLVector4 sin_params(freq, freq, freq, phase);
-		sVertexProgram->vertexAttrib4fv(LLViewerShaderMgr::AVATAR_SINWAVE, sin_params.mV);
+		sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_SINWAVE, 1, sin_params.mV);
 
 		LLVector4 gravity(0.f, 0.f, -CLOTHING_GRAVITY_EFFECT, 0.f);
 		gravity = gravity * rot_mat;
-		sVertexProgram->vertexAttrib4fv(LLViewerShaderMgr::AVATAR_GRAVITY, gravity.mV);
+		sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_GRAVITY, 1, gravity.mV);
 	}
 
 	if( !single_avatar || (avatarp == single_avatar) )
@@ -1306,8 +1277,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
 	
 	if (buffer.isNull() || 
 		buffer->getTypeMask() != data_mask ||
-		buffer->getRequestedVerts() != vol_face.mNumVertices ||
-		buffer->getRequestedIndices() != vol_face.mNumIndices ||
+		buffer->getNumVerts() != vol_face.mNumVertices ||
+		buffer->getNumIndices() != vol_face.mNumIndices ||
 		(drawable && drawable->isState(LLDrawable::REBUILD_ALL)))
 	{
 		face->setGeomIndex(0);
@@ -1346,7 +1317,19 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
 
 		LLMatrix3 mat_normal(mat3);				
 
+		//let getGeometryVolume know if alpha should override shiny
+		if (face->getFaceColor().mV[3] < 1.f)
+		{
+			face->setPoolType(LLDrawPool::POOL_ALPHA);
+		}
+		else
+		{
+			face->setPoolType(LLDrawPool::POOL_AVATAR);
+		}
+
 		face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true);
+
+		buffer->flush();
 	}
 
 	if (sShaderLevel <= 0 && face->mLastSkinTime < avatar->getLastSkinTime())
@@ -1383,7 +1366,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
 		LLMatrix4a bind_shape_matrix;
 		bind_shape_matrix.loadu(skin->mBindShapeMatrix);
 
-		for (U32 j = 0; j < buffer->getRequestedVerts(); ++j)
+		for (U32 j = 0; j < buffer->getNumVerts(); ++j)
 		{
 			LLMatrix4a final_mat;
 			final_mat.clear();
@@ -1483,12 +1466,12 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 			continue;
 		}
 
-		stop_glerror();
+		//stop_glerror();
 
-		const LLVolumeFace& vol_face = volume->getVolumeFace(te);
-		updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face);
+		//const LLVolumeFace& vol_face = volume->getVolumeFace(te);
+		//updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face);
 		
-		stop_glerror();
+		//stop_glerror();
 
 		U32 data_mask = LLFace::getRiggedDataMask(type);
 
@@ -1524,17 +1507,15 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 				data_mask &= ~LLVertexBuffer::MAP_WEIGHT4;
 			}
 
-			buff->setBuffer(data_mask);
-
 			U16 start = face->getGeomStart();
 			U16 end = start + face->getGeomCount()-1;
 			S32 offset = face->getIndicesStart();
 			U32 count = face->getIndicesCount();
 
-			if (glow)
+			/*if (glow)
 			{
-				glColor4f(0,0,0,face->getTextureEntry()->getGlow());
-			}
+				gGL.diffuseColor4f(0,0,0,face->getTextureEntry()->getGlow());
+			}*/
 
 			gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture());
 			if (normal_channel > -1)
@@ -1544,14 +1525,16 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 
 			if (face->mTextureMatrix)
 			{
-				glMatrixMode(GL_TEXTURE);
-				glLoadMatrixf((F32*) face->mTextureMatrix->mMatrix);
+				gGL.matrixMode(LLRender::MM_TEXTURE);
+				gGL.loadMatrix((F32*) face->mTextureMatrix->mMatrix);
+				buff->setBuffer(data_mask);
 				buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
-				glLoadIdentity();
-				glMatrixMode(GL_MODELVIEW);
+				gGL.loadIdentity();
+				gGL.matrixMode(LLRender::MM_MODELVIEW);
 			}
 			else
 			{
+				buff->setBuffer(data_mask);
 				buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);		
 			}
 		}
@@ -1560,6 +1543,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 
 void LLDrawPoolAvatar::renderDeferredRiggedSimple(LLVOAvatar* avatar)
 {
+	updateRiggedVertexBuffers(avatar);
 	renderRigged(avatar, RIGGED_DEFERRED_SIMPLE);
 }
 
@@ -1568,8 +1552,58 @@ void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar)
 	renderRigged(avatar, RIGGED_DEFERRED_BUMP);
 }
 
+void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
+{
+	//update rigged vertex buffers
+	for (U32 type = 0; type < NUM_RIGGED_PASSES; ++type)
+	{
+		for (U32 i = 0; i < mRiggedFace[type].size(); ++i)
+		{
+			LLFace* face = mRiggedFace[type][i];
+			LLDrawable* drawable = face->getDrawable();
+			if (!drawable)
+			{
+				continue;
+			}
+
+			LLVOVolume* vobj = drawable->getVOVolume();
+
+			if (!vobj)
+			{
+				continue;
+			}
+
+			LLVolume* volume = vobj->getVolume();
+			S32 te = face->getTEOffset();
+
+			if (!volume || volume->getNumVolumeFaces() <= te)
+			{
+				continue;
+			}
+
+			LLUUID mesh_id = volume->getParams().getSculptID();
+			if (mesh_id.isNull())
+			{
+				continue;
+			}
+
+			const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(mesh_id, vobj);
+			if (!skin)
+			{
+				continue;
+			}
+
+			stop_glerror();
+
+			const LLVolumeFace& vol_face = volume->getVolumeFace(te);
+			updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face);
+		}
+	}
+}
+
 void LLDrawPoolAvatar::renderRiggedSimple(LLVOAvatar* avatar)
 {
+	updateRiggedVertexBuffers(avatar);
 	renderRigged(avatar, RIGGED_SIMPLE);
 }
 
@@ -1684,34 +1718,3 @@ LLVertexBufferAvatar::LLVertexBufferAvatar()
 }
 
 
-void LLVertexBufferAvatar::setupVertexBuffer(U32 data_mask) const
-{
-	if (sRenderingSkinned)
-	{
-		U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
-
-		glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_VERTEX], (void*)(base + 0));
-		glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL]));
-		glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
-		
-		set_vertex_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT], 
-						LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_WEIGHT], (F32*)(base + mOffsets[TYPE_WEIGHT]));
-
-		if (sShaderLevel >= LLDrawPoolAvatar::SHADER_LEVEL_BUMP)
-		{
-			set_binormals(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::BINORMAL],
-				LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_BINORMAL], (LLVector3*)(base + mOffsets[TYPE_BINORMAL]));
-		}
-	
-		if (sShaderLevel >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH)
-		{
-			set_vertex_clothing_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_CLOTHING], 
-				LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_CLOTHWEIGHT], (LLVector4*)(base + mOffsets[TYPE_CLOTHWEIGHT]));
-		}
-	}
-	else
-	{
-		LLVertexBuffer::setupVertexBuffer(data_mask);
-	}
-}
-
diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h
index fcd8294af544e27d8b4a10150590ef7c3c49b5ce..69e306885893797c00e5b222c59d338d59a43739 100644
--- a/indra/newview/lldrawpoolavatar.h
+++ b/indra/newview/lldrawpoolavatar.h
@@ -134,6 +134,7 @@ class LLDrawPoolAvatar : public LLFacePool
 									  const LLMeshSkinInfo* skin, 
 									  LLVolume* volume,
 									  const LLVolumeFace& vol_face);
+	void updateRiggedVertexBuffers(LLVOAvatar* avatar);
 
 	void renderRigged(LLVOAvatar* avatar, U32 type, bool glow = false);
 	void renderRiggedSimple(LLVOAvatar* avatar);
@@ -176,6 +177,7 @@ class LLDrawPoolAvatar : public LLFacePool
 		RIGGED_FULLBRIGHT_SHINY_MASK = RIGGED_SIMPLE_MASK,							 
 		RIGGED_GLOW_MASK = LLVertexBuffer::MAP_VERTEX | 
 							 LLVertexBuffer::MAP_TEXCOORD0 |
+							 LLVertexBuffer::MAP_EMISSIVE |
 							 LLVertexBuffer::MAP_WEIGHT4,
 		RIGGED_ALPHA_MASK = RIGGED_SIMPLE_MASK,
 		RIGGED_FULLBRIGHT_ALPHA_MASK = RIGGED_FULLBRIGHT_MASK,
@@ -214,7 +216,6 @@ class LLVertexBufferAvatar : public LLVertexBuffer
 {
 public:
 	LLVertexBufferAvatar();
-	virtual void setupVertexBuffer(U32 data_mask) const;
 };
 
 extern S32 AVATAR_OFFSET_POS;
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 0742250b0b995b973cf0a5debad9eba4e139e9e4..7b9fb2b34bb47989db65eabc16197b2d8ccd838b 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -763,7 +763,7 @@ void LLDrawPoolBump::renderBump(U32 pass)
 	LLGLDisable fog(GL_FOG);
 	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_LEQUAL);
 	LLGLEnable blend(GL_BLEND);
-	glColor4f(1,1,1,1);
+	gGL.diffuseColor4f(1,1,1,1);
 	/// Get rid of z-fighting with non-bump pass.
 	LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
 	glPolygonOffset(-1.0f, -1.0f);
@@ -786,7 +786,7 @@ void LLDrawPoolBump::endBump(U32 pass)
 	{
 		// Disable texture blending on unit 1
 		gGL.getTexUnit(1)->activate();
-		//gGL.getTexUnit(1)->disable();
+		gGL.getTexUnit(1)->disable();
 		gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT);
 
 		// Disable texture blending on unit 0
@@ -1088,6 +1088,8 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText
 }
 
 
+static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_STANDARD_LOADED("Bump Standard Callback");
+
 // static
 void LLBumpImageList::onSourceBrightnessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
 {
@@ -1110,14 +1112,24 @@ void LLBumpImageList::onSourceDarknessLoaded( BOOL success, LLViewerFetchedTextu
 	}
 }
 
+static LLFastTimer::DeclareTimer FTM_BUMP_GEN_NORMAL("Generate Normal Map");
+static LLFastTimer::DeclareTimer FTM_BUMP_CREATE_TEXTURE("Create GL Normal Map");
+
 void LLBumpImageList::onSourceStandardLoaded( BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)
 {
 	if (success && LLPipeline::sRenderDeferred)
 	{
+		LLFastTimer t(FTM_BUMP_SOURCE_STANDARD_LOADED);
 		LLPointer<LLImageRaw> nrm_image = new LLImageRaw(src->getWidth(), src->getHeight(), 4);
-		generateNormalMapFromAlpha(src, nrm_image);
+		{
+			LLFastTimer t(FTM_BUMP_GEN_NORMAL);
+			generateNormalMapFromAlpha(src, nrm_image);
+		}
 		src_vi->setExplicitFormat(GL_RGBA, GL_RGBA);
-		src_vi->createGLTexture(src_vi->getDiscardLevel(), nrm_image);
+		{
+			LLFastTimer t(FTM_BUMP_CREATE_TEXTURE);
+			src_vi->createGLTexture(src_vi->getDiscardLevel(), nrm_image);
+		}
 	}
 }
 
@@ -1176,24 +1188,39 @@ void LLBumpImageList::generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nr
 	}
 }
 
+
+static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_LOADED("Bump Source Loaded");
+static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_ENTRIES_UPDATE("Entries Update");
+static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_MIN_MAX("Min/Max");
+static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_RGB2LUM("RGB to Luminance");
+static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_RESCALE("Rescale");
+static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_GEN_NORMAL("Generate Normal");
+static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_CREATE("Create");
+
 // static
 void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump_code )
 {
 	if( success )
 	{
+		LLFastTimer t(FTM_BUMP_SOURCE_LOADED);
+
+
 		bump_image_map_t& entries_list(bump_code == BE_BRIGHTNESS ? gBumpImageList.mBrightnessEntries : gBumpImageList.mDarknessEntries );
 		bump_image_map_t::iterator iter = entries_list.find(source_asset_id);
 
-		if (iter == entries_list.end() ||
-			iter->second.isNull() ||
-                        iter->second->getWidth() != src->getWidth() ||
-                        iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution
-		{ //make sure an entry exists for this image
-			LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,1);
-			raw->clear(0x77, 0x77, 0xFF, 0xFF);
-
-			entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture( raw.get(), TRUE);
-			iter = entries_list.find(src_vi->getID());
+		{
+			LLFastTimer t(FTM_BUMP_SOURCE_ENTRIES_UPDATE);
+			if (iter == entries_list.end() ||
+				iter->second.isNull() ||
+							iter->second->getWidth() != src->getWidth() ||
+							iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution
+			{ //make sure an entry exists for this image
+				LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,1);
+				raw->clear(0x77, 0x77, 0xFF, 0xFF);
+
+				entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture( raw.get(), TRUE);
+				iter = entries_list.find(src_vi->getID());
+			}
 		}
 
 		//if (iter->second->getWidth() != src->getWidth() ||
@@ -1224,50 +1251,56 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
 			{
 			case 1:
 			case 2:
-				if( src_data_size == dst_data_size * src_components )
 				{
-					for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components )
+					LLFastTimer t(FTM_BUMP_SOURCE_MIN_MAX);
+					if( src_data_size == dst_data_size * src_components )
 					{
-						dst_data[i] = src_data[j];
-						if( dst_data[i] < minimum )
-						{
-							minimum = dst_data[i];
-						}
-						if( dst_data[i] > maximum )
+						for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components )
 						{
-							maximum = dst_data[i];
+							dst_data[i] = src_data[j];
+							if( dst_data[i] < minimum )
+							{
+								minimum = dst_data[i];
+							}
+							if( dst_data[i] > maximum )
+							{
+								maximum = dst_data[i];
+							}
 						}
 					}
-				}
-				else
-				{
-					llassert(0);
-					dst_image->clear();
+					else
+					{
+						llassert(0);
+						dst_image->clear();
+					}
 				}
 				break;
 			case 3:
 			case 4:
-				if( src_data_size == dst_data_size * src_components )
 				{
-					for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components )
+					LLFastTimer t(FTM_BUMP_SOURCE_RGB2LUM);
+					if( src_data_size == dst_data_size * src_components )
 					{
-						// RGB to luminance
-						dst_data[i] = (R_WEIGHT * src_data[j] + G_WEIGHT * src_data[j+1] + B_WEIGHT * src_data[j+2]) >> FIXED_PT;
-						//llassert( dst_data[i] <= 255 );true because it's 8bit
-						if( dst_data[i] < minimum )
-						{
-							minimum = dst_data[i];
-						}
-						if( dst_data[i] > maximum )
+						for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components )
 						{
-							maximum = dst_data[i];
+							// RGB to luminance
+							dst_data[i] = (R_WEIGHT * src_data[j] + G_WEIGHT * src_data[j+1] + B_WEIGHT * src_data[j+2]) >> FIXED_PT;
+							//llassert( dst_data[i] <= 255 );true because it's 8bit
+							if( dst_data[i] < minimum )
+							{
+								minimum = dst_data[i];
+							}
+							if( dst_data[i] > maximum )
+							{
+								maximum = dst_data[i];
+							}
 						}
 					}
-				}
-				else
-				{
-					llassert(0);
-					dst_image->clear();
+					else
+					{
+						llassert(0);
+						dst_image->clear();
+					}
 				}
 				break;
 			default:
@@ -1278,6 +1311,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
 
 			if( maximum > minimum )
 			{
+				LLFastTimer t(FTM_BUMP_SOURCE_RESCALE);
 				U8 bias_and_scale_lut[256];
 				F32 twice_one_over_range = 2.f / (maximum - minimum);
 				S32 i;
@@ -1311,17 +1345,63 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
 			// accidentally releases it.
 			LLPointer<LLViewerTexture> bump = LLViewerTextureManager::getLocalTexture( TRUE );
 			
+			
 			if (!LLPipeline::sRenderDeferred)
 			{
+				LLFastTimer t(FTM_BUMP_SOURCE_CREATE);
 				bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA);
 				bump->createGLTexture(0, dst_image);
 			}
-			else
-			{
-				LLPointer<LLImageRaw> nrm_image = new LLImageRaw(dst_image->getWidth(), dst_image->getHeight(), 4);
-				generateNormalMapFromAlpha(dst_image, nrm_image);
-				bump->setExplicitFormat(GL_RGBA, GL_RGBA);
-				bump->createGLTexture(0, nrm_image);
+			else 
+			{ //convert to normal map
+				{
+					LLFastTimer t(FTM_BUMP_SOURCE_CREATE);
+					bump->setExplicitFormat(GL_RGBA8, GL_ALPHA);
+					bump->createGLTexture(0, dst_image);
+				}
+
+				{
+					LLFastTimer t(FTM_BUMP_SOURCE_GEN_NORMAL);
+					gPipeline.mScreen.bindTarget();
+					LLGLDepthTest depth(GL_FALSE);
+					LLGLDisable cull(GL_CULL_FACE);
+					LLGLDisable blend(GL_BLEND);
+					gGL.setColorMask(TRUE, TRUE);
+					gNormalMapGenProgram.bind();
+					gNormalMapGenProgram.uniform1f("norm_scale", gSavedSettings.getF32("RenderNormalMapScale"));
+					gNormalMapGenProgram.uniform1f("stepX", 1.f/bump->getWidth());
+					gNormalMapGenProgram.uniform1f("stepY", 1.f/bump->getHeight());
+
+					LLVector2 v((F32) bump->getWidth()/gPipeline.mScreen.getWidth(),
+								(F32) bump->getHeight()/gPipeline.mScreen.getHeight());
+
+					gGL.getTexUnit(0)->bind(bump);
+					
+					gGL.begin(LLRender::TRIANGLE_STRIP);
+
+					gGL.texCoord2f(0, 0);
+					gGL.vertex2f(0, 0);
+					gGL.texCoord2f(0, 1);
+					gGL.vertex2f(0, v.mV[1]);
+					gGL.texCoord2f(1, 0);
+					gGL.vertex2f(v.mV[0], 0);
+					gGL.texCoord2f(1, 1);
+					gGL.vertex2f(v.mV[0], v.mV[1]);
+
+					gGL.end();
+
+					gGL.flush();
+
+					glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, bump->getWidth(), bump->getHeight());
+
+					glGenerateMipmap(GL_TEXTURE_2D);
+
+					gPipeline.mScreen.flush();
+
+					gNormalMapGenProgram.unbind();
+										
+					//generateNormalMapFromAlpha(dst_image, nrm_image);
+				}
 			}
 		
 			iter->second = bump; // derefs (and deletes) old image
@@ -1369,18 +1449,24 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
 			if (mShiny)
 			{
 				gGL.getTexUnit(0)->activate();
-				glMatrixMode(GL_TEXTURE);
+				gGL.matrixMode(LLRender::MM_TEXTURE);
 			}
 			else
 			{
-				gGL.getTexUnit(1)->activate();
-				glMatrixMode(GL_TEXTURE);
-				glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);
-				gPipeline.mTextureMatrixOps++;
+				if (!LLGLSLShader::sNoFixedFunction)
+				{
+					gGL.getTexUnit(1)->activate();
+					gGL.matrixMode(LLRender::MM_TEXTURE);
+					gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
+				}
+
 				gGL.getTexUnit(0)->activate();
+				gGL.matrixMode(LLRender::MM_TEXTURE);
+				gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
+				gPipeline.mTextureMatrixOps++;
 			}
 
-			glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);
+			gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
 			gPipeline.mTextureMatrixOps++;
 
 			tex_setup = true;
@@ -1390,7 +1476,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
 		{
 			if (params.mTexture.notNull())
 			{
-				gGL.getTexUnit(diffuse_channel)->bind(params.mTexture) ;
+				gGL.getTexUnit(diffuse_channel)->bind(params.mTexture);
 				params.mTexture->addTextureStats(params.mVSize);		
 			}
 			else
@@ -1415,12 +1501,17 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
 		}
 		else
 		{
-			gGL.getTexUnit(1)->activate();
-			glLoadIdentity();
+			if (!LLGLSLShader::sNoFixedFunction)
+			{
+				gGL.getTexUnit(1)->activate();
+				gGL.matrixMode(LLRender::MM_TEXTURE);
+				gGL.loadIdentity();
+			}
 			gGL.getTexUnit(0)->activate();
+			gGL.matrixMode(LLRender::MM_TEXTURE);
 		}
-		glLoadIdentity();
-		glMatrixMode(GL_MODELVIEW);
+		gGL.loadIdentity();
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
 	}
 }
 
@@ -1465,6 +1556,7 @@ void LLDrawPoolInvisible::endDeferredPass( S32 pass )
 
 void LLDrawPoolInvisible::renderDeferred( S32 pass )
 { //render invisiprims; this doesn't work becaue it also blocks all the post-deferred stuff
+#if 0 
 	LLFastTimer t(FTM_RENDER_INVISIBLE);
   
 	U32 invisi_mask = LLVertexBuffer::MAP_VERTEX;
@@ -1482,4 +1574,5 @@ void LLDrawPoolInvisible::renderDeferred( S32 pass )
 		renderShiny(true);
 		endShiny(true);
 	}
+#endif
 }
diff --git a/indra/newview/lldrawpoolground.cpp b/indra/newview/lldrawpoolground.cpp
index ce07e62122de7d44ed340cd50344c9c485b84c09..59c3fbf7a125bf6ab727770e59ffc606d4bfeedc 100644
--- a/indra/newview/lldrawpoolground.cpp
+++ b/indra/newview/lldrawpoolground.cpp
@@ -71,9 +71,9 @@ void LLDrawPoolGround::render(S32 pass)
 	LLGLSquashToFarClip far_clip(glh_get_current_projection());
 
 	F32 water_height = gAgent.getRegion()->getWaterHeight();
-	glPushMatrix();
+	gGL.pushMatrix();
 	LLVector3 origin = LLViewerCamera::getInstance()->getOrigin();
-	glTranslatef(origin.mV[0], origin.mV[1], llmax(origin.mV[2], water_height));
+	gGL.translatef(origin.mV[0], origin.mV[1], llmax(origin.mV[2], water_height));
 
 	LLFace *facep = mDrawFace[0];
 
@@ -82,6 +82,6 @@ void LLDrawPoolGround::render(S32 pass)
 	LLOverrideFaceColor col(this, gSky.mVOSkyp->getGLFogColor());
 	facep->renderIndexed();
 	
-	glPopMatrix();
+	gGL.popMatrix();
 }
 
diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp
index eec4ee6bac99c75456d0c951b7914003f62096e7..80c202d4e2fd92698afd4177071529cf48440ea6 100644
--- a/indra/newview/lldrawpoolsimple.cpp
+++ b/indra/newview/lldrawpoolsimple.cpp
@@ -46,7 +46,7 @@ static LLFastTimer::DeclareTimer FTM_RENDER_GRASS_DEFERRED("Deferred Grass");
 
 void LLDrawPoolGlow::beginPostDeferredPass(S32 pass)
 {
-	gDeferredFullbrightProgram.bind();
+	gDeferredEmissiveProgram.bind();
 }
 
 static LLFastTimer::DeclareTimer FTM_RENDER_GLOW_PUSH("Glow Push");
@@ -76,10 +76,22 @@ void LLDrawPoolGlow::renderPostDeferred(S32 pass)
 
 void LLDrawPoolGlow::endPostDeferredPass(S32 pass)
 {
-	gDeferredFullbrightProgram.unbind();
+	gDeferredEmissiveProgram.unbind();
 	LLRenderPass::endRenderPass(pass);
 }
 
+S32 LLDrawPoolGlow::getNumPasses()
+{
+	if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0)
+	{
+		return 1;
+	}
+	else
+	{
+		return 0;
+	}
+}
+
 void LLDrawPoolGlow::render(S32 pass)
 {
 	LLFastTimer t(FTM_RENDER_GLOW);
@@ -93,39 +105,29 @@ void LLDrawPoolGlow::render(S32 pass)
 	
 	U32 shader_level = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
 
-	if (shader_level > 0 && fullbright_shader)
-	{
-		fullbright_shader->bind();
-	}
-	else
-	{
-		gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
-	}
+	//should never get here without basic shaders enabled
+	llassert(shader_level > 0);
+	
+	LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
+	shader->bind();
 
 	LLGLDepthTest depth(GL_TRUE, GL_FALSE);
 	gGL.setColorMask(false, true);
 
-	if (shader_level > 1)
-	{
-		pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-	}
-	else
-	{
-		renderTexture(LLRenderPass::PASS_GLOW, getVertexDataMask());
-	}
+	pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
 	
 	gGL.setColorMask(true, false);
 	gGL.setSceneBlendType(LLRender::BT_ALPHA);
 	
 	if (shader_level > 0 && fullbright_shader)
 	{
-		fullbright_shader->unbind();
+		shader->unbind();
 	}
 }
 
 void LLDrawPoolGlow::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
 {
-	glColor4ubv(params.mGlowColor.mV);
+	//gGL.diffuseColor4ubv(params.mGlowColor.mV);
 	LLRenderPass::pushBatch(params, mask, texture, batch_textures);
 }
 
@@ -253,6 +255,7 @@ void LLDrawPoolGrass::prerender()
 void LLDrawPoolGrass::beginRenderPass(S32 pass)
 {
 	LLFastTimer t(FTM_RENDER_GRASS);
+	stop_glerror();
 
 	if (LLPipeline::sUnderWaterRender)
 	{
diff --git a/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h
index 3811b3d398f872193cb6861e63c053f6f926e263..bd62bc75025fc7179ea257df5760c32b8ed1cf05 100644
--- a/indra/newview/lldrawpoolsimple.h
+++ b/indra/newview/lldrawpoolsimple.h
@@ -118,7 +118,8 @@ class LLDrawPoolGlow : public LLRenderPass
 	enum
 	{
 		VERTEX_DATA_MASK =	LLVertexBuffer::MAP_VERTEX |
-							LLVertexBuffer::MAP_TEXCOORD0
+							LLVertexBuffer::MAP_TEXCOORD0 |
+							LLVertexBuffer::MAP_EMISSIVE
 	};
 
 	virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
@@ -130,6 +131,8 @@ class LLDrawPoolGlow : public LLRenderPass
 	/*virtual*/ void endPostDeferredPass(S32 pass);
 	/*virtual*/ void renderPostDeferred(S32 pass);
 
+	/*virtual*/ S32 getNumPasses();
+
 	void render(S32 pass = 0);
 	void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
 
diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp
index efffb2df9e705ab96682a8c6c7c8ea3f8abe4288..7f7d9f65c60c048a26d02438e278dd21893f190f 100644
--- a/indra/newview/lldrawpoolsky.cpp
+++ b/indra/newview/lldrawpoolsky.cpp
@@ -76,15 +76,16 @@ void LLDrawPoolSky::render(S32 pass)
 		return;
 	}
 	
-	// use a shader only underwater
+	// don't render sky under water (background just gets cleared to fog color)
 	if(mVertexShaderLevel > 0 && LLPipeline::sUnderWaterRender)
 	{
-		mShader = &gObjectFullbrightWaterProgram;
-		mShader->bind();
+		return;
 	}
-	else if (LLGLSLShader::sNoFixedFunction)
+
+
+	if (LLGLSLShader::sNoFixedFunction)
 	{ //just use the UI shader (generic single texture no lighting)
-		gUIProgram.bind();
+		gOneTextureNoColorProgram.bind();
 	}
 	else
 	{
@@ -111,21 +112,21 @@ void LLDrawPoolSky::render(S32 pass)
 	
 	LLGLDisable clip(GL_CLIP_PLANE0);
 
-	glPushMatrix();
+	gGL.pushMatrix();
 	LLVector3 origin = LLViewerCamera::getInstance()->getOrigin();
-	glTranslatef(origin.mV[0], origin.mV[1], origin.mV[2]);
+	gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
 
 	S32 face_count = (S32)mDrawFace.size();
 
 	LLVertexBuffer::unbind();
-	glColor4f(1,1,1,1);
+	gGL.diffuseColor4f(1,1,1,1);
 
 	for (S32 i = 0; i < llmin(6, face_count); ++i)
 	{
 		renderSkyCubeFace(i);
 	}
 
-	glPopMatrix();
+	gGL.popMatrix();
 }
 
 void LLDrawPoolSky::renderSkyCubeFace(U8 side)
@@ -146,7 +147,7 @@ void LLDrawPoolSky::renderSkyCubeFace(U8 side)
 		
 		LLGLEnable blend(GL_BLEND);
 		mSkyTex[side].bindTexture(FALSE);
-		glColor4f(1, 1, 1, LLSkyTex::getInterpVal()); // lighting is disabled
+		gGL.diffuseColor4f(1, 1, 1, LLSkyTex::getInterpVal()); // lighting is disabled
 		face.renderIndexed();
 	}
 }
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 3daa0f8261f808ad247960da29ce766f83a3f5d2..ce601325c88ccd1c2f87ede6d676f3aecc969615 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -62,13 +62,16 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :
 	LLFacePool(POOL_TERRAIN),
 	mTexturep(texturep)
 {
+	U32 format = GL_ALPHA8;
+	U32 int_format = GL_ALPHA;
+
 	// Hack!
 	sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale");
 	sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");
 	mAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient.tga", 
 													TRUE, LLViewerTexture::BOOST_UI, 
 													LLViewerTexture::FETCHED_TEXTURE,
-													GL_ALPHA8, GL_ALPHA,
+													format, int_format,
 													LLUUID("e97cf410-8e61-7005-ec06-629eba4cd1fb"));
 
 	//gGL.getTexUnit(0)->bind(mAlphaRampImagep.get());
@@ -77,7 +80,7 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :
 	m2DAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient_2d.j2c", 
 													TRUE, LLViewerTexture::BOOST_UI, 
 													LLViewerTexture::FETCHED_TEXTURE,
-													GL_ALPHA8, GL_ALPHA,
+													format, int_format,
 													LLUUID("38b86f85-2575-52a9-a531-23108d8da837"));
 
 	//gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get());
@@ -106,6 +109,10 @@ U32 LLDrawPoolTerrain::getVertexDataMask()
 	{
 		return LLVertexBuffer::MAP_VERTEX;
 	}
+	else if (LLGLSLShader::sCurBoundShaderPtr)
+	{
+		return VERTEX_DATA_MASK & ~(LLVertexBuffer::MAP_TEXCOORD2 | LLVertexBuffer::MAP_TEXCOORD3);
+	}
 	else
 	{
 		return VERTEX_DATA_MASK; 
@@ -115,14 +122,7 @@ U32 LLDrawPoolTerrain::getVertexDataMask()
 void LLDrawPoolTerrain::prerender()
 {
 	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
-	if (mVertexShaderLevel > 0)
-	{
-		sDetailMode = 1;
-	}
-	else
-	{
-		sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");
-	}
+	sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");
 }
 
 void LLDrawPoolTerrain::beginRenderPass( S32 pass )
@@ -130,9 +130,24 @@ void LLDrawPoolTerrain::beginRenderPass( S32 pass )
 	LLFastTimer t(FTM_RENDER_TERRAIN);
 	LLFacePool::beginRenderPass(pass);
 
-	sShader = LLPipeline::sUnderWaterRender ? 
-					&gTerrainWaterProgram :
-					&gTerrainProgram;
+	if (sDetailMode > 0)
+	{
+		sShader = LLPipeline::sUnderWaterRender ? 
+						&gTerrainWaterProgram :
+						&gTerrainProgram;
+	}
+	else
+	{
+		if (LLPipeline::sUnderWaterRender)
+		{
+			sShader = &gObjectSimpleNonIndexedTexGenWaterProgram;
+		}
+		else
+		{
+			sShader = &gObjectSimpleNonIndexedTexGenProgram;
+		}
+	}
+					
 
 	if (mVertexShaderLevel > 1 && sShader->mShaderLevel > 0)
 	{
@@ -181,7 +196,7 @@ void LLDrawPoolTerrain::render(S32 pass)
 		return;
 	}
 	// Render simplified land if video card can't do sufficient multitexturing
-	if (!gGLManager.mHasARBEnvCombine || (gGLManager.mNumTextureUnits < 2))
+	if (!LLGLSLShader::sNoFixedFunction || !gGLManager.mHasARBEnvCombine || (gGLManager.mNumTextureUnits < 2))
 	{
 		renderSimple(); // Render without multitexture
 		return;
@@ -193,7 +208,15 @@ void LLDrawPoolTerrain::render(S32 pass)
 	if (mVertexShaderLevel > 1 && sShader->mShaderLevel > 0)
 	{
 		gPipeline.enableLightsDynamic();
-		renderFullShader();
+
+		if (sDetailMode > 0)
+		{
+			renderFullShader();
+		}
+		else
+		{
+			renderSimple();
+		}
 	}
 	else
 	{
@@ -312,16 +335,15 @@ void LLDrawPoolTerrain::renderFullShader()
 	gGL.getTexUnit(detail0)->bind(detail_texture0p);
 	gGL.getTexUnit(0)->activate();
 
-	glEnable(GL_TEXTURE_GEN_S);
-	glEnable(GL_TEXTURE_GEN_T);
-	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
-	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+	llassert(shader);
+		
+	shader->uniform4fv("object_plane_s", 1, tp0.mV);
+	shader->uniform4fv("object_plane_t", 1, tp1.mV);
 
-	glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
-	glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 
 	//
 	// detail texture 1
@@ -331,9 +353,9 @@ void LLDrawPoolTerrain::renderFullShader()
 	
 	/// ALPHA TEXTURE COORDS 0:
 	gGL.getTexUnit(1)->activate();
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	
 	// detail texture 2
 	//
@@ -343,10 +365,10 @@ void LLDrawPoolTerrain::renderFullShader()
 	gGL.getTexUnit(2)->activate();
 	
 	/// ALPHA TEXTURE COORDS 1:
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glTranslatef(-2.f, 0.f, 0.f);
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.translatef(-2.f, 0.f, 0.f);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 
 	//
 	// detail texture 3
@@ -356,10 +378,10 @@ void LLDrawPoolTerrain::renderFullShader()
 	
 	/// ALPHA TEXTURE COORDS 2:
 	gGL.getTexUnit(3)->activate();
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glTranslatef(-1.f, 0.f, 0.f);
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.translatef(-1.f, 0.f, 0.f);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 
 	//
 	// Alpha Ramp 
@@ -380,38 +402,30 @@ void LLDrawPoolTerrain::renderFullShader()
 	gGL.getTexUnit(alpha_ramp)->unbind(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(4)->disable();
 	gGL.getTexUnit(4)->activate();
-	glDisable(GL_TEXTURE_GEN_S);
-	glDisable(GL_TEXTURE_GEN_T);
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glMatrixMode(GL_MODELVIEW);
-
+	
 	gGL.getTexUnit(detail3)->unbind(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(3)->disable();
 	gGL.getTexUnit(3)->activate();
-	glDisable(GL_TEXTURE_GEN_S);
-	glDisable(GL_TEXTURE_GEN_T);
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glMatrixMode(GL_MODELVIEW);
+	
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 
 	gGL.getTexUnit(detail2)->unbind(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(2)->disable();
 	gGL.getTexUnit(2)->activate();
-	glDisable(GL_TEXTURE_GEN_S);
-	glDisable(GL_TEXTURE_GEN_T);
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glMatrixMode(GL_MODELVIEW);
+	
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 
 	gGL.getTexUnit(detail1)->unbind(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(1)->disable();
 	gGL.getTexUnit(1)->activate();
-	glDisable(GL_TEXTURE_GEN_S);
-	glDisable(GL_TEXTURE_GEN_T);
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glMatrixMode(GL_MODELVIEW);
+	
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	
 	//----------------------------------------------------------------------------
 	// Restore Texture Unit 0 defaults
@@ -419,11 +433,9 @@ void LLDrawPoolTerrain::renderFullShader()
 	gGL.getTexUnit(detail0)->unbind(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(0)->activate();
-	glDisable(GL_TEXTURE_GEN_S);
-	glDisable(GL_TEXTURE_GEN_T);
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 }
 
 void LLDrawPoolTerrain::renderFull4TU()
@@ -534,9 +546,9 @@ void LLDrawPoolTerrain::renderFull4TU()
 	gGL.getTexUnit(1)->activate();
 
 	// Set the texture matrix
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glTranslatef(-2.f, 0.f, 0.f);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.translatef(-2.f, 0.f, 0.f);
 
 	// Care about alpha only
 	gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
@@ -566,9 +578,9 @@ void LLDrawPoolTerrain::renderFull4TU()
 	gGL.getTexUnit(3)->activate();
 
 	// Set the texture matrix
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glTranslatef(-1.f, 0.f, 0.f);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.translatef(-1.f, 0.f, 0.f);
   
 	// Set alpha texture and do lighting modulation
 	gGL.getTexUnit(3)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_PREV_COLOR, LLTexUnit::TBS_VERT_COLOR);
@@ -586,9 +598,9 @@ void LLDrawPoolTerrain::renderFull4TU()
 	gGL.getTexUnit(3)->disable();
 	gGL.getTexUnit(3)->activate();
 	
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 
 	gGL.getTexUnit(2)->unbind(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(2)->disable();
@@ -596,17 +608,17 @@ void LLDrawPoolTerrain::renderFull4TU()
 	
 	glDisable(GL_TEXTURE_GEN_S);
 	glDisable(GL_TEXTURE_GEN_T);
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 
 	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);	
 	gGL.getTexUnit(1)->disable();
 	gGL.getTexUnit(1)->activate();
  	
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 
 	// Restore blend state
 	gGL.setSceneBlendType(LLRender::BT_ALPHA);
@@ -620,9 +632,9 @@ void LLDrawPoolTerrain::renderFull4TU()
 	
 	glDisable(GL_TEXTURE_GEN_S);
 	glDisable(GL_TEXTURE_GEN_T);
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 
 	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
 }
@@ -714,9 +726,9 @@ void LLDrawPoolTerrain::renderFull2TU()
 	gGL.getTexUnit(0)->bind(m2DAlphaRampImagep);
 
 	// Set the texture matrix
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glTranslatef(-1.f, 0.f, 0.f);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.translatef(-1.f, 0.f, 0.f);
 
 	// Care about alpha only
 	gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
@@ -753,9 +765,9 @@ void LLDrawPoolTerrain::renderFull2TU()
 	gGL.getTexUnit(0)->activate();
 	gGL.getTexUnit(0)->bind(m2DAlphaRampImagep);
 	// Set the texture matrix
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glTranslatef(-2.f, 0.f, 0.f);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.translatef(-2.f, 0.f, 0.f);
 
 	// Care about alpha only
 	gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
@@ -793,9 +805,9 @@ void LLDrawPoolTerrain::renderFull2TU()
 
 	glDisable(GL_TEXTURE_GEN_S);
 	glDisable(GL_TEXTURE_GEN_T);
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 
 	//----------------------------------------------------------------------------
 	// Restore Texture Unit 0 defaults
@@ -805,9 +817,9 @@ void LLDrawPoolTerrain::renderFull2TU()
 
 	glDisable(GL_TEXTURE_GEN_S);
 	glDisable(GL_TEXTURE_GEN_T);
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
 }
 
@@ -831,13 +843,21 @@ void LLDrawPoolTerrain::renderSimple()
 	tp0.setVec(tscale, 0.f, 0.0f, -1.f*(origin_agent.mV[0]/256.f));
 	tp1.setVec(0.f, tscale, 0.0f, -1.f*(origin_agent.mV[1]/256.f));
 	
-	glEnable(GL_TEXTURE_GEN_S);
-	glEnable(GL_TEXTURE_GEN_T);
-	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
-	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
-	glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
-	glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
-	
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		sShader->uniform4fv("object_plane_s", 1, tp0.mV);
+		sShader->uniform4fv("object_plane_t", 1, tp1.mV);
+	}
+	else
+	{
+		glEnable(GL_TEXTURE_GEN_S);
+		glEnable(GL_TEXTURE_GEN_T);
+		glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+		glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+		glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
+		glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
+	}
+
 	gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR);
 
 	drawLoop();
@@ -847,11 +867,14 @@ void LLDrawPoolTerrain::renderSimple()
 	
 	gGL.getTexUnit(0)->activate();
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-	glDisable(GL_TEXTURE_GEN_S);
-	glDisable(GL_TEXTURE_GEN_T);
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glMatrixMode(GL_MODELVIEW);
+	if (!LLGLSLShader::sNoFixedFunction)
+	{
+		glDisable(GL_TEXTURE_GEN_S);
+		glDisable(GL_TEXTURE_GEN_T);
+	}
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
 }
 
@@ -882,11 +905,11 @@ void LLDrawPoolTerrain::renderOwnership()
 	// texture coordinates for pixel 256x256 is not 1,1. This makes the
 	// ownership map not line up with the selection. We address this with
 	// a texture matrix multiply.
-	glMatrixMode(GL_TEXTURE);
-	glPushMatrix();
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.pushMatrix();
 
 	const F32 TEXTURE_FUDGE = 257.f / 256.f;
-	glScalef( TEXTURE_FUDGE, TEXTURE_FUDGE, 1.f );
+	gGL.scalef( TEXTURE_FUDGE, TEXTURE_FUDGE, 1.f );
 	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
 		 iter != mDrawFace.end(); iter++)
 	{
@@ -895,9 +918,9 @@ void LLDrawPoolTerrain::renderOwnership()
 							LLVertexBuffer::MAP_TEXCOORD0);
 	}
 
-	glMatrixMode(GL_TEXTURE);
-	glPopMatrix();
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.popMatrix();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 }
 
 
diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp
index a6e01511147ad195682099d091ddd481cdd6cd46..cdf6e1ab5230b1a42adabe3ee4b13a9a835d59e0 100644
--- a/indra/newview/lldrawpooltree.cpp
+++ b/indra/newview/lldrawpooltree.cpp
@@ -65,17 +65,18 @@ void LLDrawPoolTree::beginRenderPass(S32 pass)
 		
 	if (LLPipeline::sUnderWaterRender)
 	{
-		shader = &gObjectAlphaMaskNonIndexedWaterProgram;
+		shader = &gTreeWaterProgram;
 	}
 	else
 	{
-		shader = &gObjectAlphaMaskNonIndexedProgram;
+		shader = &gTreeProgram;
 	}
 
 	if (gPipeline.canUseVertexShaders())
 	{
 		shader->bind();
 		shader->setAlphaRange(0.5f, 1.f);
+		gGL.diffuseColor4f(1,1,1,1);
 	}
 	else
 	{
@@ -112,8 +113,8 @@ void LLDrawPoolTree::render(S32 pass)
 			if(buff)
 			{
 				buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
-				buff->drawRange(LLRender::TRIANGLES, 0, buff->getRequestedVerts()-1, buff->getRequestedIndices(), 0); 
-				gPipeline.addTrianglesDrawn(buff->getRequestedIndices());
+				buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0); 
+				gPipeline.addTrianglesDrawn(buff->getNumIndices());
 			}
 		}
 	}
@@ -141,7 +142,7 @@ void LLDrawPoolTree::beginDeferredPass(S32 pass)
 {
 	LLFastTimer t(FTM_RENDER_TREES);
 		
-	shader = &gDeferredNonIndexedDiffuseAlphaMaskProgram;
+	shader = &gDeferredTreeProgram;
 	shader->bind();
 	shader->setAlphaRange(0.5f, 1.f);
 }
@@ -168,8 +169,8 @@ void LLDrawPoolTree::beginShadowPass(S32 pass)
 	glPolygonOffset(gSavedSettings.getF32("RenderDeferredTreeShadowOffset"),
 					gSavedSettings.getF32("RenderDeferredTreeShadowBias"));
 
-	gDeferredShadowAlphaMaskProgram.bind();
-	gDeferredShadowAlphaMaskProgram.setAlphaRange(0.5f, 1.f);
+	gDeferredTreeShadowProgram.bind();
+	gDeferredTreeShadowProgram.setAlphaRange(0.5f, 1.f);
 }
 
 void LLDrawPoolTree::renderShadow(S32 pass)
@@ -183,6 +184,7 @@ void LLDrawPoolTree::endShadowPass(S32 pass)
 	
 	glPolygonOffset(gSavedSettings.getF32("RenderDeferredSpotShadowOffset"),
 						gSavedSettings.getF32("RenderDeferredSpotShadowBias"));
+	gDeferredTreeShadowProgram.unbind();
 }
 
 
@@ -195,7 +197,7 @@ void LLDrawPoolTree::renderTree(BOOL selecting)
 		
 	U32 indices_drawn = 0;
 
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	
 	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
 		 iter != mDrawFace.end(); iter++)
@@ -226,8 +228,8 @@ void LLDrawPoolTree::renderTree(BOOL selecting)
 			}
 			
 			gGLLastMatrix = NULL;
-			glLoadMatrixd(gGLModelView);
-			//glPushMatrix();
+			gGL.loadMatrix(gGLModelView);
+			//gGL.pushMatrix();
 			F32 mat[16];
 			for (U32 i = 0; i < 16; i++)
 				mat[i] = (F32) gGLModelView[i];
@@ -236,7 +238,7 @@ void LLDrawPoolTree::renderTree(BOOL selecting)
 			
 			// Translate to tree base  HACK - adjustment in Z plants tree underground
 			const LLVector3 &pos_agent = treep->getPositionAgent();
-			//glTranslatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f);
+			//gGL.translatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f);
 			LLMatrix4 trans_mat;
 			trans_mat.setTranslation(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f);
 			trans_mat *= matrix;
@@ -307,7 +309,7 @@ void LLDrawPoolTree::renderTree(BOOL selecting)
 				indices_drawn += treep->drawBranchPipeline(scale_mat, indicesp, trunk_LOD, stop_depth, treep->mDepth, treep->mTrunkDepth, 1.0, treep->mTwist, droop, treep->mBranches, alpha);
 			}
 			
-			//glPopMatrix();
+			//gGL.popMatrix();
 		}
 	}
 }
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 31c14361b5f1ecc93e8deb6b1eff517d2ba1bd56..4f6eaa5a5b778b099e53e65cf599ff26d088be7a 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -59,6 +59,8 @@ BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE;
 BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE;
 BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE;
 LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f);
+F32 LLDrawPoolWater::sWaterFogEnd = 0.f;
+
 LLVector3 LLDrawPoolWater::sLightDir;
 
 LLDrawPoolWater::LLDrawPoolWater() :
@@ -219,7 +221,7 @@ void LLDrawPoolWater::render(S32 pass)
 		water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
 	}
 
-	glColor4fv(water_color.mV);
+	gGL.diffuseColor4fv(water_color.mV);
 
 	// Automatically generate texture coords for detail map
 	glEnable(GL_TEXTURE_GEN_S); //texture unit 1
@@ -275,15 +277,15 @@ void LLDrawPoolWater::render(S32 pass)
 		gSky.mVOSkyp->getCubeMap()->enable(0);
 		gSky.mVOSkyp->getCubeMap()->bind();
 
-		glMatrixMode(GL_TEXTURE);
-		glLoadIdentity();
+		gGL.matrixMode(LLRender::MM_TEXTURE);
+		gGL.loadIdentity();
 		LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview();
 		LLMatrix4 camera_rot(camera_mat.getMat3());
 		camera_rot.invert();
 
-		glLoadMatrixf((F32 *)camera_rot.mMatrix);
+		gGL.loadMatrix((F32 *)camera_rot.mMatrix);
 
-		glMatrixMode(GL_MODELVIEW);
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
 		LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f,  0.5f*up_dot);
 
 		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
@@ -310,9 +312,9 @@ void LLDrawPoolWater::render(S32 pass)
 		
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
-		glMatrixMode(GL_TEXTURE);
-		glLoadIdentity();
-		glMatrixMode(GL_MODELVIEW);
+		gGL.matrixMode(LLRender::MM_TEXTURE);
+		gGL.loadIdentity();
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
 		
 	}
 
@@ -332,6 +334,21 @@ void LLDrawPoolWater::renderOpaqueLegacyWater()
 {
 	LLVOSky *voskyp = gSky.mVOSkyp;
 
+	LLGLSLShader* shader = NULL;
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		if (LLPipeline::sUnderWaterRender)
+		{
+			shader = &gObjectSimpleNonIndexedTexGenWaterProgram;
+		}
+		else
+		{
+			shader = &gObjectSimpleNonIndexedTexGenProgram;
+		}
+
+		shader->bind();
+	}
+
 	stop_glerror();
 
 	// Depth sorting and write to depth buffer
@@ -354,10 +371,13 @@ void LLDrawPoolWater::renderOpaqueLegacyWater()
 	gGL.getTexUnit(0)->bind(mOpaqueWaterImagep);
 
 	// Automatically generate texture coords for water texture
-	glEnable(GL_TEXTURE_GEN_S); //texture unit 0
-	glEnable(GL_TEXTURE_GEN_T); //texture unit 0
-	glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
-	glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+	if (!shader)
+	{
+		glEnable(GL_TEXTURE_GEN_S); //texture unit 0
+		glEnable(GL_TEXTURE_GEN_T); //texture unit 0
+		glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+		glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+	}
 
 	// Use the fact that we know all water faces are the same size
 	// to save some computation
@@ -380,10 +400,18 @@ void LLDrawPoolWater::renderOpaqueLegacyWater()
 	F32 tp0[4] = { 16.f / 256.f, 0.0f, 0.0f, offset };
 	F32 tp1[4] = { 0.0f, 16.f / 256.f, 0.0f, offset };
 
-	glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
-	glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
+	if (!shader)
+	{
+		glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
+		glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
+	}
+	else
+	{
+		shader->uniform4fv("object_plane_s", 1, tp0);
+		shader->uniform4fv("object_plane_t", 1, tp1);
+	}
 
-	glColor3f(1.f, 1.f, 1.f);
+	gGL.diffuseColor3f(1.f, 1.f, 1.f);
 
 	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
 		 iter != mDrawFace.end(); iter++)
@@ -399,9 +427,12 @@ void LLDrawPoolWater::renderOpaqueLegacyWater()
 
 	stop_glerror();
 
-	// Reset the settings back to expected values
-	glDisable(GL_TEXTURE_GEN_S); //texture unit 0
-	glDisable(GL_TEXTURE_GEN_T); //texture unit 0
+	if (!shader)
+	{
+		// Reset the settings back to expected values
+		glDisable(GL_TEXTURE_GEN_S); //texture unit 0
+		glDisable(GL_TEXTURE_GEN_T); //texture unit 0
+	}
 
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
@@ -623,8 +654,6 @@ void LLDrawPoolWater::shade()
 		water_color.mV[3] = 0.9f;
 	}
 
-	glColor4fv(water_color.mV);
-
 	{
 		LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
 		LLGLDisable cullface(GL_CULL_FACE);
diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h
index 99b541ca5a384d1de939c9795e96b908f0265abd..aeeba179d6ca134c240ea7cf70ec4768a95cea20 100644
--- a/indra/newview/lldrawpoolwater.h
+++ b/indra/newview/lldrawpoolwater.h
@@ -49,6 +49,7 @@ class LLDrawPoolWater: public LLFacePool
 	static LLVector3 sLightDir;
 
 	static LLColor4 sWaterFogColor;
+	static F32 sWaterFogEnd;
 
 	enum
 	{
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 79a835fd14ef1e8f6950766ea8f23d8d03ced896..f2d077030cf0a8331004cf9d8ddfeb9855ae5bc8 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -100,12 +100,12 @@ void LLDrawPoolWLSky::beginRenderPass( S32 pass )
 {
 	sky_shader =
 		LLPipeline::sUnderWaterRender ?
-			&gObjectSimpleWaterProgram :
+			&gObjectFullbrightNoColorWaterProgram :
 			&gWLSkyProgram;
 
 	cloud_shader =
 			LLPipeline::sUnderWaterRender ?
-				&gObjectSimpleWaterProgram :
+				&gObjectFullbrightNoColorWaterProgram :
 				&gWLCloudProgram;
 }
 
@@ -130,33 +130,33 @@ void LLDrawPoolWLSky::renderDome(F32 camHeightLocal, LLGLSLShader * shader) cons
 
 	llassert_always(NULL != shader);
 
-	glPushMatrix();
+	gGL.pushMatrix();
 
 	//chop off translation
 	if (LLPipeline::sReflectionRender && origin.mV[2] > 256.f)
 	{
-		glTranslatef(origin.mV[0], origin.mV[1], 256.f-origin.mV[2]*0.5f);
+		gGL.translatef(origin.mV[0], origin.mV[1], 256.f-origin.mV[2]*0.5f);
 	}
 	else
 	{
-		glTranslatef(origin.mV[0], origin.mV[1], origin.mV[2]);
+		gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
 	}
 		
 
 	// the windlight sky dome works most conveniently in a coordinate system
 	// where Y is up, so permute our basis vectors accordingly.
-	glRotatef(120.f, 1.f / F_SQRT3, 1.f / F_SQRT3, 1.f / F_SQRT3);
+	gGL.rotatef(120.f, 1.f / F_SQRT3, 1.f / F_SQRT3, 1.f / F_SQRT3);
 
-	glScalef(0.333f, 0.333f, 0.333f);
+	gGL.scalef(0.333f, 0.333f, 0.333f);
 
-	glTranslatef(0.f,-camHeightLocal, 0.f);
+	gGL.translatef(0.f,-camHeightLocal, 0.f);
 	
 	// Draw WL Sky	
 	shader->uniform3f("camPosLocal", 0.f, camHeightLocal, 0.f);
 
 	gSky.mVOWLSkyp->drawDome();
 
-	glPopMatrix();
+	gGL.popMatrix();
 }
 
 void LLDrawPoolWLSky::renderSkyHaze(F32 camHeightLocal) const
@@ -197,7 +197,7 @@ void LLDrawPoolWLSky::renderStars(void) const
 	gGL.getTexUnit(0)->bind(gSky.mVOSkyp->getBloomTex());
 
 	gGL.pushMatrix();
-	glRotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f);
+	gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f);
 	// gl_FragColor.rgb = gl_Color.rgb;
 	// gl_FragColor.a = gl_Color.a * star_alpha.a;
 	if (LLGLSLShader::sNoFixedFunction)
@@ -269,7 +269,7 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
 	{
 		if (gPipeline.canUseVertexShaders())
 		{
-			gUIProgram.bind();
+			gHighlightProgram.bind();
 		}
 		// *NOTE: even though we already bound this texture above for the
 		// stars register combiners, we bind again here for defensive reasons,
@@ -289,7 +289,7 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
 
 		if (gPipeline.canUseVertexShaders())
 		{
-			gUIProgram.unbind();
+			gHighlightProgram.unbind();
 		}
 	}
 }
@@ -315,10 +315,10 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass)
 	renderSkyHaze(camHeightLocal);
 
 	LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
-	glPushMatrix();
+	gGL.pushMatrix();
 
 		
-		glTranslatef(origin.mV[0], origin.mV[1], origin.mV[2]);
+		gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
 
 		gDeferredStarProgram.bind();
 		// *NOTE: have to bind a texture here since register combiners blending in
@@ -332,7 +332,7 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass)
 		
 		gDeferredStarProgram.unbind();
 
-	glPopMatrix();
+	gGL.popMatrix();
 
 	renderSkyClouds(camHeightLocal);
 
@@ -360,9 +360,9 @@ void LLDrawPoolWLSky::render(S32 pass)
 	renderSkyHaze(camHeightLocal);
 
 	LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
-	glPushMatrix();
+	gGL.pushMatrix();
 
-		glTranslatef(origin.mV[0], origin.mV[1], origin.mV[2]);
+		gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
 
 		// *NOTE: have to bind a texture here since register combiners blending in
 		// renderStars() requires something to be bound and we might as well only
@@ -374,7 +374,7 @@ void LLDrawPoolWLSky::render(S32 pass)
 		renderStars();
 		
 
-	glPopMatrix();
+	gGL.popMatrix();
 
 	renderSkyClouds(camHeightLocal);
 
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index fb9958ee9dd52affbea8ee0538be67a76037105e..5d6081a35cfc0f3e8c64f5d9c6ddc48073aaa168 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -41,6 +41,7 @@
 #include "llviewerdisplay.h"
 #include "llrender.h"
 #include "pipeline.h"
+#include "llglslshader.h"
 
 // static
 LLViewerDynamicTexture::instance_list_t LLViewerDynamicTexture::sInstances[ LLViewerDynamicTexture::ORDER_COUNT ];
@@ -207,6 +208,9 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
 		return TRUE;
 	}
 
+	LLGLSLShader::bindNoShader();
+	LLVertexBuffer::unbind();
+	
 	BOOL result = FALSE;
 	BOOL ret = FALSE ;
 	for( S32 order = 0; order < ORDER_COUNT; order++ )
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 432e61f6d8479c593e6b3025529d155a56308a84..eab3dcfaddb7ba46d34de82cab4811056690b1c3 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -496,14 +496,14 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
 		gGL.pushMatrix();
 		if (mDrawablep->isActive())
 		{
-			glMultMatrixf((GLfloat*)mDrawablep->getRenderMatrix().mMatrix);
+			gGL.multMatrix((GLfloat*)mDrawablep->getRenderMatrix().mMatrix);
 		}
 		else
 		{
-			glMultMatrixf((GLfloat*)mDrawablep->getRegion()->mRenderMatrix.mMatrix);
+			gGL.multMatrix((GLfloat*)mDrawablep->getRegion()->mRenderMatrix.mMatrix);
 		}
 
-		glColor4fv(color.mV);
+		gGL.diffuseColor4fv(color.mV);
 	
 		if (mDrawablep->isState(LLDrawable::RIGGED))
 		{
@@ -515,7 +515,7 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
 				{
 					LLGLEnable offset(GL_POLYGON_OFFSET_FILL);
 					glPolygonOffset(-1.f, -1.f);
-					glMultMatrixf((F32*) volume->getRelativeXform().mMatrix);
+					gGL.multMatrix((F32*) volume->getRelativeXform().mMatrix);
 					const LLVolumeFace& vol_face = rigged->getVolumeFace(getTEOffset());
 					LLVertexBuffer::unbind();
 					glVertexPointer(3, GL_FLOAT, 16, vol_face.mPositions);
@@ -524,6 +524,7 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
 						glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 						glTexCoordPointer(2, GL_FLOAT, 8, vol_face.mTexCoords);
 					}
+					gGL.syncMatrices();
 					glDrawElements(GL_TRIANGLES, vol_face.mNumIndices, GL_UNSIGNED_SHORT, vol_face.mIndices);
 					glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 				}
@@ -557,17 +558,17 @@ void LLFace::renderSelectedUV()
 
 	// add green dither pattern on top of red/blue gradient
 	gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_ONE);
-	glMatrixMode(GL_TEXTURE);
-	glPushMatrix();
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.pushMatrix();
 	// make green pattern repeat once per texel in red/blue texture
-	glScalef(256.f, 256.f, 1.f);
-	glMatrixMode(GL_MODELVIEW);
+	gGL.scalef(256.f, 256.f, 1.f);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 
 	renderSelected(green_imagep, LLColor4::white);
 
-	glMatrixMode(GL_TEXTURE);
-	glPopMatrix();
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.popMatrix();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
 }
 */
@@ -1055,6 +1056,7 @@ static LLFastTimer::DeclareTimer FTM_FACE_GEOM_POSITION("Position");
 static LLFastTimer::DeclareTimer FTM_FACE_GEOM_NORMAL("Normal");
 static LLFastTimer::DeclareTimer FTM_FACE_GEOM_TEXTURE("Texture");
 static LLFastTimer::DeclareTimer FTM_FACE_GEOM_COLOR("Color");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_EMISSIVE("Emissive");
 static LLFastTimer::DeclareTimer FTM_FACE_GEOM_WEIGHTS("Weights");
 static LLFastTimer::DeclareTimer FTM_FACE_GEOM_BINORMAL("Binormal");
 static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX("Index");
@@ -1071,6 +1073,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 	S32 num_vertices = (S32)vf.mNumVertices;
 	S32 num_indices = (S32) vf.mNumIndices;
 	
+	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE))
+	{
+		updateRebuildFlags();
+	}
+
 	bool map_range = gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange;
 
 	if (mVertexBuffer.notNull())
@@ -1124,6 +1131,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 	
 	bool rebuild_pos = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_POSITION);
 	bool rebuild_color = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_COLOR);
+	bool rebuild_emissive = rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE);
 	bool rebuild_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD);
 	bool rebuild_normal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
 	bool rebuild_binormal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_BINORMAL);
@@ -1213,7 +1221,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 
 		if (map_range)
 		{
-			mVertexBuffer->setBuffer(0);
+			mVertexBuffer->flush();
 		}
 	}
 	
@@ -1438,7 +1446,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 
 			if (map_range)
 			{
-				mVertexBuffer->setBuffer(0);
+				mVertexBuffer->flush();
 			}
 		}
 		else
@@ -1585,7 +1593,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 
 			if (map_range)
 			{
-				mVertexBuffer->setBuffer(0);
+				mVertexBuffer->flush();
 			}
 
 			if (do_bump)
@@ -1622,7 +1630,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 
 				if (map_range)
 				{
-					mVertexBuffer->setBuffer(0);
+					mVertexBuffer->flush();
 				}
 			}
 		}
@@ -1672,7 +1680,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 		
 		if (map_range)
 		{
-			mVertexBuffer->setBuffer(0);
+			mVertexBuffer->flush();
 		}
 	}
 		
@@ -1692,7 +1700,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 
 		if (map_range)
 		{
-			mVertexBuffer->setBuffer(0);
+			mVertexBuffer->flush();
 		}
 	}
 		
@@ -1712,7 +1720,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 
 		if (map_range)
 		{
-			mVertexBuffer->setBuffer(0);
+			mVertexBuffer->flush();
 		}
 	}
 	
@@ -1724,7 +1732,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 		LLVector4a::memcpyNonAliased16((F32*) weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32));
 		if (map_range)
 		{
-			mVertexBuffer->setBuffer(0);
+			mVertexBuffer->flush();
 		}
 	}
 
@@ -1754,10 +1762,48 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 
 		if (map_range)
 		{
-			mVertexBuffer->setBuffer(0);
+			mVertexBuffer->flush();
 		}
 	}
 
+	if (rebuild_emissive)
+	{
+		LLFastTimer t(FTM_FACE_GEOM_EMISSIVE);
+		LLStrider<LLColor4U> emissive;
+		mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount, map_range);
+
+		U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255);
+
+		LLVector4a src;
+
+		
+		U32 glow32 = glow |
+					 (glow << 8) |
+					 (glow << 16) |
+					 (glow << 24);
+
+		U32 vec[4];
+		vec[0] = vec[1] = vec[2] = vec[3] = glow32;
+		
+		src.loadua((F32*) vec);
+
+		LLVector4a* dst = (LLVector4a*) emissive.get();
+		S32 num_vecs = num_vertices/4;
+		if (num_vertices%4 > 0)
+		{
+			++num_vecs;
+		}
+
+		for (S32 i = 0; i < num_vecs; i++)
+		{	
+			dst[i] = src;
+		}
+
+		if (map_range)
+		{
+			mVertexBuffer->flush();
+		}
+	}
 	if (rebuild_tcoord)
 	{
 		mTexExtents[0].setVec(0,0);
@@ -2014,7 +2060,7 @@ BOOL LLFace::verify(const U32* indices_array) const
 	}
 	
 	// First, check whether the face data fits within the pool's range.
-	if ((mGeomIndex + mGeomCount) > mVertexBuffer->getRequestedVerts())
+	if ((mGeomIndex + mGeomCount) > mVertexBuffer->getNumVerts())
 	{
 		ok = FALSE;
 		llinfos << "Face references invalid vertices!" << llendl;
@@ -2033,7 +2079,7 @@ BOOL LLFace::verify(const U32* indices_array) const
 		llinfos << "Face has bogus indices count" << llendl;
 	}
 	
-	if (mIndicesIndex + mIndicesCount > mVertexBuffer->getRequestedIndices())
+	if (mIndicesIndex + mIndicesCount > mVertexBuffer->getNumIndices())
 	{
 		ok = FALSE;
 		llinfos << "Face references invalid indices!" << llendl;
@@ -2095,7 +2141,7 @@ void LLFace::renderSetColor() const
 	{
 		const LLColor4* color = &(getRenderColor());
 		
-		glColor4fv(color->mV);
+		gGL.diffuseColor4fv(color->mV);
 	}
 }
 
@@ -2130,10 +2176,10 @@ S32 LLFace::renderElements(const U16 *index_array) const
 	}
 	else
 	{
-		glPushMatrix();
-		glMultMatrixf((float*)getRenderMatrix().mMatrix);
+		gGL.pushMatrix();
+		gGL.multMatrix((float*)getRenderMatrix().mMatrix);
 		ret = pushVertices(index_array);
-		glPopMatrix();
+		gGL.popMatrix();
 	}
 	
 	return ret;
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index b5eaeecd60ea18c533f441e7c9b04c51386ef85f..82e4ab61b7d9d5695afbe08f0c929327eca019e6 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -329,13 +329,9 @@ class LLFace
 			{
 				return lhs->getTexture() < rhs->getTexture();
 			}
-			else if (lte->getBumpShinyFullbright() != rte->getBumpShinyFullbright())
-			{
-				return lte->getBumpShinyFullbright() < rte->getBumpShinyFullbright();
-			}
 			else 
 			{
-				return lte->getGlow() < rte->getGlow();
+				return lte->getBumpShinyFullbright() < rte->getBumpShinyFullbright();
 			}
 		}
 	};
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index a161428c2b99b2366a0775b3447ecbf08f8bb182..065dc5f4be9b9b473d4fd475fa4dbf547ee3263f 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -1125,10 +1125,10 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t
 	LLPointer<LLImageRaw> scratch = new LLImageRaw(1024, 512, 3);
 
 	gGL.pushMatrix();
-	glLoadIdentity();
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	glOrtho(-0.05, 1.05, -0.05, 1.05, -1.0, 1.0);
+	gGL.loadIdentity();
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.loadIdentity();
+	gGL.ortho(-0.05f, 1.05f, -0.05f, 1.05f, -1.0f, 1.0f);
 
 	//render charts
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -1367,7 +1367,7 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t
 	buffer.flush();
 
 	gGL.popMatrix();
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.popMatrix();
 }
 
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index db9a0424c0d66182c25ec07e5b99ac3ed6c6e5a0..08f9d267054cffb2662bd7a810e06bd2b59157b9 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -51,6 +51,7 @@
 #include "llcontrol.h"
 #include "llboost.h"
 #include "llweb.h"
+#include "llviewershadermgr.h"
 
 #if LL_WINDOWS
 #include "lldxhardware.h"
@@ -662,8 +663,10 @@ void LLFeatureManager::applyFeatures(bool skipFeatures)
 
 void LLFeatureManager::setGraphicsLevel(S32 level, bool skipFeatures)
 {
-	applyBaseMasks();
+	LLViewerShaderMgr::sSkipReload = true;
 
+	applyBaseMasks();
+	
 	switch (level)
 	{
 		case 0:
@@ -684,6 +687,9 @@ void LLFeatureManager::setGraphicsLevel(S32 level, bool skipFeatures)
 	}
 
 	applyFeatures(skipFeatures);
+
+	LLViewerShaderMgr::sSkipReload = false;
+	LLViewerShaderMgr::instance()->setShaders();
 }
 
 void LLFeatureManager::applyBaseMasks()
@@ -725,7 +731,7 @@ void LLFeatureManager::applyBaseMasks()
 	{
 		maskFeatures("NoPixelShaders");
 	}
-	if (!gGLManager.mHasVertexShader)
+	if (!gGLManager.mHasVertexShader || !mGPUSupported)
 	{
 		maskFeatures("NoVertexShaders");
 	}
diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp
index 1f334815d6a1e42c56232e051d6f6169cf4758a2..2a3512e21a922e334382aa9980e55a004aabff31 100644
--- a/indra/newview/llfloateranimpreview.cpp
+++ b/indra/newview/llfloateranimpreview.cpp
@@ -1063,14 +1063,19 @@ BOOL	LLPreviewAnimation::render()
 	mNeedsUpdate = FALSE;
 	LLVOAvatar* avatarp = mDummyAvatar;
 	
-	glMatrixMode(GL_PROJECTION);
+	gGL.matrixMode(LLRender::MM_PROJECTION);
 	gGL.pushMatrix();
-	glLoadIdentity();
-	glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
+	gGL.loadIdentity();
+	gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
 
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.pushMatrix();
-	glLoadIdentity();
+	gGL.loadIdentity();
+
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		gUIProgram.bind();
+	}
 
 	LLGLSUIDefault def;
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -1078,10 +1083,10 @@ BOOL	LLPreviewAnimation::render()
 
 	gl_rect_2d_simple( mFullWidth, mFullHeight );
 
-	glMatrixMode(GL_PROJECTION);
+	gGL.matrixMode(LLRender::MM_PROJECTION);
 	gGL.popMatrix();
 
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.popMatrix();
 
 	gGL.flush();
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index e4d8e3513d72f79ed481a5a5f27703da8c5e0128..69de15d9eae7905700edf533013c32dce5b62f8b 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -50,6 +50,7 @@
 #include "llvoavatar.h"
 #include "pipeline.h"
 #include "lluictrlfactory.h"
+#include "llviewershadermgr.h"
 #include "llviewertexturelist.h"
 #include "llstring.h"
 
@@ -649,25 +650,30 @@ BOOL LLImagePreviewAvatar::render()
 	gGL.pushUIMatrix();
 	gGL.loadUIIdentity();
 
-	glMatrixMode(GL_PROJECTION);
+	gGL.matrixMode(LLRender::MM_PROJECTION);
 	gGL.pushMatrix();
-	glLoadIdentity();
-	glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
+	gGL.loadIdentity();
+	gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
 
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.pushMatrix();
-	glLoadIdentity();
+	gGL.loadIdentity();
 	
 
 	LLGLSUIDefault def;
 	gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);
 
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		gUIProgram.bind();
+	}
+
 	gl_rect_2d_simple( mFullWidth, mFullHeight );
 
-	glMatrixMode(GL_PROJECTION);
+	gGL.matrixMode(LLRender::MM_PROJECTION);
 	gGL.popMatrix();
 
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.popMatrix();
 
 	gGL.flush();
@@ -690,8 +696,7 @@ BOOL LLImagePreviewAvatar::render()
 
 	LLVertexBuffer::unbind();
 	avatarp->updateLOD();
-	
-
+		
 	if (avatarp->mDrawable.notNull())
 	{
 		LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
@@ -699,7 +704,7 @@ BOOL LLImagePreviewAvatar::render()
 		LLGLDisable no_blend(GL_BLEND);
 
 		LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool();
-		
+		gPipeline.enableLightsPreview();
 		avatarPoolp->renderAvatars(avatarp);  // renders only one avatar
 	}
 
@@ -790,15 +795,17 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)
 	U32 num_indices = vf.mNumIndices;
 	U32 num_vertices = vf.mNumVertices;
 
-	mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL, 0);
+	mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0, 0);
 	mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE);
 
 	LLStrider<LLVector3> vertex_strider;
 	LLStrider<LLVector3> normal_strider;
+	LLStrider<LLVector2> tc_strider;
 	LLStrider<U16> index_strider;
 
 	mVertexBuffer->getVertexStrider(vertex_strider);
 	mVertexBuffer->getNormalStrider(normal_strider);
+	mVertexBuffer->getTexCoord0Strider(tc_strider);
 	mVertexBuffer->getIndexStrider(index_strider);
 
 	// build vertices and normals
@@ -806,7 +813,8 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)
 	pos = (LLVector3*) vf.mPositions; pos.setStride(16);
 	LLStrider<LLVector3> norm;
 	norm = (LLVector3*) vf.mNormals; norm.setStride(16);
-		
+	LLStrider<LLVector2> tc;
+	tc = (LLVector2*) vf.mTexCoords; tc.setStride(8);
 
 	for (U32 i = 0; i < num_vertices; i++)
 	{
@@ -814,6 +822,7 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)
 		LLVector3 normal = *norm++;
 		normal.normalize();
 		*(normal_strider++) = normal;
+		*(tc_strider++) = *tc++;
 	}
 
 	// build indices
@@ -835,23 +844,28 @@ BOOL LLImagePreviewSculpted::render()
 	LLGLEnable cull(GL_CULL_FACE);
 	LLGLDepthTest depth(GL_TRUE);
 
-	glMatrixMode(GL_PROJECTION);
+	gGL.matrixMode(LLRender::MM_PROJECTION);
 	gGL.pushMatrix();
-	glLoadIdentity();
-	glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
+	gGL.loadIdentity();
+	gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
 
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.pushMatrix();
-	glLoadIdentity();
+	gGL.loadIdentity();
 		
 	gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);
 
-	gl_rect_2d_simple( mFullWidth, mFullHeight );
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		gUIProgram.bind();
+	}
 
-	glMatrixMode(GL_PROJECTION);
+	gl_rect_2d_simple( mFullWidth, mFullHeight );
+	
+	gGL.matrixMode(LLRender::MM_PROJECTION);
 	gGL.popMatrix();
 
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.popMatrix();
 
 	glClear(GL_DEPTH_BUFFER_BIT);
@@ -876,17 +890,28 @@ BOOL LLImagePreviewSculpted::render()
 	const LLVolumeFace &vf = mVolume->getVolumeFace(0);
 	U32 num_indices = vf.mNumIndices;
 	
-	mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL);
-
 	gPipeline.enableLightsAvatar();
+
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		gObjectPreviewProgram.bind();
+	}
 	gGL.pushMatrix();
 	const F32 SCALE = 1.25f;
 	gGL.scalef(SCALE, SCALE, SCALE);
 	const F32 BRIGHTNESS = 0.9f;
 	gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
+
+	mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0);
 	mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0);
 
 	gGL.popMatrix();
+
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		gObjectPreviewProgram.unbind();
+	}
+
 	return TRUE;
 }
 
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 881f087d7b72d9e6216e1f7d086cb6636ccf3ca8..0460247f9852299fc1842822d2d35e24084d956e 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -103,6 +103,7 @@
 #include "llviewerobjectlist.h"
 #include "llanimationstates.h"
 #include "llviewernetwork.h"
+#include "llviewershadermgr.h"
 #include "glod/glod.h"
 #include <boost/algorithm/string.hpp>
 
@@ -3840,6 +3841,15 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
 
 	LLVertexBuffer::unbind();
 
+	bool no_ff = LLGLSLShader::sNoFixedFunction;
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+	LLGLSLShader::sNoFixedFunction = false;
+
+	if (shader)
+	{
+		shader->unbind();
+	}
+	
 	stop_gloderror();
 	static U32 cur_name = 1;
 
@@ -4138,6 +4148,13 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
 
 	mResourceCost = calcResourceCost();
 
+	LLVertexBuffer::unbind();
+	LLGLSLShader::sNoFixedFunction = no_ff;
+	if (shader)
+	{
+		shader->bind();
+	}
+
 	/*if (which_lod == -1 && mScene[LLModel::LOD_PHYSICS].empty())
 	 { //build physics scene
 	 mScene[LLModel::LOD_PHYSICS] = mScene[LLModel::LOD_LOW];
@@ -4888,6 +4905,8 @@ BOOL LLModelPreview::render()
 	LLMutexLock lock(this);
 	mNeedsUpdate = FALSE;
 
+	bool use_shaders = LLGLSLShader::sNoFixedFunction;
+
 	bool edges = mViewOption["show_edges"];
 	bool joint_positions = mViewOption["show_joint_positions"];
 	bool skin_weight = mViewOption["show_skin_weight"];
@@ -4904,25 +4923,33 @@ BOOL LLModelPreview::render()
 	LLGLDisable fog(GL_FOG);
 
 	{
+		if (use_shaders)
+		{
+			gUIProgram.bind();
+		}
 		//clear background to blue
-		glMatrixMode(GL_PROJECTION);
+		gGL.matrixMode(LLRender::MM_PROJECTION);
 		gGL.pushMatrix();
-		glLoadIdentity();
-		glOrtho(0.0f, width, 0.0f, height, -1.0f, 1.0f);
+		gGL.loadIdentity();
+		gGL.ortho(0.0f, width, 0.0f, height, -1.0f, 1.0f);
 
-		glMatrixMode(GL_MODELVIEW);
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
 		gGL.pushMatrix();
-		glLoadIdentity();
+		gGL.loadIdentity();
 
 		gGL.color4f(0.169f, 0.169f, 0.169f, 1.f);
 
 		gl_rect_2d_simple( width, height );
 
-		glMatrixMode(GL_PROJECTION);
+		gGL.matrixMode(LLRender::MM_PROJECTION);
 		gGL.popMatrix();
 
-		glMatrixMode(GL_MODELVIEW);
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
 		gGL.popMatrix();
+		if (use_shaders)
+		{
+			gUIProgram.unbind();
+		}
 	}
 
 	LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
@@ -5035,7 +5062,7 @@ BOOL LLModelPreview::render()
 		refresh();
 	}
 
-	glLoadIdentity();
+	gGL.loadIdentity();
 	gPipeline.enableLightsPreview();
 
 	LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *
@@ -5060,6 +5087,11 @@ BOOL LLModelPreview::render()
 
 	const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
 
+	if (use_shaders)
+	{
+		gObjectPreviewProgram.bind();
+	}
+
 	LLGLEnable normalize(GL_NORMALIZE);
 
 	if (!mBaseModel.empty() && mVertexBuffer[5].empty())
@@ -5121,7 +5153,7 @@ BOOL LLModelPreview::render()
 				gGL.pushMatrix();
 				LLMatrix4 mat = instance.mTransform;
 
-				glMultMatrixf((GLfloat*) mat.mMatrix);
+				gGL.multMatrix((GLfloat*) mat.mMatrix);
 
 				for (U32 i = 0; i < mVertexBuffer[mPreviewLOD][model].size(); ++i)
 				{
@@ -5137,7 +5169,8 @@ BOOL LLModelPreview::render()
 							const std::string& binding = instance.mModel->mMaterialList[i];						
 							const LLImportMaterial& material = instance.mMaterial[binding];
 
-							glColor4fv(material.mDiffuseColor.mV);
+							gGL.diffuseColor4fv(material.mDiffuseColor.mV);
+
 							if (material.mDiffuseMap.notNull())
 							{
 								if (material.mDiffuseMap->getDiscardLevel() > -1)
@@ -5150,12 +5183,12 @@ BOOL LLModelPreview::render()
 					}
 					else
 					{
-						glColor4f(1,1,1,1);
+						gGL.diffuseColor4f(1,1,1,1);
 					}
 
 					buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
 					gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-					glColor3f(0.4f, 0.4f, 0.4f);
+					gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
 
 					if (edges)
 					{
@@ -5203,7 +5236,7 @@ BOOL LLModelPreview::render()
 						gGL.pushMatrix();
 						LLMatrix4 mat = instance.mTransform;
 
-						glMultMatrixf((GLfloat*) mat.mMatrix);
+						gGL.multMatrix((GLfloat*) mat.mMatrix);
 
 
 						bool render_mesh = true;
@@ -5268,12 +5301,12 @@ BOOL LLModelPreview::render()
 								LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
 
 								gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-								glColor4f(0.4f, 0.4f, 0.0f, 0.4f);
+								gGL.diffuseColor4f(0.4f, 0.4f, 0.0f, 0.4f);
 
 								buffer->setBuffer(type_mask & buffer->getTypeMask());
 								buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
 
-								glColor3f(1.f, 1.f, 0.f);
+								gGL.diffuseColor3f(1.f, 1.f, 0.f);
 
 								glLineWidth(2.f);
 								glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -5293,7 +5326,7 @@ BOOL LLModelPreview::render()
 					//show degenerate triangles
 					LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
 					LLGLDisable cull(GL_CULL_FACE);
-					glColor4f(1.f,0.f,0.f,1.f);
+					gGL.diffuseColor4f(1.f,0.f,0.f,1.f);
 					const LLVector4a scale(0.5f);
 
 					for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
@@ -5310,7 +5343,7 @@ BOOL LLModelPreview::render()
 						gGL.pushMatrix();
 						LLMatrix4 mat = instance.mTransform;
 
-						glMultMatrixf((GLfloat*) mat.mMatrix);
+						gGL.multMatrix((GLfloat*) mat.mMatrix);
 
 
 						LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
@@ -5376,7 +5409,16 @@ BOOL LLModelPreview::render()
 
 			if (joint_positions)
 			{
+				LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+				if (shader)
+				{
+					gDebugProgram.bind();
+				}
 				getPreviewAvatar()->renderCollisionVolumes();
+				if (shader)
+				{
+					shader->bind();
+				}
 			}
 
 			for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter)
@@ -5415,7 +5457,7 @@ BOOL LLModelPreview::render()
 								}
 							}
 
-							for (U32 j = 0; j < buffer->getRequestedVerts(); ++j)
+							for (U32 j = 0; j < buffer->getNumVerts(); ++j)
 							{
 								LLMatrix4 final_mat;
 								final_mat.mMatrix[0][0] = final_mat.mMatrix[1][1] = final_mat.mMatrix[2][2] = final_mat.mMatrix[3][3] = 0.f;
@@ -5459,11 +5501,12 @@ BOOL LLModelPreview::render()
 
 							const std::string& binding = instance.mModel->mMaterialList[i];
 							const LLImportMaterial& material = instance.mMaterial[binding];
+
 							buffer->setBuffer(type_mask & buffer->getTypeMask());
-							glColor4fv(material.mDiffuseColor.mV);
+							gGL.diffuseColor4fv(material.mDiffuseColor.mV);
 							gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 							buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
-							glColor3f(0.4f, 0.4f, 0.4f);
+							gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
 
 							if (edges)
 							{
@@ -5480,6 +5523,11 @@ BOOL LLModelPreview::render()
 		}
 	}
 
+	if (use_shaders)
+	{
+		gObjectPreviewProgram.unbind();
+	}
+
 	gGL.popMatrix();
 
 	return TRUE;
diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp
index 3bcbb987f750eec897a7aa6145fea62790452e45..2fd7c0ef0ed86aa6e7a2fe8782befd5137fef892 100644
--- a/indra/newview/llfloaterpostcard.cpp
+++ b/indra/newview/llfloaterpostcard.cpp
@@ -159,11 +159,11 @@ void LLFloaterPostcard::draw()
 		}
 		{
 
-		glMatrixMode(GL_TEXTURE);
-		glPushMatrix();
+		gGL.matrixMode(LLRender::MM_TEXTURE);
+		gGL.pushMatrix();
 		{
-			glScalef(mImageScale.mV[VX], mImageScale.mV[VY], 1.f);
-			glMatrixMode(GL_MODELVIEW);
+			gGL.scalef(mImageScale.mV[VX], mImageScale.mV[VY], 1.f);
+			gGL.matrixMode(LLRender::MM_MODELVIEW);
 			gl_draw_scaled_image(rect.mLeft,
 								 rect.mBottom,
 								 rect.getWidth(),
@@ -171,9 +171,9 @@ void LLFloaterPostcard::draw()
 								 mViewerImage.get(), 
 								 LLColor4::white % alpha);
 		}
-		glMatrixMode(GL_TEXTURE);
-		glPopMatrix();
-		glMatrixMode(GL_MODELVIEW);
+		gGL.matrixMode(LLRender::MM_TEXTURE);
+		gGL.popMatrix();
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
 		}
 	}
 }
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 5fdeb46daaf7088a57406ab5deb2031d53a5cc8d..92c4214fdbb4c0a755606bd551cbf20360d7434d 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1034,30 +1034,19 @@ void LLFloaterPreference::refreshEnabledState()
 	}
 	
 	// Vertex Shaders
-	// Global Shader Enable
-	LLCheckBoxCtrl* ctrl_shader_enable   = getChild<LLCheckBoxCtrl>("BasicShaders");
 	// radio set for terrain detail mode
 	LLRadioGroup*   mRadioTerrainDetail = getChild<LLRadioGroup>("TerrainDetailRadio");   // can be linked with control var
 	
-	ctrl_shader_enable->setEnabled(LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable"));
-	
-	BOOL shaders = ctrl_shader_enable->get();
-	if (shaders)
-	{
-		mRadioTerrainDetail->setValue(1);
-		mRadioTerrainDetail->setEnabled(FALSE);
-	}
-	else
-	{
-		mRadioTerrainDetail->setEnabled(TRUE);		
-	}
-	
+	BOOL shaders = gGLManager.mGLVersion >= 2.f;
+
+	mRadioTerrainDetail->setEnabled(TRUE);		
+		
 	// WindLight
 	LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
 	
 	// *HACK just checks to see if we can use shaders... 
 	// maybe some cards that use shaders, but don't support windlight
-	ctrl_wind_light->setEnabled(ctrl_shader_enable->getEnabled() && shaders);
+	ctrl_wind_light->setEnabled(shaders);
 
 	//Deferred/SSAO/Shadows
 	LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
@@ -1095,7 +1084,6 @@ void LLFloaterPreference::disableUnavailableSettings()
 	LLComboBox* ctrl_reflections   = getChild<LLComboBox>("Reflections");
 	LLCheckBoxCtrl* ctrl_avatar_vp     = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
 	LLCheckBoxCtrl* ctrl_avatar_cloth  = getChild<LLCheckBoxCtrl>("AvatarCloth");
-	LLCheckBoxCtrl* ctrl_shader_enable = getChild<LLCheckBoxCtrl>("BasicShaders");
 	LLCheckBoxCtrl* ctrl_wind_light    = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
 	LLCheckBoxCtrl* ctrl_avatar_impostors = getChild<LLCheckBoxCtrl>("AvatarImpostors");
 	LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
@@ -1106,9 +1094,6 @@ void LLFloaterPreference::disableUnavailableSettings()
 	// if vertex shaders off, disable all shader related products
 	if (!LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable"))
 	{
-		ctrl_shader_enable->setEnabled(FALSE);
-		ctrl_shader_enable->setValue(FALSE);
-		
 		ctrl_wind_light->setEnabled(FALSE);
 		ctrl_wind_light->setValue(FALSE);
 		
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 8105844b0df391d549e267836d622a2e3714fa93..350509708cec2270b3e85dfefdd61df2b9b3516c 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -445,9 +445,9 @@ void LLSnapshotLivePreview::draw()
 		// calculate UV scale
 		F32 uv_width = mImageScaled[mCurImageIndex] ? 1.f : llmin((F32)mWidth[mCurImageIndex] / (F32)mViewerImage[mCurImageIndex]->getWidth(), 1.f);
 		F32 uv_height = mImageScaled[mCurImageIndex] ? 1.f : llmin((F32)mHeight[mCurImageIndex] / (F32)mViewerImage[mCurImageIndex]->getHeight(), 1.f);
-		glPushMatrix();
+		gGL.pushMatrix();
 		{
-			glTranslatef((F32)rect.mLeft, (F32)rect.mBottom, 0.f);
+			gGL.translatef((F32)rect.mLeft, (F32)rect.mBottom, 0.f);
 			gGL.begin(LLRender::QUADS);
 			{
 				gGL.texCoord2f(uv_width, uv_height);
@@ -464,7 +464,7 @@ void LLSnapshotLivePreview::draw()
 			}
 			gGL.end();
 		}
-		glPopMatrix();
+		gGL.popMatrix();
 
 		gGL.color4f(1.f, 1.f, 1.f, mFlashAlpha);
 		gl_rect_2d(getRect());
@@ -580,11 +580,11 @@ void LLSnapshotLivePreview::draw()
 			BOOL rescale = !mImageScaled[old_image_index] && mViewerImage[mCurImageIndex].notNull();
 			F32 uv_width = rescale ? llmin((F32)mWidth[old_image_index] / (F32)mViewerImage[mCurImageIndex]->getWidth(), 1.f) : 1.f;
 			F32 uv_height = rescale ? llmin((F32)mHeight[old_image_index] / (F32)mViewerImage[mCurImageIndex]->getHeight(), 1.f) : 1.f;
-			glPushMatrix();
+			gGL.pushMatrix();
 			{
 				LLRect& rect = mImageRect[old_image_index];
-				glTranslatef((F32)rect.mLeft, (F32)rect.mBottom - llround(getRect().getHeight() * 2.f * (fall_interp * fall_interp)), 0.f);
-				glRotatef(-45.f * fall_interp, 0.f, 0.f, 1.f);
+				gGL.translatef((F32)rect.mLeft, (F32)rect.mBottom - llround(getRect().getHeight() * 2.f * (fall_interp * fall_interp)), 0.f);
+				gGL.rotatef(-45.f * fall_interp, 0.f, 0.f, 1.f);
 				gGL.begin(LLRender::QUADS);
 				{
 					gGL.texCoord2f(uv_width, uv_height);
@@ -601,7 +601,7 @@ void LLSnapshotLivePreview::draw()
 				}
 				gGL.end();
 			}
-			glPopMatrix();
+			gGL.popMatrix();
 		}
 	}
 }
@@ -2226,7 +2226,7 @@ void LLFloaterSnapshot::draw()
 			S32 offset_x = (getRect().getWidth() - previewp->getThumbnailWidth()) / 2 ;
 			S32 offset_y = thumbnail_rect.mBottom + (thumbnail_rect.getHeight() - previewp->getThumbnailHeight()) / 2 ;
 
-			glMatrixMode(GL_MODELVIEW);
+			gGL.matrixMode(LLRender::MM_MODELVIEW);
 			// Apply floater transparency to the texture unless the floater is focused.
 			F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
 			gl_draw_scaled_image(offset_x, offset_y, 
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index fa3f546157b17f35a8bdb7093c2ea9fb893b0911..ac87da2d71c89905612934c664b3b932cd55df3d 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -115,7 +115,7 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
 	S32 center_y = (top + bottom) / 2;
 
 	// save drawing mode
-	glMatrixMode(GL_PROJECTION);
+	gGL.matrixMode(LLRender::MM_PROJECTION);
 	gGL.pushMatrix();
 
 	BOOL limit_select_distance = gSavedSettings.getBOOL("LimitSelectDistance");
@@ -230,9 +230,9 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
 	}
 
 	// restore drawing mode
-	glMatrixMode(GL_PROJECTION);
+	gGL.matrixMode(LLRender::MM_PROJECTION);
 	gGL.popMatrix();
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 
 	// restore camera
 	LLViewerCamera::getInstance()->setFar(old_far_plane);
@@ -777,13 +777,17 @@ void LLViewerObjectList::renderObjectBeacons()
 
 	LLGLSUIDefault gls_ui;
 
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		gUIProgram.bind();
+	}
+
 	{
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 		S32 last_line_width = -1;
 		// gGL.begin(LLRender::LINES); // Always happens in (line_width != last_line_width)
 		
-		BOOL flush = FALSE;
 		for (std::vector<LLDebugBeacon>::iterator iter = mDebugBeacons.begin(); iter != mDebugBeacons.end(); ++iter)
 		{
 			const LLDebugBeacon &debug_beacon = *iter;
@@ -792,18 +796,14 @@ void LLViewerObjectList::renderObjectBeacons()
 			S32 line_width = debug_beacon.mLineWidth;
 			if (line_width != last_line_width)
 			{
-				if (flush)
-				{
-					gGL.end();
-				}
-				flush = TRUE;
 				gGL.flush();
 				glLineWidth( (F32)line_width );
 				last_line_width = line_width;
-				gGL.begin(LLRender::LINES);
 			}
 
 			const LLVector3 &thisline = debug_beacon.mPositionAgent;
+		
+			gGL.begin(LLRender::LINES);
 			gGL.color4fv(color.mV);
 			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] - 50.f);
 			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] + 50.f);
@@ -813,8 +813,9 @@ void LLViewerObjectList::renderObjectBeacons()
 			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] + 2.f,thisline.mV[VZ]);
 
 			draw_line_cube(0.10f, thisline);
+			
+			gGL.end();
 		}
-		gGL.end();
 	}
 
 	{
@@ -824,7 +825,6 @@ void LLViewerObjectList::renderObjectBeacons()
 		S32 last_line_width = -1;
 		// gGL.begin(LLRender::LINES); // Always happens in (line_width != last_line_width)
 		
-		BOOL flush = FALSE;
 		for (std::vector<LLDebugBeacon>::iterator iter = mDebugBeacons.begin(); iter != mDebugBeacons.end(); ++iter)
 		{
 			const LLDebugBeacon &debug_beacon = *iter;
@@ -832,18 +832,13 @@ void LLViewerObjectList::renderObjectBeacons()
 			S32 line_width = debug_beacon.mLineWidth;
 			if (line_width != last_line_width)
 			{
-				if (flush)
-				{
-					gGL.end();
-				}
-				flush = TRUE;
 				gGL.flush();
 				glLineWidth( (F32)line_width );
 				last_line_width = line_width;
-				gGL.begin(LLRender::LINES);
 			}
 
 			const LLVector3 &thisline = debug_beacon.mPositionAgent;
+			gGL.begin(LLRender::LINES);
 			gGL.color4fv(debug_beacon.mColor.mV);
 			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] - 0.5f);
 			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] + 0.5f);
@@ -853,9 +848,10 @@ void LLViewerObjectList::renderObjectBeacons()
 			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] + 0.5f,thisline.mV[VZ]);
 
 			draw_line_cube(0.10f, thisline);
+
+			gGL.end();
 		}
 		
-		gGL.end();
 		gGL.flush();
 		glLineWidth(1.f);
 
diff --git a/indra/newview/llhudeffectbeam.cpp b/indra/newview/llhudeffectbeam.cpp
index 37b7b2e75dc6abe3b0139c1ed17f7878a0b7ded9..8abad3d292f41dd9d3f6e5967a0c3d369ba3b7e6 100644
--- a/indra/newview/llhudeffectbeam.cpp
+++ b/indra/newview/llhudeffectbeam.cpp
@@ -295,13 +295,13 @@ void LLHUDEffectBeam::render()
 		F32 alpha = mFadeInterp.getCurVal()*mColor.mV[3];
 		alpha *= mInterpFade[i].getCurVal();
 		coloru.mV[3] = (U8)alpha;
-		glColor4ubv(coloru.mV);
+		gGL.color4ubv(coloru.mV);
 
-		glPushMatrix();
-		glTranslatef(pos_agent.mV[0], pos_agent.mV[1], pos_agent.mV[2]);
-		glScalef(scale, scale, scale);
-		gSphere.render(0);
-		glPopMatrix();
+		gGL.pushMatrix();
+		gGL.translatef(pos_agent.mV[0], pos_agent.mV[1], pos_agent.mV[2]);
+		gGL.scalef(scale, scale, scale);
+		gSphere.render();
+		gGL.popMatrix();
 	}
 }
 
diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp
index b380b3fe2020abe4edb2ae026099ee31a06d05e6..bc3b220dc098d9183782f865469c1e78251e6db0 100644
--- a/indra/newview/llhudeffectlookat.cpp
+++ b/indra/newview/llhudeffectlookat.cpp
@@ -498,10 +498,10 @@ void LLHUDEffectLookAt::render()
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 		LLVector3 target = mTargetPos + ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->mHeadp->getWorldPosition();
-		glMatrixMode(GL_MODELVIEW);
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
 		gGL.pushMatrix();
 		gGL.translatef(target.mV[VX], target.mV[VY], target.mV[VZ]);
-		glScalef(0.3f, 0.3f, 0.3f);
+		gGL.scalef(0.3f, 0.3f, 0.3f);
 		gGL.begin(LLRender::LINES);
 		{
 			LLColor3 color = (*mAttentions)[mTargetType].mColor;
diff --git a/indra/newview/llhudeffectpointat.cpp b/indra/newview/llhudeffectpointat.cpp
index 28fe8e1c015f4dee42efc991e007c7e454f39528..114a633821c93b9867061769aa33d36166ccff1f 100644
--- a/indra/newview/llhudeffectpointat.cpp
+++ b/indra/newview/llhudeffectpointat.cpp
@@ -327,7 +327,7 @@ void LLHUDEffectPointAt::render()
 		LLVector3 target = mTargetPos + mSourceObject->getRenderPosition();
 		gGL.pushMatrix();
 		gGL.translatef(target.mV[VX], target.mV[VY], target.mV[VZ]);
-		glScalef(0.3f, 0.3f, 0.3f);
+		gGL.scalef(0.3f, 0.3f, 0.3f);
 		gGL.begin(LLRender::LINES);
 		{
 			gGL.color3f(1.f, 0.f, 0.f);
diff --git a/indra/newview/llhudrender.cpp b/indra/newview/llhudrender.cpp
index 1156e764a17a548beab38508f6d446755c791673..122711a86d23f6c06959d598a846a2587648db61 100644
--- a/indra/newview/llhudrender.cpp
+++ b/indra/newview/llhudrender.cpp
@@ -107,14 +107,24 @@ void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent,
 	viewport[1] = world_view_rect.mBottom;
 	viewport[2] = world_view_rect.getWidth();
 	viewport[3] = world_view_rect.getHeight();
+
+	F64 mdlv[16];
+	F64 proj[16];
+
+	for (U32 i = 0; i < 16; i++)
+	{
+		mdlv[i] = (F64) gGLModelView[i];
+		proj[i] = (F64) gGLProjection[i];
+	}
+
 	gluProject(render_pos.mV[0], render_pos.mV[1], render_pos.mV[2],
-				gGLModelView, gGLProjection, (GLint*) viewport,
+				mdlv, proj, (GLint*) viewport,
 				&winX, &winY, &winZ);
 		
 	//fonts all render orthographically, set up projection``
-	glMatrixMode(GL_PROJECTION);
-	glPushMatrix();
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.pushMatrix();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.pushMatrix();
 	LLUI::pushMatrix();
 		
@@ -124,7 +134,7 @@ void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent,
 	winX -= world_view_rect.mLeft;
 	winY -= world_view_rect.mBottom;
 	LLUI::loadIdentity();
-	glLoadIdentity();
+	gGL.loadIdentity();
 	LLUI::translate((F32) winX*1.0f/LLFontGL::sScaleX, (F32) winY*1.0f/(LLFontGL::sScaleY), -(((F32) winZ*2.f)-1.f));
 	F32 right_x;
 	
@@ -133,7 +143,7 @@ void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent,
 	LLUI::popMatrix();
 	gGL.popMatrix();
 
-	glMatrixMode(GL_PROJECTION);
-	glPopMatrix();
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.popMatrix();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 }
diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp
index 85e00436510ee64a187ef4cb69c6d1d6d97b3106..6e0f360cbc05174e8fde998bde64e2e8bec141e7 100644
--- a/indra/newview/llmanip.cpp
+++ b/indra/newview/llmanip.cpp
@@ -372,14 +372,14 @@ void LLManip::renderGuidelines(BOOL draw_x, BOOL draw_y, BOOL draw_z)
 	//LLVector3  center_agent  = LLSelectMgr::getInstance()->getBBoxOfSelection().getCenterAgent();
 	LLVector3  center_agent  = getPivotPoint();
 
-	glPushMatrix();
+	gGL.pushMatrix();
 	{
-		glTranslatef(center_agent.mV[VX], center_agent.mV[VY], center_agent.mV[VZ]);
+		gGL.translatef(center_agent.mV[VX], center_agent.mV[VY], center_agent.mV[VZ]);
 
 		F32 angle_radians, x, y, z;
 
 		grid_rot.getAngleAxis(&angle_radians, &x, &y, &z);
-		glRotatef(angle_radians * RAD_TO_DEG, x, y, z);
+		gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
 
 		F32 region_size = LLWorld::getInstance()->getRegionWidthInMeters();
 
@@ -416,7 +416,7 @@ void LLManip::renderGuidelines(BOOL draw_x, BOOL draw_y, BOOL draw_z)
 		}
 		LLUI::setLineWidth(1.0f);
 	}
-	glPopMatrix();
+	gGL.popMatrix();
 }
 
 void LLManip::renderXYZ(const LLVector3 &vec) 
@@ -466,11 +466,11 @@ void LLManip::renderXYZ(const LLVector3 &vec)
 		feedback_string = llformat("X: %.3f", vec.mV[VX]);
 		hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -102.f, (F32)vertical_offset, LLColor4(1.f, 0.5f, 0.5f, 1.f), FALSE);
 
-		glColor3f(0.5f, 1.f, 0.5f);
+		gGL.diffuseColor3f(0.5f, 1.f, 0.5f);
 		feedback_string = llformat("Y: %.3f", vec.mV[VY]);
 		hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -27.f, (F32)vertical_offset, LLColor4(0.5f, 1.f, 0.5f, 1.f), FALSE);
 		
-		glColor3f(0.5f, 0.5f, 1.f);
+		gGL.diffuseColor3f(0.5f, 0.5f, 1.f);
 		feedback_string = llformat("Z: %.3f", vec.mV[VZ]);
 		hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, 48.f, (F32)vertical_offset, LLColor4(0.5f, 0.5f, 1.f, 1.f), FALSE);
 	}
@@ -481,8 +481,8 @@ void LLManip::renderTickText(const LLVector3& pos, const std::string& text, cons
 	const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
 
 	BOOL hud_selection = mObjectSelection->getSelectType() == SELECT_TYPE_HUD;
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.pushMatrix();
 	LLVector3 render_pos = pos;
 	if (hud_selection)
 	{
@@ -490,7 +490,7 @@ void LLManip::renderTickText(const LLVector3& pos, const std::string& text, cons
 		F32 inv_zoom_amt = 1.f / zoom_amt;
 		// scale text back up to counter-act zoom level
 		render_pos = pos * zoom_amt;
-		glScalef(inv_zoom_amt, inv_zoom_amt, inv_zoom_amt);
+		gGL.scalef(inv_zoom_amt, inv_zoom_amt, inv_zoom_amt);
 	}
 
 	// render shadow first
@@ -501,7 +501,7 @@ void LLManip::renderTickText(const LLVector3& pos, const std::string& text, cons
 	gViewerWindow->setup3DViewport();
 	hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(text), 3.f, color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
 
-	glPopMatrix();
+	gGL.popMatrix();
 }
 
 void LLManip::renderTickValue(const LLVector3& pos, F32 value, const std::string& suffix, const LLColor4 &color)
@@ -539,8 +539,8 @@ void LLManip::renderTickValue(const LLVector3& pos, F32 value, const std::string
 	}
 
 	BOOL hud_selection = mObjectSelection->getSelectType() == SELECT_TYPE_HUD;
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.pushMatrix();
 	LLVector3 render_pos = pos;
 	if (hud_selection)
 	{
@@ -548,7 +548,7 @@ void LLManip::renderTickValue(const LLVector3& pos, F32 value, const std::string
 		F32 inv_zoom_amt = 1.f / zoom_amt;
 		// scale text back up to counter-act zoom level
 		render_pos = pos * zoom_amt;
-		glScalef(inv_zoom_amt, inv_zoom_amt, inv_zoom_amt);
+		gGL.scalef(inv_zoom_amt, inv_zoom_amt, inv_zoom_amt);
 	}
 
 	LLColor4 shadow_color = LLColor4::black;
@@ -573,7 +573,7 @@ void LLManip::renderTickValue(const LLVector3& pos, F32 value, const std::string
 		gViewerWindow->setup3DViewport();
 		hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection);
 	}
-	glPopMatrix();
+	gGL.popMatrix();
 }
 
 LLColor4 LLManip::setupSnapGuideRenderPass(S32 pass)
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index 6ee095475fb04fc73e69ee9fee82dc887229ef58..04dd2be583fbc580059020ad9b8aac3f7dd8ddde 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -130,12 +130,12 @@ void LLManipRotate::render()
 		return;
 	}
 
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.pushMatrix();
 	if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
 	{
 		F32 zoom = gAgentCamera.mHUDCurZoom;
-		glScalef(zoom, zoom, zoom);
+		gGL.scalef(zoom, zoom, zoom);
 	}
 
 
@@ -145,7 +145,7 @@ void LLManipRotate::render()
 	LLColor4 highlight_inside( 0.7f, 0.7f, 0.f, 0.5f );
 	F32 width_meters = WIDTH_PIXELS * mRadiusMeters / RADIUS_PIXELS;
 
-	glPushMatrix();
+	gGL.pushMatrix();
 	{
 		// are we in the middle of a constrained drag?
 		if (mManipPart >= LL_ROT_X && mManipPart <= LL_ROT_Z)
@@ -156,11 +156,11 @@ void LLManipRotate::render()
 		{
 			LLGLEnable cull_face(GL_CULL_FACE);
 			LLGLDepthTest gls_depth(GL_FALSE);
-			glPushMatrix();
+			gGL.pushMatrix();
 			{
 				// Draw "sphere" (intersection of sphere with tangent cone that has apex at camera)
-				glTranslatef( mCenterToProfilePlane.mV[VX], mCenterToProfilePlane.mV[VY], mCenterToProfilePlane.mV[VZ] );
-				glTranslatef( center.mV[VX], center.mV[VY], center.mV[VZ] );
+				gGL.translatef( mCenterToProfilePlane.mV[VX], mCenterToProfilePlane.mV[VY], mCenterToProfilePlane.mV[VZ] );
+				gGL.translatef( center.mV[VX], center.mV[VY], center.mV[VZ] );
 
 				// Inverse change of basis vectors
 				LLVector3 forward = mCenterToCamNorm;
@@ -177,14 +177,14 @@ void LLManipRotate::render()
 				LLMatrix4 mat;
 				mat.initRows(a, b, c, LLVector4(0.f, 0.f, 0.f, 1.f));
 
-				glMultMatrixf( &mat.mMatrix[0][0] );
+				gGL.multMatrix( &mat.mMatrix[0][0] );
 
-				glRotatef( -90, 0.f, 1.f, 0.f);
+				gGL.rotatef( -90, 0.f, 1.f, 0.f);
 				LLColor4 color;
 				if (mManipPart == LL_ROT_ROLL || mHighlightedPart == LL_ROT_ROLL)
 				{
 					color.setVec(0.8f, 0.8f, 0.8f, 0.8f);
-					glScalef(mManipulatorScales.mV[VW], mManipulatorScales.mV[VW], mManipulatorScales.mV[VW]);
+					gGL.scalef(mManipulatorScales.mV[VW], mManipulatorScales.mV[VW], mManipulatorScales.mV[VW]);
 				}
 				else
 				{
@@ -199,13 +199,12 @@ void LLManipRotate::render()
 					gl_circle_2d( 0, 0,  mRadiusMeters, CIRCLE_STEPS, TRUE );
 				}
 				
-				GLdouble plane_eqn[] = { 0, 0, 1, 0 };
-				glClipPlane( GL_CLIP_PLANE0, plane_eqn );
+				gGL.flush();
 			}
-			glPopMatrix();
+			gGL.popMatrix();
 		}
 
-		glTranslatef( center.mV[VX], center.mV[VY], center.mV[VZ] );
+		gGL.translatef( center.mV[VX], center.mV[VY], center.mV[VZ] );
 
 		LLQuaternion rot;
 		F32 angle_radians, x, y, z;
@@ -217,41 +216,41 @@ void LLManipRotate::render()
 		LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
 
 		grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z);
-		glRotatef(angle_radians * RAD_TO_DEG, x, y, z);
+		gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
 
 
 		if (mManipPart == LL_ROT_Z)
 		{
 			mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
-			glPushMatrix();
+			gGL.pushMatrix();
 			{
 				// selected part
-				glScalef(mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ]);
+				gGL.scalef(mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ]);
 				renderActiveRing( mRadiusMeters, width_meters, LLColor4( 0.f, 0.f, 1.f, 1.f) , LLColor4( 0.f, 0.f, 1.f, 0.3f ));
 			}
-			glPopMatrix();
+			gGL.popMatrix();
 		}
 		else if (mManipPart == LL_ROT_Y)
 		{
 			mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
-			glPushMatrix();
+			gGL.pushMatrix();
 			{
-				glRotatef( 90.f, 1.f, 0.f, 0.f );
-				glScalef(mManipulatorScales.mV[VY], mManipulatorScales.mV[VY], mManipulatorScales.mV[VY]);
+				gGL.rotatef( 90.f, 1.f, 0.f, 0.f );
+				gGL.scalef(mManipulatorScales.mV[VY], mManipulatorScales.mV[VY], mManipulatorScales.mV[VY]);
 				renderActiveRing( mRadiusMeters, width_meters, LLColor4( 0.f, 1.f, 0.f, 1.f), LLColor4( 0.f, 1.f, 0.f, 0.3f));
 			}
-			glPopMatrix();
+			gGL.popMatrix();
 		}
 		else if (mManipPart == LL_ROT_X)
 		{
 			mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
-			glPushMatrix();
+			gGL.pushMatrix();
 			{
-				glRotatef( 90.f, 0.f, 1.f, 0.f );
-				glScalef(mManipulatorScales.mV[VX], mManipulatorScales.mV[VX], mManipulatorScales.mV[VX]);
+				gGL.rotatef( 90.f, 0.f, 1.f, 0.f );
+				gGL.scalef(mManipulatorScales.mV[VX], mManipulatorScales.mV[VX], mManipulatorScales.mV[VX]);
 				renderActiveRing( mRadiusMeters, width_meters, LLColor4( 1.f, 0.f, 0.f, 1.f), LLColor4( 1.f, 0.f, 0.f, 0.3f));
 			}
-			glPopMatrix();
+			gGL.popMatrix();
 		}
 		else if (mManipPart == LL_ROT_ROLL)
 		{
@@ -271,12 +270,12 @@ void LLManipRotate::render()
 			// First pass: centers. Second pass: sides.
 			for( S32 i=0; i<2; i++ )
 			{
-				glPushMatrix();
+				gGL.pushMatrix();
 				{
 					if (mHighlightedPart == LL_ROT_Z)
 					{
 						mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
-						glScalef(mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ]);
+						gGL.scalef(mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ]);
 						// hovering over part
 						gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 0.f, 1.f, 1.f ), LLColor4( 0.f, 0.f, 1.f, 0.5f ), CIRCLE_STEPS, i);
 					}
@@ -286,15 +285,15 @@ void LLManipRotate::render()
 						gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 0.f, 0.8f, 0.8f ), LLColor4( 0.f, 0.f, 0.8f, 0.4f ), CIRCLE_STEPS, i);
 					}
 				}
-				glPopMatrix();
+				gGL.popMatrix();
 
-				glPushMatrix();
+				gGL.pushMatrix();
 				{
-					glRotatef( 90.f, 1.f, 0.f, 0.f );
+					gGL.rotatef( 90.f, 1.f, 0.f, 0.f );
 					if (mHighlightedPart == LL_ROT_Y)
 					{
 						mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
-						glScalef(mManipulatorScales.mV[VY], mManipulatorScales.mV[VY], mManipulatorScales.mV[VY]);
+						gGL.scalef(mManipulatorScales.mV[VY], mManipulatorScales.mV[VY], mManipulatorScales.mV[VY]);
 						// hovering over part
 						gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 1.f, 0.f, 1.f ), LLColor4( 0.f, 1.f, 0.f, 0.5f ), CIRCLE_STEPS, i);
 					}
@@ -304,15 +303,15 @@ void LLManipRotate::render()
 						gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 0.8f, 0.f, 0.8f ), LLColor4( 0.f, 0.8f, 0.f, 0.4f ), CIRCLE_STEPS, i);
 					}						
 				}
-				glPopMatrix();
+				gGL.popMatrix();
 
-				glPushMatrix();
+				gGL.pushMatrix();
 				{
-					glRotatef( 90.f, 0.f, 1.f, 0.f );
+					gGL.rotatef( 90.f, 0.f, 1.f, 0.f );
 					if (mHighlightedPart == LL_ROT_X)
 					{
 						mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
-						glScalef(mManipulatorScales.mV[VX], mManipulatorScales.mV[VX], mManipulatorScales.mV[VX]);
+						gGL.scalef(mManipulatorScales.mV[VX], mManipulatorScales.mV[VX], mManipulatorScales.mV[VX]);
 	
 						// hovering over part
 						gl_ring( mRadiusMeters, width_meters, LLColor4( 1.f, 0.f, 0.f, 1.f ), LLColor4( 1.f, 0.f, 0.f, 0.5f ), CIRCLE_STEPS, i);
@@ -323,7 +322,7 @@ void LLManipRotate::render()
 						gl_ring( mRadiusMeters, width_meters, LLColor4( 0.8f, 0.f, 0.f, 0.8f ), LLColor4( 0.8f, 0.f, 0.f, 0.4f ), CIRCLE_STEPS, i);
 					}
 				}
-				glPopMatrix();
+				gGL.popMatrix();
 
 				if (mHighlightedPart == LL_ROT_ROLL)
 				{
@@ -332,8 +331,8 @@ void LLManipRotate::render()
 			}
 		}
 	}
-	glPopMatrix();
-	glPopMatrix();
+	gGL.popMatrix();
+	gGL.popMatrix();
 
 	LLVector3 euler_angles;
 	LLQuaternion object_rot = first_object->getRotationEdit();
@@ -796,14 +795,14 @@ void LLManipRotate::renderSnapGuides()
 		for (S32 pass = 0; pass < 3; pass++)
 		{
 			// render snap guide ring
-			glPushMatrix();
+			gGL.pushMatrix();
 			
 			LLQuaternion snap_guide_rot;
 			F32 angle_radians, x, y, z;
 			snap_guide_rot.shortestArc(LLVector3::z_axis, getConstraintAxis());
 			snap_guide_rot.getAngleAxis(&angle_radians, &x, &y, &z);
-			glTranslatef(center.mV[VX], center.mV[VY], center.mV[VZ]);
-			glRotatef(angle_radians * RAD_TO_DEG, x, y, z);
+			gGL.translatef(center.mV[VX], center.mV[VY], center.mV[VZ]);
+			gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
 
 			LLColor4 line_color = setupSnapGuideRenderPass(pass);
 
@@ -826,7 +825,7 @@ void LLManipRotate::renderSnapGuides()
 			{
 				gl_circle_2d(0.f, 0.f, mRadiusMeters * SNAP_GUIDE_INNER_RADIUS, CIRCLE_STEPS, FALSE);
 			}
-			glPopMatrix();
+			gGL.popMatrix();
 
 			for (S32 i = 0; i < 64; i++)
 			{
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index 4eb94dfb8e805997665212b06761bd929675cc30..f6df4cdfbfe0c8530d5c3efa9eb56858e4d315d1 100644
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -217,12 +217,12 @@ void LLManipScale::render()
 	
 	if( canAffectSelection() )
 	{
-		glMatrixMode(GL_MODELVIEW);
-		glPushMatrix();
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
+		gGL.pushMatrix();
 		if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
 		{
 			F32 zoom = gAgentCamera.mHUDCurZoom;
-			glScalef(zoom, zoom, zoom);
+			gGL.scalef(zoom, zoom, zoom);
 		}
 
 		////////////////////////////////////////////////////////////////////////
@@ -274,14 +274,14 @@ void LLManipScale::render()
 		LLVector3 pos_agent = bbox.getPositionAgent();
 		LLQuaternion rot = bbox.getRotation();
 
-		glMatrixMode(GL_MODELVIEW);
-		glPushMatrix();
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
+		gGL.pushMatrix();
 		{
-			glTranslatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ]);
+			gGL.translatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ]);
 
 			F32 angle_radians, x, y, z;
 			rot.getAngleAxis(&angle_radians, &x, &y, &z);
-			glRotatef(angle_radians * RAD_TO_DEG, x, y, z);
+			gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
 
 			
 			{
@@ -303,13 +303,13 @@ void LLManipScale::render()
 				glPolygonOffset( 0.f, 0.f);
 			}
 		}
-		glPopMatrix();
+		gGL.popMatrix();
 
 		if (mManipPart != LL_NO_PART)
 		{
 			renderSnapGuides(bbox);
 		}
-		glPopMatrix();
+		gGL.popMatrix();
 
 		renderXYZ(bbox.getExtentLocal());
 	}
@@ -719,17 +719,17 @@ void LLManipScale::renderEdges( const LLBBox& bbox )
 		LLVector3 direction = edgeToUnitVector( part );
 		LLVector3 center_to_edge = unitVectorToLocalBBoxExtent( direction, bbox );
 
-		glPushMatrix();
+		gGL.pushMatrix();
 		{
-			glTranslatef( center_to_edge.mV[0], center_to_edge.mV[1], center_to_edge.mV[2] );
+			gGL.translatef( center_to_edge.mV[0], center_to_edge.mV[1], center_to_edge.mV[2] );
 			conditionalHighlight( part );
-			glScalef( 
+			gGL.scalef( 
 				direction.mV[0] ? edge_width : extent.mV[VX],
 				direction.mV[1] ? edge_width : extent.mV[VY],
 				direction.mV[2] ? edge_width : extent.mV[VZ] );
 			gBox.render();
 		}
-		glPopMatrix();
+		gGL.popMatrix();
 	}
 }
 
@@ -766,13 +766,13 @@ void LLManipScale::renderBoxHandle( F32 x, F32 y, F32 z )
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	LLGLDepthTest gls_depth(GL_FALSE);
 
-	glPushMatrix();
+	gGL.pushMatrix();
 	{
-		glTranslatef( x, y, z );
-		glScalef( mScaledBoxHandleSize, mScaledBoxHandleSize, mScaledBoxHandleSize );
+		gGL.translatef( x, y, z );
+		gGL.scalef( mScaledBoxHandleSize, mScaledBoxHandleSize, mScaledBoxHandleSize );
 		gBox.render();
 	}
-	glPopMatrix();
+	gGL.popMatrix();
 }
 
 
@@ -788,16 +788,16 @@ void LLManipScale::renderAxisHandle( const LLVector3& start, const LLVector3& en
 		LLVector3 delta = end - offset_start;
 		LLVector3 pos = offset_start + 0.5f * delta;
 
-		glPushMatrix();
+		gGL.pushMatrix();
 		{
-			glTranslatef( pos.mV[VX], pos.mV[VY], pos.mV[VZ] );
-			glScalef( 
+			gGL.translatef( pos.mV[VX], pos.mV[VY], pos.mV[VZ] );
+			gGL.scalef( 
 				mBoxHandleSize + llabs(delta.mV[VX]),
 				mBoxHandleSize + llabs(delta.mV[VY]),
 				mBoxHandleSize + llabs(delta.mV[VZ]));
 			gBox.render();
 		}
-		glPopMatrix();
+		gGL.popMatrix();
 	}
 	else
 	{
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index f871df0c36cc787abe6a9081f33961f4e16512e3..3a88fbd96deab76c4a0a8811d5f5497071cc6f43 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -1066,12 +1066,12 @@ BOOL LLManipTranslate::handleMouseUp(S32 x, S32 y, MASK mask)
 
 void LLManipTranslate::render()
 {
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.pushMatrix();
 	if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
 	{
 		F32 zoom = gAgentCamera.mHUDCurZoom;
-		glScalef(zoom, zoom, zoom);
+		gGL.scalef(zoom, zoom, zoom);
 	}
 	{
 		LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
@@ -1515,11 +1515,12 @@ void LLManipTranslate::renderSnapGuides()
 		F32 x,y,z,angle_radians;
 		grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z);
 		gGL.translatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]);
-		glRotatef(angle_radians * RAD_TO_DEG, x, y, z);
+		gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
 		
 		F32 sz = mGridSizeMeters;
 		F32 tiles = sz;
-		glMatrixMode(GL_TEXTURE);
+
+		gGL.matrixMode(LLRender::MM_TEXTURE);
 		gGL.pushMatrix();
 		usc = 1.0f/usc;
 		vsc = 1.0f/vsc;
@@ -1533,7 +1534,7 @@ void LLManipTranslate::renderSnapGuides()
 			vsc *= 0.5f;
 		}
 
-		glScalef(usc, vsc, 1.0f);
+		gGL.scalef(usc, vsc, 1.0f);
 		gGL.translatef(u, v, 0);
 		
 		float a = line_alpha;
@@ -1566,7 +1567,7 @@ void LLManipTranslate::renderSnapGuides()
 					renderGrid(u,v,tiles,1,1,1,a);
 
 					gGL.popMatrix();
-					glMatrixMode(GL_MODELVIEW);
+					gGL.matrixMode(LLRender::MM_MODELVIEW);
 					gGL.popMatrix();
 				}
 
@@ -1665,7 +1666,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
 		glStencilFunc(GL_ALWAYS, 0, stencil_mask);
 		gGL.setColorMask(false, false);
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-		glColor4f(1,1,1,1);
+		gGL.diffuseColor4f(1,1,1,1);
 
 		//setup clip plane
 		normal = normal * grid_rotation;
@@ -1723,7 +1724,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
 	F32 x,y,z,angle_radians;
 	grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z);
 	gGL.translatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]);
-	glRotatef(angle_radians * RAD_TO_DEG, x, y, z);
+	gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
 	
 	F32 sz = mGridSizeMeters;
 	F32 tiles = sz;
@@ -1852,7 +1853,7 @@ void LLManipTranslate::renderTranslationHandles()
 	mGridSizeMeters = gSavedSettings.getF32("GridDrawSize");
 	mConeSize = mArrowLengthMeters / 4.f;
 
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.pushMatrix();
 	{
 		gGL.translatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]);
@@ -1860,7 +1861,7 @@ void LLManipTranslate::renderTranslationHandles()
 		F32 angle_radians, x, y, z;
 		grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z);
 
-		glRotatef(angle_radians * RAD_TO_DEG, x, y, z);
+		gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
 
 		LLQuaternion invRotation = grid_rotation;
 		invRotation.conjQuat();
@@ -1908,9 +1909,9 @@ void LLManipTranslate::renderTranslationHandles()
 			{
 				// render YZ plane manipulator
 				gGL.pushMatrix();
-				glScalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]);
+				gGL.scalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]);
 				gGL.translatef(0.f, mPlaneManipOffsetMeters, mPlaneManipOffsetMeters);
-				glScalef(mPlaneScales.mV[VX], mPlaneScales.mV[VX], mPlaneScales.mV[VX]);
+				gGL.scalef(mPlaneScales.mV[VX], mPlaneScales.mV[VX], mPlaneScales.mV[VX]);
 				if (mHighlightedPart == LL_YZ_PLANE)
 				{
 					color1.setVec(0.f, 1.f, 0.f, 1.f);
@@ -1962,9 +1963,9 @@ void LLManipTranslate::renderTranslationHandles()
 			{
 				// render XZ plane manipulator
 				gGL.pushMatrix();
-				glScalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]);
+				gGL.scalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]);
 				gGL.translatef(mPlaneManipOffsetMeters, 0.f, mPlaneManipOffsetMeters);
-				glScalef(mPlaneScales.mV[VY], mPlaneScales.mV[VY], mPlaneScales.mV[VY]);
+				gGL.scalef(mPlaneScales.mV[VY], mPlaneScales.mV[VY], mPlaneScales.mV[VY]);
 				if (mHighlightedPart == LL_XZ_PLANE)
 				{
 					color1.setVec(0.f, 0.f, 1.f, 1.f);
@@ -2018,7 +2019,7 @@ void LLManipTranslate::renderTranslationHandles()
 			{
 				// render XY plane manipulator
 				gGL.pushMatrix();
-				glScalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]);
+				gGL.scalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]);
 				
 /*				 			  Y
 				 			  ^
@@ -2043,7 +2044,7 @@ void LLManipTranslate::renderTranslationHandles()
 					v2 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), 0.f);
 					v3 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), 0.f);
 #endif
-					glScalef(mPlaneScales.mV[VZ], mPlaneScales.mV[VZ], mPlaneScales.mV[VZ]);
+					gGL.scalef(mPlaneScales.mV[VZ], mPlaneScales.mV[VZ], mPlaneScales.mV[VZ]);
 					if (mHighlightedPart == LL_XY_PLANE)
 					{
 						color1.setVec(1.f, 0.f, 0.f, 1.f);
@@ -2215,7 +2216,7 @@ void LLManipTranslate::renderArrow(S32 which_arrow, S32 selected_arrow, F32 box_
 		}
 		
 		gGL.translatef(vec.mV[0], vec.mV[1], vec.mV[2]);
-		glScalef(handle_size, handle_size, handle_size);
+		gGL.scalef(handle_size, handle_size, handle_size);
 
 		F32 rot = 0.0f;
 		LLVector3 axis;
@@ -2239,11 +2240,11 @@ void LLManipTranslate::renderArrow(S32 which_arrow, S32 selected_arrow, F32 box_
 			break;
 		}
 
-		glColor4fv(color.mV);
-		glRotatef(rot, axis.mV[0], axis.mV[1], axis.mV[2]);
-		glScalef(mArrowScales.mV[index], mArrowScales.mV[index], mArrowScales.mV[index] * 1.5f);
+		gGL.diffuseColor4fv(color.mV);
+		gGL.rotatef(rot, axis.mV[0], axis.mV[1], axis.mV[2]);
+		gGL.scalef(mArrowScales.mV[index], mArrowScales.mV[index], mArrowScales.mV[index] * 1.5f);
 
-		gCone.render(CONE_LOD_HIGHEST);
+		gCone.render();
 
 		gGL.popMatrix();
 	}
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 5fe5c9b1e8a4e03c0073cd053ee3599f8f1d3633..15d5d7c1628f8b43dd2da028ec299ea30fb825c1 100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -172,10 +172,10 @@ void LLNetMap::draw()
 	LLVector3 offset = gGL.getUITranslation();
 	LLVector3 scale = gGL.getUIScale();
 
-	glLoadIdentity();
+	gGL.loadIdentity();
 	gGL.loadUIIdentity();
 
-	glScalef(scale.mV[0], scale.mV[1], scale.mV[2]);
+	gGL.scalef(scale.mV[0], scale.mV[1], scale.mV[2]);
 	gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
 	
 	{
@@ -183,7 +183,7 @@ void LLNetMap::draw()
 		{
 			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
-			glMatrixMode(GL_MODELVIEW);
+			gGL.matrixMode(LLRender::MM_MODELVIEW);
 
 			// Draw background rectangle
 			LLColor4 background_color = mBackgroundColor.get();
@@ -204,7 +204,7 @@ void LLNetMap::draw()
 		{
 			// rotate subsequent draws to agent rotation
 			rotation = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] );
-			glRotatef( rotation * RAD_TO_DEG, 0.f, 0.f, 1.f);
+			gGL.rotatef( rotation * RAD_TO_DEG, 0.f, 0.f, 1.f);
 		}
 
 		// figure out where agent is
@@ -492,7 +492,7 @@ void LLNetMap::draw()
 			// If we don't rotate the map, we have to rotate the frustum.
 			gGL.pushMatrix();
 				gGL.translatef( ctr_x, ctr_y, 0 );
-				glRotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
+				gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
 				gGL.begin( LLRender::TRIANGLES  );
 					gGL.vertex2f( 0, 0 );
 					gGL.vertex2f( -half_width_pixels, far_clip_pixels );
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index bef809f3a71749423ad6e8f6c0c28cc16401f13c..058d1ad6bc91433e9e8f656396438753f60bac9c 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -283,15 +283,15 @@ LLPanelLogin::~LLPanelLogin()
 // virtual
 void LLPanelLogin::draw()
 {
-	glPushMatrix();
+	gGL.pushMatrix();
 	{
 		F32 image_aspect = 1.333333f;
 		F32 view_aspect = (F32)getRect().getWidth() / (F32)getRect().getHeight();
 		// stretch image to maintain aspect ratio
 		if (image_aspect > view_aspect)
 		{
-			glTranslatef(-0.5f * (image_aspect / view_aspect - 1.f) * getRect().getWidth(), 0.f, 0.f);
-			glScalef(image_aspect / view_aspect, 1.f, 1.f);
+			gGL.translatef(-0.5f * (image_aspect / view_aspect - 1.f) * getRect().getWidth(), 0.f, 0.f);
+			gGL.scalef(image_aspect / view_aspect, 1.f, 1.f);
 		}
 
 		S32 width = getRect().getWidth();
@@ -306,7 +306,7 @@ void LLPanelLogin::draw()
 			mLogoImage->draw(0, -264, width + 8, mLogoImage->getHeight());
 		};
 	}
-	glPopMatrix();
+	gGL.popMatrix();
 
 	LLPanel::draw();
 }
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index 18d6731fcb2c997b21773a04b32c371beb080c53..3ff5a05d81e7b7a3a12246b19d879a56307af28b 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -169,7 +169,7 @@ void LLPreviewTexture::draw()
 				saveAs();
 			}
 			// Draw the texture
-			glColor3f( 1.f, 1.f, 1.f );
+			gGL.diffuseColor3f( 1.f, 1.f, 1.f );
 			gl_draw_scaled_image(interior.mLeft,
 								interior.mBottom,
 								interior.getWidth(),
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index a1f38f185479e1e50f3242186786df891efe0d39..5d7a5b1c59b94e7e9462d20e9a84a9b9f9d19c12 100644
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -187,7 +187,7 @@ void LLProgressView::setVisible(BOOL visible)
 
 void LLProgressView::drawStartTexture(F32 alpha)
 {
-	glPushMatrix();	
+	gGL.pushMatrix();	
 	if (gStartTexture)
 	{
 		LLGLSUIDefault gls_ui;
@@ -200,13 +200,13 @@ void LLProgressView::drawStartTexture(F32 alpha)
 		// stretch image to maintain aspect ratio
 		if (image_aspect > view_aspect)
 		{
-			glTranslatef(-0.5f * (image_aspect / view_aspect - 1.f) * width, 0.f, 0.f);
-			glScalef(image_aspect / view_aspect, 1.f, 1.f);
+			gGL.translatef(-0.5f * (image_aspect / view_aspect - 1.f) * width, 0.f, 0.f);
+			gGL.scalef(image_aspect / view_aspect, 1.f, 1.f);
 		}
 		else
 		{
-			glTranslatef(0.f, -0.5f * (view_aspect / image_aspect - 1.f) * height, 0.f);
-			glScalef(1.f, view_aspect / image_aspect, 1.f);
+			gGL.translatef(0.f, -0.5f * (view_aspect / image_aspect - 1.f) * height, 0.f);
+			gGL.scalef(1.f, view_aspect / image_aspect, 1.f);
 		}
 		gl_rect_2d_simple_tex( getRect().getWidth(), getRect().getHeight() );
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -217,7 +217,7 @@ void LLProgressView::drawStartTexture(F32 alpha)
 		gGL.color4f(0.f, 0.f, 0.f, 1.f);
 		gl_rect_2d(getRect());
 	}
-	glPopMatrix();
+	gGL.popMatrix();
 }
 
 
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 733902ad30d937923f8bfe093d9a0942b028f06c..2971ee710a0b4fe0d16779770cec35a4603d2afe 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -89,6 +89,7 @@
 #include "llvoavatarself.h"
 #include "llvovolume.h"
 #include "pipeline.h"
+#include "llviewershadermgr.h"
 
 #include "llglheaders.h"
 
@@ -4837,7 +4838,7 @@ void LLSelectMgr::processForceObjectSelect(LLMessageSystem* msg, void**)
 	LLSelectMgr::getInstance()->highlightObjectAndFamily(objects);
 }
 
-extern LLGLdouble	gGLModelView[16];
+extern F32	gGLModelView[16];
 
 void LLSelectMgr::updateSilhouettes()
 {
@@ -5133,20 +5134,20 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
 		F32 cur_zoom = gAgentCamera.mHUDCurZoom;
 
 		// set up transform to encompass bounding box of HUD
-		glMatrixMode(GL_PROJECTION);
+		gGL.matrixMode(LLRender::MM_PROJECTION);
 		gGL.pushMatrix();
-		glLoadIdentity();
+		gGL.loadIdentity();
 		F32 depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f);
-		glOrtho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, depth);
+		gGL.ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, depth);
 
-		glMatrixMode(GL_MODELVIEW);
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
 		gGL.pushMatrix();
 		gGL.pushUIMatrix();
 		gGL.loadUIIdentity();
-		glLoadIdentity();
-		glLoadMatrixf(OGL_TO_CFR_ROTATION);		// Load Cory's favorite reference frame
-		glTranslatef(-hud_bbox.getCenterLocal().mV[VX] + (depth *0.5f), 0.f, 0.f);
-		glScalef(cur_zoom, cur_zoom, cur_zoom);
+		gGL.loadIdentity();
+		gGL.loadMatrix(OGL_TO_CFR_ROTATION);		// Load Cory's favorite reference frame
+		gGL.translatef(-hud_bbox.getCenterLocal().mV[VX] + (depth *0.5f), 0.f, 0.f);
+		gGL.scalef(cur_zoom, cur_zoom, cur_zoom);
 	}
 	if (mSelectedObjects->getNumNodes())
 	{
@@ -5239,10 +5240,10 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
 
 	if (isAgentAvatarValid() && for_hud)
 	{
-		glMatrixMode(GL_PROJECTION);
+		gGL.matrixMode(LLRender::MM_PROJECTION);
 		gGL.popMatrix();
 
-		glMatrixMode(GL_MODELVIEW);
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
 		gGL.popMatrix();
 		gGL.popUIMatrix();
 		stop_glerror();
@@ -5566,12 +5567,11 @@ void pushWireframe(LLDrawable* drawable)
 			{
 				LLVertexBuffer::unbind();
 				gGL.pushMatrix();
-				glMultMatrixf((F32*) vobj->getRelativeXform().mMatrix);
+				gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix);
 				for (S32 i = 0; i < rigged_volume->getNumVolumeFaces(); ++i)
 				{
 					const LLVolumeFace& face = rigged_volume->getVolumeFace(i);
-					glVertexPointer(3, GL_FLOAT, 16, face.mPositions);
-					glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices);
+					LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, face.mTexCoords, face.mNumIndices, face.mIndices);
 				}
 				gGL.popMatrix();
 			}
@@ -5584,7 +5584,7 @@ void pushWireframe(LLDrawable* drawable)
 			LLFace* face = drawable->getFace(i);
 			if (face->verify())
 			{
-				pushVerts(face, LLVertexBuffer::MAP_VERTEX);
+				pushVerts(face, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0);
 			}
 		}
 	}
@@ -5604,22 +5604,29 @@ void LLSelectNode::renderOneWireframe(const LLColor4& color)
 		return;
 	}
 
-	glMatrixMode(GL_MODELVIEW);
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+
+	if (shader)
+	{
+		gHighlightProgram.bind();
+	}
+
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.pushMatrix();
 	
 	BOOL is_hud_object = objectp->isHUDAttachment();
 
 	if (drawable->isActive())
 	{
-		glLoadMatrixd(gGLModelView);
-		glMultMatrixf((F32*) objectp->getRenderMatrix().mMatrix);
+		gGL.loadMatrix(gGLModelView);
+		gGL.multMatrix((F32*) objectp->getRenderMatrix().mMatrix);
 	}
 	else if (!is_hud_object)
 	{
-		glLoadIdentity();
-		glMultMatrixd(gGLModelView);
+		gGL.loadIdentity();
+		gGL.multMatrix(gGLModelView);
 		LLVector3 trans = objectp->getRegion()->getOriginAgent();		
-		glTranslatef(trans.mV[0], trans.mV[1], trans.mV[2]);		
+		gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);		
 	}
 	
 	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -5627,26 +5634,35 @@ void LLSelectNode::renderOneWireframe(const LLColor4& color)
 	if (LLSelectMgr::sRenderHiddenSelections) // && gFloaterTools && gFloaterTools->getVisible())
 	{
 		gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE);
-		LLGLEnable fog(GL_FOG);
-		glFogi(GL_FOG_MODE, GL_LINEAR);
-		float d = (LLViewerCamera::getInstance()->getPointOfInterest()-LLViewerCamera::getInstance()->getOrigin()).magVec();
-		LLColor4 fogCol = color * (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal()-gAgentCamera.getCameraPositionGlobal()).magVec()/(LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec()*4), 0.0, 1.0);
-		glFogf(GL_FOG_START, d);
-		glFogf(GL_FOG_END, d*(1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV())));
-		glFogfv(GL_FOG_COLOR, fogCol.mV);
-
 		LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL);
-		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+		if (shader)
 		{
-			glColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
+			gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
 			pushWireframe(drawable);
 		}
+		else
+		{
+			LLGLEnable fog(GL_FOG);
+			glFogi(GL_FOG_MODE, GL_LINEAR);
+			float d = (LLViewerCamera::getInstance()->getPointOfInterest()-LLViewerCamera::getInstance()->getOrigin()).magVec();
+			LLColor4 fogCol = color * (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal()-gAgentCamera.getCameraPositionGlobal()).magVec()/(LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec()*4), 0.0, 1.0);
+			glFogf(GL_FOG_START, d);
+			glFogf(GL_FOG_END, d*(1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV())));
+			glFogfv(GL_FOG_COLOR, fogCol.mV);
+
+			gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+			{
+				gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
+				pushWireframe(drawable);
+			}
+		}
 	}
 
 	gGL.flush();
 	gGL.setSceneBlendType(LLRender::BT_ALPHA);
 
-	glColor4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2);
+	gGL.diffuseColor4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2);
+	
 	LLGLEnable offset(GL_POLYGON_OFFSET_LINE);
 	glPolygonOffset(3.f, 3.f);
 	glLineWidth(3.f);
@@ -5654,6 +5670,11 @@ void LLSelectNode::renderOneWireframe(const LLColor4& color)
 	glLineWidth(1.f);
 	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 	gGL.popMatrix();
+
+	if (shader)
+	{
+		shader->bind();
+	}
 }
 
 //-----------------------------------------------------------------------------
@@ -5692,21 +5713,21 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color)
 		return;
 	}
 
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.pushMatrix();
 	gGL.pushUIMatrix();
 	gGL.loadUIIdentity();
 
 	if (!is_hud_object)
 	{
-		glLoadIdentity();
-		glMultMatrixd(gGLModelView);
+		gGL.loadIdentity();
+		gGL.multMatrix(gGLModelView);
 	}
 	
 	
 	if (drawable->isActive())
 	{
-		glMultMatrixf((F32*) objectp->getRenderMatrix().mMatrix);
+		gGL.multMatrix((F32*) objectp->getRenderMatrix().mMatrix);
 	}
 
 	LLVolume *volume = objectp->getVolume();
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 6c2b71dd0a0c539b1bb3755808dd3018f1389ad2..7bf4e901c1c674efa51eedfb4d4bf76ac7606b4b 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -48,6 +48,7 @@
 #include "llvolumemgr.h"
 #include "lltextureatlas.h"
 #include "llglslshader.h"
+#include "llviewershadermgr.h"
 
 static LLFastTimer::DeclareTimer FTM_FRUSTUM_CULL("Frustum Culling");
 static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound");
@@ -214,7 +215,7 @@ typedef enum
 //contact Runitai Linden for a copy of the SL object used to write this table
 //basically, you give the table a bitmask of the look-at vector to a node and it
 //gives you a triangle fan index array
-static U8 sOcclusionIndices[] =
+static U16 sOcclusionIndices[] =
 {
 	 //000
 		b111, b110, b010, b011, b001, b101, b100, b110,
@@ -251,7 +252,7 @@ U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center)
 
 	S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7;
 	
-	return sOcclusionIndices+cypher*8;
+	return (U8*) (sOcclusionIndices+cypher*8);
 }
 
 
@@ -261,7 +262,6 @@ void LLSpatialGroup::buildOcclusion()
 {
 	if (mOcclusionVerts.isNull())
 	{
-
 		mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 
 			LLVertexBuffer::sUseStreamDraw ? mBufferUsage : 0); //if GL has a hard time with VBOs, don't use them for occlusion culling.
 		mOcclusionVerts->allocateBuffer(8, 64, true);
@@ -321,7 +321,8 @@ void LLSpatialGroup::buildOcclusion()
 	}
 	
 	{
-		mOcclusionVerts->setBuffer(0);
+		mOcclusionVerts->flush();
+		LLVertexBuffer::unbind();
 	}
 
 	clearState(LLSpatialGroup::OCCLUSION_DIRTY);
@@ -1614,6 +1615,8 @@ void LLSpatialGroup::checkOcclusion()
 static LLFastTimer::DeclareTimer FTM_PUSH_OCCLUSION_VERTS("Push Occlusion");
 static LLFastTimer::DeclareTimer FTM_SET_OCCLUSION_STATE("Occlusion State");
 static LLFastTimer::DeclareTimer FTM_OCCLUSION_EARLY_FAIL("Occlusion Early Fail");
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_ALLOCATE("Allocate");
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_BUILD("Build");
 
 void LLSpatialGroup::doOcclusion(LLCamera* camera)
 {
@@ -1637,11 +1640,13 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
 
 					if (!mOcclusionQuery[LLViewerCamera::sCurCameraID])
 					{
+						LLFastTimer t(FTM_OCCLUSION_ALLOCATE);
 						mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate();
 					}
 
 					if (mOcclusionVerts.isNull() || isState(LLSpatialGroup::OCCLUSION_DIRTY))
 					{
+						LLFastTimer t(FTM_OCCLUSION_BUILD);
 						buildOcclusion();
 					}
 					
@@ -2416,7 +2421,7 @@ void pushVerts(LLFace* face, U32 mask)
 
 	LLVertexBuffer* buffer = face->getVertexBuffer();
 
-	if (buffer)
+	if (buffer && (face->getGeomCount() >= 3))
 	{
 		buffer->setBuffer(mask);
 		U16 start = face->getGeomStart();
@@ -2441,8 +2446,7 @@ void pushVerts(LLVolume* volume)
 	for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
 	{
 		const LLVolumeFace& face = volume->getVolumeFace(i);
-		glVertexPointer(3, GL_FLOAT, 16, face.mPositions);
-		glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices);
+		LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, NULL, face.mNumIndices, face.mIndices);
 	}
 }
 
@@ -2451,7 +2455,7 @@ void pushBufferVerts(LLVertexBuffer* buffer, U32 mask)
 	if (buffer)
 	{
 		buffer->setBuffer(mask);
-		buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getRequestedVerts()-1, buffer->getRequestedIndices(), 0);
+		buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
 	}
 }
 
@@ -2508,7 +2512,7 @@ void pushVertsColorCoded(LLSpatialGroup* group, U32 mask)
 		{
 			params = *j;
 			LLRenderPass::applyModelMatrix(*params);
-			glColor4f(colors[col].mV[0], colors[col].mV[1], colors[col].mV[2], 0.5f);
+			gGL.diffuseColor4f(colors[col].mV[0], colors[col].mV[1], colors[col].mV[2], 0.5f);
 			params->mVertexBuffer->setBuffer(mask);
 			params->mVertexBuffer->drawRange(params->mParticle ? LLRender::POINTS : LLRender::TRIANGLES,
 				params->mStart, params->mEnd, params->mCount, params->mOffset);
@@ -2523,7 +2527,7 @@ void renderOctree(LLSpatialGroup* group)
 	//coded by buffer usage and activity
 	gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
 	LLVector4 col;
-	/*if (group->mBuilt > 0.f)
+	if (group->mBuilt > 0.f)
 	{
 		group->mBuilt -= 2.f * gFrameIntervalSeconds;
 		if (group->mBufferUsage == GL_STATIC_DRAW_ARB)
@@ -2541,7 +2545,7 @@ void renderOctree(LLSpatialGroup* group)
 			LLGLDepthTest gl_depth(FALSE, FALSE);
 			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 
-			gGL.color4f(1,0,0,group->mBuilt);
+			gGL.diffuseColor4f(1,0,0,group->mBuilt);
 			gGL.flush();
 			glLineWidth(5.f);
 			drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]);
@@ -2553,9 +2557,9 @@ void renderOctree(LLSpatialGroup* group)
 				LLDrawable* drawable = *i;
 				if (!group->mSpatialPartition->isBridge())
 				{
-					glPushMatrix();
+					gGL.pushMatrix();
 					LLVector3 trans = drawable->getRegion()->getOriginAgent();
-					glTranslatef(trans.mV[0], trans.mV[1], trans.mV[2]);
+					gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
 				}
 				
 				for (S32 j = 0; j < drawable->getNumFaces(); j++)
@@ -2565,11 +2569,11 @@ void renderOctree(LLSpatialGroup* group)
 					{
 						if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f)
 						{
-							glColor4f(0, 1, 0, group->mBuilt);
+							gGL.diffuseColor4f(0, 1, 0, group->mBuilt);
 						}
 						else if (gFrameTimeSeconds - face->mLastMoveTime < 0.5f)
 						{
-							glColor4f(1, 0, 0, group->mBuilt);
+							gGL.diffuseColor4f(1, 0, 0, group->mBuilt);
 						}
 						else
 						{
@@ -2585,14 +2589,14 @@ void renderOctree(LLSpatialGroup* group)
 
 				if (!group->mSpatialPartition->isBridge())
 				{
-					glPopMatrix();
+					gGL.popMatrix();
 				}
 			}
 			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-			gGL.color4f(1,1,1,1);
+			gGL.diffuseColor4f(1,1,1,1);
 		}
 	}
-	else*/
+	else
 	{
 		if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->getData().empty() 
 			&& group->mSpatialPartition->mRenderByGroup)
@@ -2605,7 +2609,7 @@ void renderOctree(LLSpatialGroup* group)
 		}
 	}
 
-	gGL.color4fv(col.mV);
+	gGL.diffuseColor4fv(col.mV);
 	LLVector4a fudge;
 	fudge.splat(0.001f);
 	LLVector4a size = group->mObjectBounds[1];
@@ -2622,16 +2626,16 @@ void renderOctree(LLSpatialGroup* group)
 	//if (group->mBuilt <= 0.f)
 	{
 		//draw opaque outline
-		//gGL.color4f(col.mV[0], col.mV[1], col.mV[2], 1.f);
+		//gGL.diffuseColor4f(col.mV[0], col.mV[1], col.mV[2], 1.f);
 		//drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]);
 
-		gGL.color4f(0,1,1,1);
+		gGL.diffuseColor4f(0,1,1,1);
 		drawBoxOutline(group->mBounds[0],group->mBounds[1]);
 		
 		//draw bounding box for draw info
 		/*if (group->mSpatialPartition->mRenderByGroup)
 		{
-			gGL.color4f(1.0f, 0.75f, 0.25f, 0.6f);
+			gGL.diffuseColor4f(1.0f, 0.75f, 0.25f, 0.6f);
 			for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
 			{
 				for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j)
@@ -2650,7 +2654,7 @@ void renderOctree(LLSpatialGroup* group)
 	}
 	
 //	LLSpatialGroup::OctreeNode* node = group->mOctreeNode;
-//	gGL.color4f(0,1,0,1);
+//	gGL.diffuseColor4f(0,1,0,1);
 //	drawBoxOutline(LLVector3(node->getCenter()), LLVector3(node->getSize()));
 }
 
@@ -2663,11 +2667,12 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
 
 	BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() &&
 							!group->getData().empty();
+
 	if (render_objects)
 	{
 		LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER);
-		glColor4f(0, 0.5f, 0, 0.5f);
-		gGL.color4f(0, 0.5f, 0, 0.5f);
+		gGL.diffuseColor4f(0, 0.5f, 0, 0.5f);
+		gGL.diffuseColor4f(0, 0.5f, 0, 0.5f);
 		pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
 	}
 
@@ -2676,8 +2681,8 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
 
 		if (render_objects)
 		{
-			glColor4f(0.f, 0.5f, 0.f,1.f);
-			gGL.color4f(0.f, 0.5f, 0.f, 1.f);
+			gGL.diffuseColor4f(0.f, 0.5f, 0.f,1.f);
+			gGL.diffuseColor4f(0.f, 0.5f, 0.f, 1.f);
 			pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
 		}
 
@@ -2685,8 +2690,8 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
 
 		if (render_objects)
 		{
-			glColor4f(0.f, 0.75f, 0.f,0.5f);
-			gGL.color4f(0.f, 0.75f, 0.f, 0.5f);
+			gGL.diffuseColor4f(0.f, 0.75f, 0.f,0.5f);
+			gGL.diffuseColor4f(0.f, 0.75f, 0.f, 0.5f);
 			pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
 		}
 		/*else if (camera && group->mOcclusionVerts.notNull())
@@ -2694,11 +2699,11 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
 			LLVertexBuffer::unbind();
 			group->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
 			
-			glColor4f(1.0f, 0.f, 0.f, 0.5f);
+			gGL.diffuseColor4f(1.0f, 0.f, 0.f, 0.5f);
 			group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0]));
 			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 			
-			glColor4f(1.0f, 1.f, 1.f, 1.0f);
+			gGL.diffuseColor4f(1.0f, 1.f, 1.f, 1.0f);
 			group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0]));
 			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 		}*/
@@ -2707,7 +2712,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
 
 void renderCrossHairs(LLVector3 position, F32 size, LLColor4 color)
 {
-	gGL.color4fv(color.mV);
+	gGL.diffuseColor4fv(color.mV);
 	gGL.begin(LLRender::LINES);
 	{
 		gGL.vertex3fv((position - LLVector3(size, 0.f, 0.f)).mV);
@@ -2731,23 +2736,23 @@ void renderUpdateType(LLDrawable* drawablep)
 	switch (vobj->getLastUpdateType())
 	{
 	case OUT_FULL:
-		glColor4f(0,1,0,0.5f);
+		gGL.diffuseColor4f(0,1,0,0.5f);
 		break;
 	case OUT_TERSE_IMPROVED:
-		glColor4f(0,1,1,0.5f);
+		gGL.diffuseColor4f(0,1,1,0.5f);
 		break;
 	case OUT_FULL_COMPRESSED:
 		if (vobj->getLastUpdateCached())
 		{
-			glColor4f(1,0,0,0.5f);
+			gGL.diffuseColor4f(1,0,0,0.5f);
 		}
 		else
 		{
-			glColor4f(1,1,0,0.5f);
+			gGL.diffuseColor4f(1,1,0,0.5f);
 		}
 		break;
 	case OUT_FULL_CACHED:
-		glColor4f(0,0,1,0.5f);
+		gGL.diffuseColor4f(0,0,1,0.5f);
 		break;
 	default:
 		llwarns << "Unknown update_type " << vobj->getLastUpdateType() << llendl;
@@ -2879,17 +2884,17 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
 	{
 		if (drawable->isSpatialBridge())
 		{
-			gGL.color4f(1,0.5f,0,1);
+			gGL.diffuseColor4f(1,0.5f,0,1);
 		}
 		else if (drawable->getVOVolume())
 		{
 			if (drawable->isRoot())
 			{
-				gGL.color4f(1,1,0,1);
+				gGL.diffuseColor4f(1,1,0,1);
 			}
 			else
 			{
-				gGL.color4f(0,1,0,1);
+				gGL.diffuseColor4f(0,1,0,1);
 			}
 		}
 		else if (drawable->getVObj())
@@ -2897,30 +2902,30 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
 			switch (drawable->getVObj()->getPCode())
 			{
 				case LLViewerObject::LL_VO_SURFACE_PATCH:
-						gGL.color4f(0,1,1,1);
+						gGL.diffuseColor4f(0,1,1,1);
 						break;
 				case LLViewerObject::LL_VO_CLOUDS:
 						// no longer used
 						break;
 				case LLViewerObject::LL_VO_PART_GROUP:
 				case LLViewerObject::LL_VO_HUD_PART_GROUP:
-						gGL.color4f(0,0,1,1);
+						gGL.diffuseColor4f(0,0,1,1);
 						break;
 				case LLViewerObject::LL_VO_VOID_WATER:
 				case LLViewerObject::LL_VO_WATER:
-						gGL.color4f(0,0.5f,1,1);
+						gGL.diffuseColor4f(0,0.5f,1,1);
 						break;
 				case LL_PCODE_LEGACY_TREE:
-						gGL.color4f(0,0.5f,0,1);
+						gGL.diffuseColor4f(0,0.5f,0,1);
 						break;
 				default:
-						gGL.color4f(1,0,1,1);
+						gGL.diffuseColor4f(1,0,1,1);
 						break;
 			}
 		}
 		else 
 		{
-			gGL.color4f(1,0,0,1);
+			gGL.diffuseColor4f(1,0,0,1);
 		}
 	}
 
@@ -2976,7 +2981,7 @@ void renderNormals(LLDrawable* drawablep)
 	{
 		LLVolume* volume = vol->getVolume();
 		gGL.pushMatrix();
-		glMultMatrixf((F32*) vol->getRelativeXform().mMatrix);
+		gGL.multMatrix((F32*) vol->getRelativeXform().mMatrix);
 		
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
@@ -2986,16 +2991,15 @@ void renderNormals(LLDrawable* drawablep)
 		{
 			const LLVolumeFace& face = volume->getVolumeFace(i);
 
-			gGL.begin(LLRender::LINES);
-			
 			for (S32 j = 0; j < face.mNumVertices; ++j)
 			{
+				gGL.begin(LLRender::LINES);
 				LLVector4a n,p;
 				
 				n.setMul(face.mNormals[j], scale);
 				p.setAdd(face.mPositions[j], n);
 				
-				gGL.color4f(1,1,1,1);
+				gGL.diffuseColor4f(1,1,1,1);
 				gGL.vertex3fv(face.mPositions[j].getF32ptr());
 				gGL.vertex3fv(p.getF32ptr());
 				
@@ -3004,13 +3008,12 @@ void renderNormals(LLDrawable* drawablep)
 					n.setMul(face.mBinormals[j], scale);
 					p.setAdd(face.mPositions[j], n);
 				
-					gGL.color4f(0,1,1,1);
+					gGL.diffuseColor4f(0,1,1,1);
 					gGL.vertex3fv(face.mPositions[j].getF32ptr());
 					gGL.vertex3fv(p.getF32ptr());
 				}	
+				gGL.end();
 			}
-
-			gGL.end();
 		}
 
 		gGL.popMatrix();
@@ -3050,33 +3053,33 @@ void renderMeshBaseHull(LLVOVolume* volume, U32 data_mask, LLColor4& color, LLCo
 	{		
 		if (!decomp->mBaseHullMesh.empty())
 		{
-			glColor4fv(color.mV);
+			gGL.diffuseColor4fv(color.mV);
 			LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mBaseHullMesh.mPositions, decomp->mBaseHullMesh.mNormals);
 		}
 		else
 		{
 			gMeshRepo.buildPhysicsMesh(*decomp);
-			gGL.color3f(0,1,1);
+			gGL.diffuseColor4f(0,1,1,1);
 			drawBoxOutline(center, size);
 		}
 
 	}
 	else
 	{
-		gGL.color3f(1,0,1);
+		gGL.diffuseColor3f(1,0,1);
 		drawBoxOutline(center, size);
 	}
 }
 
 void render_hull(LLModel::PhysicsMesh& mesh, const LLColor4& color, const LLColor4& line_color)
 {
-	glColor4fv(color.mV);
+	gGL.diffuseColor4fv(color.mV);
 	LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions, mesh.mNormals);
 	LLGLEnable offset(GL_POLYGON_OFFSET_LINE);
 	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 	glPolygonOffset(3.f, 3.f);
 	glLineWidth(3.f);
-	glColor4fv(line_color.mV);
+	gGL.diffuseColor4fv(line_color.mV);
 	LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions, mesh.mNormals);
 	glLineWidth(1.f);
 	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@@ -3130,7 +3133,7 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
 	LLVector3 size(0.25f,0.25f,0.25f);
 
 	gGL.pushMatrix();
-	glMultMatrixf((F32*) volume->getRelativeXform().mMatrix);
+	gGL.multMatrix((F32*) volume->getRelativeXform().mMatrix);
 		
 	if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::USER_MESH)
 	{
@@ -3158,11 +3161,11 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
 			else if (!decomp->mPhysicsShapeMesh.empty())
 			{ 
 				//decomp has physics mesh, render that mesh
-				glColor4fv(color.mV);
+				gGL.diffuseColor4fv(color.mV);
 				LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mPhysicsShapeMesh.mPositions, decomp->mPhysicsShapeMesh.mNormals);
 								
 				glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-				glColor4fv(line_color.mV);
+				gGL.diffuseColor4fv(line_color.mV);
 				LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mPhysicsShapeMesh.mPositions, decomp->mPhysicsShapeMesh.mNormals);
 				glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 			}
@@ -3179,7 +3182,7 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
 		}
 		else
 		{	
-			gGL.color3f(1,1,0);
+			gGL.diffuseColor3f(1,1,0);
 			drawBoxOutline(center, size);
 		}
 	}
@@ -3190,7 +3193,6 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
 		{
 			renderMeshBaseHull(volume, data_mask, color, line_color);
 		}
-#if LL_WINDOWS 
 		else
 		{
 			LLVolumeParams volume_params = volume->getVolume()->getParams();
@@ -3288,27 +3290,26 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
 			
 				glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 				
-				glColor4fv(line_color.mV);
+				gGL.diffuseColor4fv(line_color.mV);
 				LLVertexBuffer::unbind();
 
 				llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShader != 0);
-
-				glVertexPointer(3, GL_FLOAT, 16, phys_volume->mHullPoints);
-				glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);
+							
+				LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices);
 				
-				glColor4fv(color.mV);
+				gGL.diffuseColor4fv(color.mV);
 				glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-				glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);
+				LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices);
+				
 			}
 			else
 			{
-				gGL.color3f(1,0,1);
+				gGL.diffuseColor4f(1,0,1,1);
 				drawBoxOutline(center, size);
 			}
 
 			LLPrimitive::sVolumeManager->unrefVolume(phys_volume);
 		}
-#endif //LL_WINDOWS			
 	}
 	else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::BOX)
 	{
@@ -3317,12 +3318,12 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
 		LLVector3 vscale = volume->getScale()*2.f;
 		scale.set(scale[0]/vscale[0], scale[1]/vscale[1], scale[2]/vscale[2]);
 		
-		gGL.color4fv(color.mV);
+		gGL.diffuseColor4fv(color.mV);
 		drawBox(center, scale);
 	}
 	else if	(type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::SPHERE)
 	{
-		LLVolumeParams volume_params;
+		/*LLVolumeParams volume_params;
 		volume_params.setType( LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE );
 		volume_params.setBeginAndEndS( 0.f, 1.f );
 		volume_params.setBeginAndEndT( 0.f, 1.f );
@@ -3330,9 +3331,9 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
 		volume_params.setShear	( 0, 0 );
 		LLVolume* sphere = LLPrimitive::sVolumeManager->refVolume(volume_params, 3);
 		
-		glColor4fv(color.mV);
+		gGL.diffuseColor4fv(color.mV);
 		pushVerts(sphere);
-		LLPrimitive::sVolumeManager->unrefVolume(sphere);
+		LLPrimitive::sVolumeManager->unrefVolume(sphere);*/
 	}
 	else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::CYLINDER)
 	{
@@ -3344,7 +3345,7 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
 		volume_params.setShear	( 0, 0 );
 		LLVolume* cylinder = LLPrimitive::sVolumeManager->refVolume(volume_params, 3);
 		
-		glColor4fv(color.mV);
+		gGL.diffuseColor4fv(color.mV);
 		pushVerts(cylinder);
 		LLPrimitive::sVolumeManager->unrefVolume(cylinder);
 	}
@@ -3356,10 +3357,10 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
 		LLVolume* phys_volume = LLPrimitive::sVolumeManager->refVolume(volume_params, detail);
 		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 		
-		glColor4fv(line_color.mV);
+		gGL.diffuseColor4fv(line_color.mV);
 		pushVerts(phys_volume);
 		
-		glColor4fv(color.mV);
+		gGL.diffuseColor4fv(color.mV);
 		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 		pushVerts(phys_volume);
 		LLPrimitive::sVolumeManager->unrefVolume(phys_volume);
@@ -3377,16 +3378,17 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
 			llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShader != 0);
 			LLVertexBuffer::unbind();
 			glVertexPointer(3, GL_FLOAT, 16, phys_volume->mHullPoints);
-			glColor4fv(line_color.mV);
+			gGL.diffuseColor4fv(line_color.mV);
+			gGL.syncMatrices();
 			glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);
 			
-			glColor4fv(color.mV);
+			gGL.diffuseColor4fv(color.mV);
 			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 			glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);			
 		}
 		else
 		{
-			gGL.color3f(1,0,1);
+			gGL.diffuseColor3f(1,0,1);
 			drawBoxOutline(center, size);
 			gMeshRepo.buildHull(volume_params, detail);
 		}
@@ -3402,15 +3404,6 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
 	}
 
 	gGL.popMatrix();
-
-	/*{ //analytical shape, just push visual rep.
-		glColor3fv(color.mV);
-		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-		pushVerts(drawable, data_mask);
-		glColor4fv(color.mV);
-		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-		pushVerts(drawable, data_mask);
-	}*/
 }
 
 void renderPhysicsShapes(LLSpatialGroup* group)
@@ -3425,7 +3418,7 @@ void renderPhysicsShapes(LLSpatialGroup* group)
 			{
 				gGL.pushMatrix();
 				LLVector3 trans = drawable->getRegion()->getOriginAgent();
-				glTranslatef(trans.mV[0], trans.mV[1], trans.mV[2]);
+				gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
 				renderPhysicsShape(drawable, volume);
 				gGL.popMatrix();
 			}
@@ -3449,12 +3442,12 @@ void renderPhysicsShapes(LLSpatialGroup* group)
 						glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 
 						buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
-						glColor3f(0.2f, 0.5f, 0.3f);
-						buff->draw(LLRender::TRIANGLES, buff->getRequestedIndices(), 0);
+						gGL.diffuseColor3f(0.2f, 0.5f, 0.3f);
+						buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
 									
-						glColor3f(0.2f, 1.f, 0.3f);
+						gGL.diffuseColor3f(0.2f, 1.f, 0.3f);
 						glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-						buff->draw(LLRender::TRIANGLES, buff->getRequestedIndices(), 0);
+						buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
 					}
 				}
 			}
@@ -3491,11 +3484,11 @@ void renderTexturePriority(LLDrawable* drawable)
 			F32 t = vsize/sLastMaxTexPriority;
 			
 			LLVector4 col = lerp(cold, hot, t);
-			gGL.color4fv(col.mV);
+			gGL.diffuseColor4fv(col.mV);
 		}
 		//else
 		//{
-		//	gGL.color4f(1,0,1,1);
+		//	gGL.diffuseColor4f(1,0,1,1);
 		//}
 		
 		LLVector4a center;
@@ -3514,7 +3507,7 @@ void renderTexturePriority(LLDrawable* drawable)
 			LLVector4 col = lerp(boost_cold, boost_hot, t);
 			LLGLEnable blend_on(GL_BLEND);
 			gGL.blendFunc(GL_SRC_ALPHA, GL_ONE);
-			gGL.color4fv(col.mV);
+			gGL.diffuseColor4fv(col.mV);
 			drawBox(center, size);
 			gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 		}*/
@@ -3527,7 +3520,7 @@ void renderPoints(LLDrawable* drawablep)
 	if (drawablep->getNumFaces())
 	{
 		gGL.begin(LLRender::POINTS);
-		gGL.color3f(1,1,1);
+		gGL.diffuseColor3f(1,1,1);
 		for (S32 i = 0; i < drawablep->getNumFaces(); i++)
 		{
 			gGL.vertex3fv(drawablep->getFace(i)->mCenterLocal.mV);
@@ -3544,7 +3537,7 @@ void renderTextureAnim(LLDrawInfo* params)
 	}
 	
 	LLGLEnable blend(GL_BLEND);
-	glColor4f(1,1,0,0.5f);
+	gGL.diffuseColor4f(1,1,0,0.5f);
 	pushVerts(params, LLVertexBuffer::MAP_VERTEX);
 }
 
@@ -3552,7 +3545,7 @@ void renderBatchSize(LLDrawInfo* params)
 {
 	LLGLEnable offset(GL_POLYGON_OFFSET_FILL);
 	glPolygonOffset(-1.f, 1.f);
-	glColor3ubv((GLubyte*) &(params->mDebugColor));
+	gGL.diffuseColor4ubv((GLubyte*) &(params->mDebugColor));
 	pushVerts(params, LLVertexBuffer::MAP_VERTEX);
 }
 
@@ -3570,22 +3563,22 @@ void renderShadowFrusta(LLDrawInfo* params)
 
 	if (gPipeline.mShadowCamera[4].AABBInFrustum(center, size))
 	{
-		glColor3f(1,0,0);
+		gGL.diffuseColor3f(1,0,0);
 		pushVerts(params, LLVertexBuffer::MAP_VERTEX);
 	}
 	if (gPipeline.mShadowCamera[5].AABBInFrustum(center, size))
 	{
-		glColor3f(0,1,0);
+		gGL.diffuseColor3f(0,1,0);
 		pushVerts(params, LLVertexBuffer::MAP_VERTEX);
 	}
 	if (gPipeline.mShadowCamera[6].AABBInFrustum(center, size))
 	{
-		glColor3f(0,0,1);
+		gGL.diffuseColor3f(0,0,1);
 		pushVerts(params, LLVertexBuffer::MAP_VERTEX);
 	}
 	if (gPipeline.mShadowCamera[7].AABBInFrustum(center, size))
 	{
-		glColor3f(1,0,1);
+		gGL.diffuseColor3f(1,0,1);
 		pushVerts(params, LLVertexBuffer::MAP_VERTEX);
 	}
 
@@ -3603,7 +3596,7 @@ void renderLights(LLDrawable* drawablep)
 	if (drawablep->getNumFaces())
 	{
 		LLGLEnable blend(GL_BLEND);
-		glColor4f(0,1,1,0.5f);
+		gGL.diffuseColor4f(0,1,1,0.5f);
 
 		for (S32 i = 0; i < drawablep->getNumFaces(); i++)
 		{
@@ -3621,11 +3614,11 @@ void renderLights(LLDrawable* drawablep)
 
 		{
 			LLGLDepthTest depth(GL_FALSE, GL_TRUE);
-			gGL.color4f(1,1,1,1);
+			gGL.diffuseColor4f(1,1,1,1);
 			drawBoxOutline(pos, size);
 		}
 
-		gGL.color4f(1,1,0,1);
+		gGL.diffuseColor4f(1,1,0,1);
 		F32 rad = drawablep->getVOVolume()->getLightRadius();
 		drawBoxOutline(pos, LLVector4a(rad));
 	}
@@ -3650,13 +3643,13 @@ class LLRenderOctreeRaycast : public LLOctreeTriangleRayIntersect
 		
 		if (branch->getData().empty())
 		{
-			gGL.color3f(1.f,0.2f,0.f);
+			gGL.diffuseColor3f(1.f,0.2f,0.f);
 			center.set(branch->getCenter().getF32ptr());
 			size.set(branch->getSize().getF32ptr());
 		}
 		else
 		{
-			gGL.color3f(0.75f, 1.f, 0.f);
+			gGL.diffuseColor3f(0.75f, 1.f, 0.f);
 			center.set(vl->mBounds[0].getF32ptr());
 			size.set(vl->mBounds[1].getF32ptr());
 		}
@@ -3669,11 +3662,11 @@ class LLRenderOctreeRaycast : public LLOctreeTriangleRayIntersect
 
 			if (i == 1)
 			{
-				gGL.color4f(0,1,1,0.5f);
+				gGL.diffuseColor4f(0,1,1,0.5f);
 			}
 			else
 			{
-				gGL.color4f(0,0.5f,0.5f, 0.25f);
+				gGL.diffuseColor4f(0,0.5f,0.5f, 0.25f);
 				drawBoxOutline(center, size);
 			}
 			
@@ -3710,7 +3703,7 @@ void renderRaycast(LLDrawable* drawablep)
 	if (drawablep->getNumFaces())
 	{
 		LLGLEnable blend(GL_BLEND);
-		gGL.color4f(0,1,1,0.5f);
+		gGL.diffuseColor4f(0,1,1,0.5f);
 
 		if (drawablep->getVOVolume())
 		{
@@ -3741,8 +3734,8 @@ void renderRaycast(LLDrawable* drawablep)
 					}
 
 					gGL.pushMatrix();
-					glTranslatef(trans.mV[0], trans.mV[1], trans.mV[2]);					
-					glMultMatrixf((F32*) vobj->getRelativeXform().mMatrix);
+					gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);					
+					gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix);
 
 					LLVector3 start, end;
 					if (transform)
@@ -3771,8 +3764,9 @@ void renderRaycast(LLDrawable* drawablep)
 					{
 						//render face positions
 						LLVertexBuffer::unbind();
-						glColor4f(0,1,1,0.5f);
+						gGL.diffuseColor4f(0,1,1,0.5f);
 						glVertexPointer(3, GL_FLOAT, sizeof(LLVector4a), face.mPositions);
+						gGL.syncMatrices();
 						glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices);
 					}
 						
@@ -3795,23 +3789,23 @@ void renderRaycast(LLDrawable* drawablep)
 		if (drawablep->getVObj() == gDebugRaycastObject)
 		{
 			// draw intersection point
-			glPushMatrix();
-			glLoadMatrixd(gGLModelView);
+			gGL.pushMatrix();
+			gGL.loadMatrix(gGLModelView);
 			LLVector3 translate = gDebugRaycastIntersection;
-			glTranslatef(translate.mV[0], translate.mV[1], translate.mV[2]);
+			gGL.translatef(translate.mV[0], translate.mV[1], translate.mV[2]);
 			LLCoordFrame orient;
 			orient.lookDir(gDebugRaycastNormal, gDebugRaycastBinormal);
 			LLMatrix4 rotation;
 			orient.getRotMatrixToParent(rotation);
-			glMultMatrixf((float*)rotation.mMatrix);
+			gGL.multMatrix((float*)rotation.mMatrix);
 			
-			gGL.color4f(1,0,0,0.5f);
+			gGL.diffuseColor4f(1,0,0,0.5f);
 			drawBox(LLVector3(0, 0, 0), LLVector3(0.1f, 0.022f, 0.022f));
-			gGL.color4f(0,1,0,0.5f);
+			gGL.diffuseColor4f(0,1,0,0.5f);
 			drawBox(LLVector3(0, 0, 0), LLVector3(0.021f, 0.1f, 0.021f));
-			gGL.color4f(0,0,1,0.5f);
+			gGL.diffuseColor4f(0,0,1,0.5f);
 			drawBox(LLVector3(0, 0, 0), LLVector3(0.02f, 0.02f, 0.1f));
-			glPopMatrix();
+			gGL.popMatrix();
 
 			// draw bounding box of prim
 			const LLVector4a* ext = drawablep->getSpatialExtents();
@@ -3824,7 +3818,7 @@ void renderRaycast(LLDrawable* drawablep)
 			size.mul(0.5f);
 
 			LLGLDepthTest depth(GL_FALSE, GL_TRUE);
-			gGL.color4f(0,0.5f,0.5f,1);
+			gGL.diffuseColor4f(0,0.5f,0.5f,1);
 			drawBoxOutline(pos, size);		
 		}
 	}
@@ -3886,14 +3880,14 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable>
 				group->rebuildMesh();
 
 				gGL.flush();
-				glPushMatrix();
+				gGL.pushMatrix();
 				gGLLastMatrix = NULL;
-				glLoadMatrixd(gGLModelView);
+				gGL.loadMatrix(gGLModelView);
 				renderVisibility(group, mCamera);
 				stop_glerror();
 				gGLLastMatrix = NULL;
-				glPopMatrix();
-				gGL.color4f(1,1,1,1);
+				gGL.popMatrix();
+				gGL.diffuseColor4f(1,1,1,1);
 			}
 		}
 	}
@@ -3917,7 +3911,7 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable>
 		{
 			if (!group->getData().empty())
 			{
-				gGL.color3f(0,0,1);
+				gGL.diffuseColor3f(0,0,1);
 				drawBoxOutline(group->mObjectBounds[0],
 								group->mObjectBounds[1]);
 			}
@@ -3926,7 +3920,7 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable>
 		for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i)
 		{
 			LLDrawable* drawable = *i;
-						
+					
 			if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES))
 			{
 				renderBoundingBox(drawable);			
@@ -3941,7 +3935,7 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable>
 			{
 				if (drawable->isState(LLDrawable::IN_REBUILD_Q2))
 				{
-					gGL.color4f(0.6f, 0.6f, 0.1f, 1.f);
+					gGL.diffuseColor4f(0.6f, 0.6f, 0.1f, 1.f);
 					const LLVector4a* ext = drawable->getSpatialExtents();
 					LLVector4a center;
 					center.setAdd(ext[0], ext[1]);
@@ -4234,6 +4228,11 @@ void LLSpatialPartition::renderDebug()
 		return;
 	}
 	
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		gDebugProgram.bind();
+	}
+
 	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
 	{
 		//sLastMaxTexPriority = lerp(sLastMaxTexPriority, sCurMaxTexPriority, gFrameIntervalSeconds);
@@ -4262,11 +4261,16 @@ void LLSpatialPartition::renderDebug()
 
 	LLOctreeRenderNonOccluded render_debug(camera);
 	render_debug.traverse(mOctree);
+
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		gDebugProgram.unbind();
+	}
 }
 
 void LLSpatialGroup::drawObjectBox(LLColor4 col)
 {
-	gGL.color4fv(col.mV);
+	gGL.diffuseColor4fv(col.mV);
 	LLVector4a size;
 	size = mObjectBounds[1];
 	size.mul(1.01f);
@@ -4371,7 +4375,7 @@ class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler
 		LLVector3 local_start = mStart;
 		LLVector3 local_end = mEnd;
 
-		if (!gPipeline.hasRenderType(drawable->getRenderType()) || !drawable->isVisible())
+		if (!drawable || !gPipeline.hasRenderType(drawable->getRenderType()) || !drawable->isVisible())
 		{
 			return false;
 		}
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 11955540c62a870493bac0d2db70743db5cb31bc..f0c8a372ee3224c8f2b11f5ba99b8e5a05bb72b1 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -93,7 +93,6 @@ class LLDrawInfo : public LLRefCount
 	LLPointer<LLViewerTexture>     mTexture;
 	std::vector<LLPointer<LLViewerTexture> > mTextureList;
 
-	LLColor4U mGlowColor;
 	S32 mDebugColor;
 	const LLMatrix4* mTextureMatrix;
 	const LLMatrix4* mModelMatrix;
diff --git a/indra/newview/llsprite.cpp b/indra/newview/llsprite.cpp
index 4bde2dfcab55160ec92b88633588ae6dec55c6f5..c3eb70f850c2a7622d5a2423b7e32908a2a850a9 100644
--- a/indra/newview/llsprite.cpp
+++ b/indra/newview/llsprite.cpp
@@ -243,7 +243,7 @@ void LLSprite::updateFace(LLFace &face)
 		*indicesp++ = 3 + index_offset;
 	}
 
-	face.getVertexBuffer()->setBuffer(0);
+	face.getVertexBuffer()->flush();
 	face.mCenterAgent = mPosition;
 }
 
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index e62227fa3c7f48e621923996ae8ec410cc3ec3ec..6e9679edb41fa76e4c2b001277754caa9fb0f975 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -736,8 +736,11 @@ bool idle_startup()
 		// this startup phase more than once.
 		if (gLoginMenuBarView == NULL)
 		{
-		initialize_edit_menu();
+			display_startup();
+			initialize_edit_menu();
+			display_startup();
 			init_menus();
+			display_startup();
 		}
 
 		if (show_connect_box)
@@ -746,23 +749,28 @@ bool idle_startup()
 			// NOTE: Hits "Attempted getFields with no login view shown" warning, since we don't
 			// show the login view until login_show() is called below.  
 			if (gUserCredential.isNull())                                                                          
-			{                                                                                                      
+			{                                                  
+				display_startup();
 				gUserCredential = gLoginHandler.initializeLoginInfo();                 
+				display_startup();
 			}     
 			if (gHeadlessClient)
 			{
 				LL_WARNS("AppInit") << "Waiting at connection box in headless client.  Did you mean to add autologin params?" << LL_ENDL;
 			}
 			// Make sure the process dialog doesn't hide things
+			display_startup();
 			gViewerWindow->setShowProgress(FALSE);
-
+			display_startup();
 			// Show the login dialog
 			login_show();
+			display_startup();
 			// connect dialog is already shown, so fill in the names
 			if (gUserCredential.notNull())                                                                         
 			{                                                                                                      
 				LLPanelLogin::setFields( gUserCredential, gRememberPassword);                                  
 			}     
+			display_startup();
 			LLPanelLogin::giveFocus();
 
 			LLStartUp::setStartupState( STATE_LOGIN_WAIT );		// Wait for user input
@@ -773,14 +781,19 @@ bool idle_startup()
 			LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
 		}
 
+		display_startup();
 		gViewerWindow->setNormalControlsVisible( FALSE );	
+		display_startup();
 		gLoginMenuBarView->setVisible( TRUE );
+		display_startup();
 		gLoginMenuBarView->setEnabled( TRUE );
+		display_startup();
 		show_debug_menus();
+		display_startup();
 
 		// Hide the splash screen
 		LLSplashScreen::hide();
-
+		display_startup();
 		// Push our window frontmost
 		gViewerWindow->getWindow()->show();
 		display_startup();
@@ -789,7 +802,10 @@ bool idle_startup()
 		// first made visible.
 #ifdef _WIN32
 		MSG msg;
-		while( PeekMessage( &msg, /*All hWnds owned by this thread */ NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE ) );
+		while( PeekMessage( &msg, /*All hWnds owned by this thread */ NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE ) )
+		{
+			display_startup();
+		}
 #endif
 		timeout.reset();
 		return FALSE;
@@ -804,7 +820,7 @@ bool idle_startup()
 
 		// Don't do anything.  Wait for the login view to call the login_callback,
 		// which will push us to the next state.
-
+		display_startup();
 		// Sleep so we don't spin the CPU
 		ms_sleep(1);
 		return FALSE;
@@ -1172,37 +1188,51 @@ bool idle_startup()
 
 		// Finish agent initialization.  (Requires gSavedSettings, builds camera)
 		gAgent.init();
+		display_startup();
 		gAgentCamera.init();
+		display_startup();
 		set_underclothes_menu_options();
+		display_startup();
 
 		// Since we connected, save off the settings so the user doesn't have to
 		// type the name/password again if we crash.
 		gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
 		LLUIColorTable::instance().saveUserSettings();
 
+		display_startup();
+
 		//
 		// Initialize classes w/graphics stuff.
 		//
 		gTextureList.doPrefetchImages();		
+		display_startup();
+
 		LLSurface::initClasses();
+		display_startup();
+
 
 		LLFace::initClass();
+		display_startup();
 
 		LLDrawable::initClass();
+		display_startup();
 
 		// init the shader managers
 		LLPostProcess::initClass();
+		display_startup();
 
 		LLViewerObject::initVOClasses();
+		display_startup();
 
 		// Initialize all our tools.  Must be done after saved settings loaded.
 		// NOTE: This also is where gToolMgr used to be instantiated before being turned into a singleton.
 		LLToolMgr::getInstance()->initTools();
+		display_startup();
 
 		// Pre-load floaters, like the world map, that are slow to spawn
 		// due to XML complexity.
 		gViewerWindow->initWorldUI();
-
+		
 		display_startup();
 
 		// This is where we used to initialize gWorldp. Original comment said:
@@ -1210,24 +1240,26 @@ bool idle_startup()
 
 		// User might have overridden far clip
 		LLWorld::getInstance()->setLandFarClip(gAgentCamera.mDrawDistance);
-
+		display_startup();
 		// Before we create the first region, we need to set the agent's mOriginGlobal
 		// This is necessary because creating objects before this is set will result in a
 		// bad mPositionAgent cache.
 
 		gAgent.initOriginGlobal(from_region_handle(gFirstSimHandle));
+		display_startup();
 
 		LLWorld::getInstance()->addRegion(gFirstSimHandle, gFirstSim);
+		display_startup();
 
 		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(gFirstSimHandle);
 		LL_INFOS("AppInit") << "Adding initial simulator " << regionp->getOriginGlobal() << LL_ENDL;
 		
 		regionp->setSeedCapability(gFirstSimSeedCap);
 		LL_DEBUGS("AppInit") << "Waiting for seed grant ...." << LL_ENDL;
-		
+		display_startup();
 		// Set agent's initial region to be the one we just created.
 		gAgent.setRegion(regionp);
-
+		display_startup();
 		// Set agent's initial position, which will be read by LLVOAvatar when the avatar
 		// object is created.  I think this must be done after setting the region.  JC
 		gAgent.setPositionAgent(agent_start_position_region);
@@ -1247,6 +1279,7 @@ bool idle_startup()
 	{
 		LLStartUp::multimediaInit();
 		LLStartUp::setStartupState( STATE_FONT_INIT );
+		display_startup();
 		return FALSE;
 	}
 
@@ -1255,6 +1288,7 @@ bool idle_startup()
 	{
 		LLStartUp::fontInit();
 		LLStartUp::setStartupState( STATE_SEED_GRANTED_WAIT );
+		display_startup();
 		return FALSE;
 	}
 
@@ -1282,6 +1316,7 @@ bool idle_startup()
 				set_startup_status(0.4f, LLTrans::getString("LoginRequestSeedCapGrant"), gAgent.mMOTD);
 			}
 		}
+		display_startup();
 		return FALSE;
 	}
 
@@ -1292,7 +1327,9 @@ bool idle_startup()
 	//---------------------------------------------------------------------
 	if (STATE_SEED_CAP_GRANTED == LLStartUp::getStartupState())
 	{
+		display_startup();
 		update_texture_fetch();
+		display_startup();
 
 		if ( gViewerWindow != NULL)
 		{	// This isn't the first logon attempt, so show the UI
@@ -1300,12 +1337,15 @@ bool idle_startup()
 		}	
 		gLoginMenuBarView->setVisible( FALSE );
 		gLoginMenuBarView->setEnabled( FALSE );
+		display_startup();
 
 		// direct logging to the debug console's line buffer
 		LLError::logToFixedBuffer(gDebugView->mDebugConsolep);
+		display_startup();
 		
 		// set initial visibility of debug console
 		gDebugView->mDebugConsolep->setVisible(gSavedSettings.getBOOL("ShowDebugConsole"));
+		display_startup();
 
 		//
 		// Set message handlers
@@ -1314,22 +1354,28 @@ bool idle_startup()
 
 		// register callbacks for messages. . . do this after initial handshake to make sure that we don't catch any unwanted
 		register_viewer_callbacks(gMessageSystem);
+		display_startup();
 
 		// Debugging info parameters
 		gMessageSystem->setMaxMessageTime( 0.5f );			// Spam if decoding all msgs takes more than 500 ms
+		display_startup();
 
 		#ifndef	LL_RELEASE_FOR_DOWNLOAD
 			gMessageSystem->setTimeDecodes( TRUE );				// Time the decode of each msg
 			gMessageSystem->setTimeDecodesSpamThreshold( 0.05f );  // Spam if a single msg takes over 50ms to decode
 		#endif
+		display_startup();
 
 		gXferManager->registerCallbacks(gMessageSystem);
+		display_startup();
 
 		LLStartUp::initNameCache();
+		display_startup();
 
 		// update the voice settings *after* gCacheName initialization
 		// so that we can construct voice UI that relies on the name cache
 		LLVoiceClient::getInstance()->updateSettings();
+		display_startup();
 
 		//gCacheName is required for nearby chat history loading
 		//so I just moved nearby history loading a few states further
@@ -1338,12 +1384,14 @@ bool idle_startup()
 			LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
 			if (nearby_chat) nearby_chat->loadHistory();
 		}
+		display_startup();
 
 		// *Note: this is where gWorldMap used to be initialized.
 
 		// register null callbacks for audio until the audio system is initialized
 		gMessageSystem->setHandlerFuncFast(_PREHASH_SoundTrigger, null_message_callback, NULL);
 		gMessageSystem->setHandlerFuncFast(_PREHASH_AttachedSound, null_message_callback, NULL);
+		display_startup();
 
 		//reset statistics
 		LLViewerStats::getInstance()->resetStats();
@@ -1373,6 +1421,7 @@ bool idle_startup()
 		LLViewerCamera::getInstance()->setAspect(gViewerWindow->getWorldViewAspectRatio());
 		// Initialize FOV
 		LLViewerCamera::getInstance()->setDefaultFOV(gSavedSettings.getF32("CameraAngle")); 
+		display_startup();
 
 		// Move agent to starting location. The position handed to us by
 		// the space server is in global coordinates, but the agent frame
@@ -1383,6 +1432,7 @@ bool idle_startup()
 		gAgent.resetAxes(gAgentStartLookAt);
 		gAgentCamera.stopCameraAnimation();
 		gAgentCamera.resetCamera();
+		display_startup();
 
 		// Initialize global class data needed for surfaces (i.e. textures)
 		LL_DEBUGS("AppInit") << "Initializing sky..." << LL_ENDL;
@@ -1395,6 +1445,8 @@ bool idle_startup()
 		LLGLState::checkStates();
 		LLGLState::checkTextureChannels();
 
+		display_startup();
+
 		LL_DEBUGS("AppInit") << "Decoding images..." << LL_ENDL;
 		// For all images pre-loaded into viewer cache, decode them.
 		// Need to do this AFTER we init the sky
@@ -1408,6 +1460,8 @@ bool idle_startup()
 		}
 		LLStartUp::setStartupState( STATE_WORLD_WAIT );
 
+		display_startup();
+
 		// JC - Do this as late as possible to increase likelihood Purify
 		// will run.
 		LLMessageSystem* msg = gMessageSystem;
@@ -1435,6 +1489,7 @@ bool idle_startup()
 			NULL);
 
 		timeout.reset();
+		display_startup();
 
 		return FALSE;
 	}
@@ -1453,8 +1508,10 @@ bool idle_startup()
 		LLMessageSystem* msg = gMessageSystem;
 		while (msg->checkAllMessages(gFrameCount, gServicePump))
 		{
+			display_startup();
 		}
 		msg->processAcks();
+		display_startup();
 		return FALSE;
 	}
 
@@ -1465,6 +1522,7 @@ bool idle_startup()
 	{
 		LL_DEBUGS("AppInit") << "Connecting to region..." << LL_ENDL;
 		set_startup_status(0.60f, LLTrans::getString("LoginConnectingToRegion"), gAgent.mMOTD);
+		display_startup();
 		// register with the message system so it knows we're
 		// expecting this message
 		LLMessageSystem* msg = gMessageSystem;
@@ -1480,6 +1538,7 @@ bool idle_startup()
 			msg->newMessageFast(_PREHASH_EconomyDataRequest);
 			gAgent.sendReliableMessage();
 		}
+		display_startup();
 
 		// Create login effect
 		// But not on first login, because you can't see your avatar then
@@ -1494,6 +1553,7 @@ bool idle_startup()
 		LLStartUp::setStartupState( STATE_AGENT_WAIT );		// Go to STATE_AGENT_WAIT
 
 		timeout.reset();
+		display_startup();
 		return FALSE;
 	}
 
@@ -1518,14 +1578,17 @@ bool idle_startup()
 				LL_DEBUGS("AppInit") << "Awaiting AvatarInitComplete, got "
 				<< msg->getMessageName() << LL_ENDL;
 			}
+			display_startup();
 		}
 		msg->processAcks();
 
+		display_startup();
+
 		if (gAgentMovementCompleted)
 		{
 			LLStartUp::setStartupState( STATE_INVENTORY_SEND );
 		}
-
+		display_startup();
 		return FALSE;
 	}
 
@@ -1534,9 +1597,10 @@ bool idle_startup()
 	//---------------------------------------------------------------------
 	if (STATE_INVENTORY_SEND == LLStartUp::getStartupState())
 	{
+		display_startup();
 		// Inform simulator of our language preference
 		LLAgentLanguage::update();
-
+		display_startup();
 		// unpack thin inventory
 		LLSD response = LLLoginInstance::getInstance()->getResponse();
 		//bool dump_buffer = false;
@@ -1551,6 +1615,7 @@ bool idle_startup()
 				gInventory.setLibraryRootFolderID(id.asUUID());
 			}
 		}
+		display_startup();
  		
 		LLSD inv_lib_owner = response["inventory-lib-owner"];
 		if(inv_lib_owner.isDefined())
@@ -1562,6 +1627,7 @@ bool idle_startup()
 				gInventory.setLibraryOwnerID( LLUUID(id.asUUID()));
 			}
 		}
+		display_startup();
 
 		LLSD inv_skel_lib = response["inventory-skel-lib"];
  		if(inv_skel_lib.isDefined() && gInventory.getLibraryOwnerID().notNull())
@@ -1571,6 +1637,7 @@ bool idle_startup()
  				LL_WARNS("AppInit") << "Problem loading inventory-skel-lib" << LL_ENDL;
  			}
  		}
+		display_startup();
 
 		LLSD inv_skeleton = response["inventory-skeleton"];
  		if(inv_skeleton.isDefined())
@@ -1580,6 +1647,7 @@ bool idle_startup()
  				LL_WARNS("AppInit") << "Problem loading inventory-skel-targets" << LL_ENDL;
  			}
  		}
+		display_startup();
 
 		LLSD inv_basic = response["inventory-basic"];
  		if(inv_basic.isDefined())
@@ -1617,6 +1685,7 @@ bool idle_startup()
 				list[agent_id] = new LLRelationship(given_rights, has_rights, false);
 			}
 			LLAvatarTracker::instance().addBuddyList(list);
+			display_startup();
  		}
 
 		bool show_hud = false;
@@ -1644,6 +1713,8 @@ bool idle_startup()
 				//}
 			}
 		}
+		display_startup();
+
 		// Either we want to show tutorial because this is the first login
 		// to a Linden Help Island or the user quit with the tutorial
 		// visible.  JC
@@ -1651,22 +1722,26 @@ bool idle_startup()
 		{
 			LLFloaterReg::showInstance("hud", LLSD(), FALSE);
 		}
+		display_startup();
 
 		LLSD event_notifications = response["event_notifications"];
 		if(event_notifications.isDefined())
 		{
 			gEventNotifier.load(event_notifications);
 		}
+		display_startup();
 
 		LLSD classified_categories = response["classified_categories"];
 		if(classified_categories.isDefined())
 		{
 			LLClassifiedInfo::loadCategories(classified_categories);
 		}
+		display_startup();
 
 		// This method MUST be called before gInventory.findCategoryUUIDForType because of 
 		// gInventory.mIsAgentInvUsable is set to true in the gInventory.buildParentChildMap.
 		gInventory.buildParentChildMap();
+		display_startup();
 
 		//all categories loaded. lets create "My Favorites" category
 		gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE,true);
@@ -1680,24 +1755,26 @@ bool idle_startup()
 		LLAvatarTracker::instance().registerCallbacks(msg);
 		llinfos << " Landmark" << llendl;
 		LLLandmark::registerCallbacks(msg);
+		display_startup();
 
 		// request mute list
 		llinfos << "Requesting Mute List" << llendl;
 		LLMuteList::getInstance()->requestFromServer(gAgent.getID());
-
+		display_startup();
 		// Get L$ and ownership credit information
 		llinfos << "Requesting Money Balance" << llendl;
 		LLStatusBar::sendMoneyBalanceRequest();
-
+		display_startup();
 		// request all group information
 		llinfos << "Requesting Agent Data" << llendl;
 		gAgent.sendAgentDataUpdateRequest();
-
+		display_startup();
 		// Create the inventory views
 		llinfos << "Creating Inventory Views" << llendl;
 		LLFloaterReg::getInstance("inventory");
-
+		display_startup();
 		LLStartUp::setStartupState( STATE_MISC );
+		display_startup();
 		return FALSE;
 	}
 
@@ -1746,17 +1823,23 @@ bool idle_startup()
 			gSavedSettings.setBOOL("ShowStartLocation", TRUE);
 		}
 
+		display_startup();
+
 		if (gSavedSettings.getBOOL("HelpFloaterOpen"))
 		{
 			// show default topic
 			LLViewerHelp::instance().showTopic("");
 		}
 
+		display_startup();
+
 		// We're successfully logged in.
 		gSavedSettings.setBOOL("FirstLoginThisInstall", FALSE);
 
 		LLFloaterReg::showInitialVisibleInstances();
 
+		display_startup();
+
 		// based on the comments, we've successfully logged in so we can delete the 'forced'
 		// URL that the updater set in settings.ini (in a mostly paranoid fashion)
 		std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
@@ -1770,8 +1853,10 @@ bool idle_startup()
 			LLUIColorTable::instance().saveUserSettings();
 		};
 
+		display_startup();
 		// JC: Initializing audio requests many sounds for download.
 		init_audio();
+		display_startup();
 
 		// JC: Initialize "active" gestures.  This may also trigger
 		// many gesture downloads, if this is the user's first
@@ -1809,6 +1894,7 @@ bool idle_startup()
 			LLGestureMgr::instance().startFetch();
 		}
 		gDisplaySwapBuffers = TRUE;
+		display_startup();
 
 		LLMessageSystem* msg = gMessageSystem;
 		msg->setHandlerFuncFast(_PREHASH_SoundTrigger,				process_sound_trigger);
@@ -1883,8 +1969,10 @@ bool idle_startup()
 			}
 		}
 
+		display_startup();
         //DEV-17797.  get null folder.  Any items found here moved to Lost and Found
         LLInventoryModelBackgroundFetch::instance().findLostItems();
+		display_startup();
 
 		LLStartUp::setStartupState( STATE_PRECACHE );
 		timeout.reset();
@@ -1893,6 +1981,7 @@ bool idle_startup()
 
 	if (STATE_PRECACHE == LLStartUp::getStartupState())
 	{
+		display_startup();
 		F32 timeout_frac = timeout.getElapsedTimeF32()/PRECACHING_DELAY;
 
 		// We now have an inventory skeleton, so if this is a user's first
@@ -1909,6 +1998,8 @@ bool idle_startup()
 			LLStartUp::loadInitialOutfit( sInitialOutfit, sInitialOutfitGender );
 		}
 
+		display_startup();
+
 		// wait precache-delay and for agent's avatar or a lot longer.
 		if(((timeout_frac > 1.f) && isAgentAvatarValid())
 		   || (timeout_frac > 3.f))
@@ -1922,11 +2013,6 @@ bool idle_startup()
 				LLTrans::getString("LoginPrecaching"),
 					gAgent.mMOTD);
 			display_startup();
-			if (!LLViewerShaderMgr::sInitialized)
-			{
-				LLViewerShaderMgr::sInitialized = TRUE;
-				LLViewerShaderMgr::instance()->setShaders();
-			}
 		}
 		
 		return TRUE;
@@ -1955,6 +2041,8 @@ bool idle_startup()
 			return TRUE;
 		}
 		
+		display_startup();
+
 		if (wearables_time > MAX_WEARABLES_TIME)
 		{
 			LLNotificationsUtil::add("ClothingLoading");
@@ -1986,16 +2074,20 @@ bool idle_startup()
 			}
 		}
 
+		display_startup();
 		update_texture_fetch();
+		display_startup();
 		set_startup_status(0.9f + 0.1f * wearables_time / MAX_WEARABLES_TIME,
 						 LLTrans::getString("LoginDownloadingClothing").c_str(),
 						 gAgent.mMOTD.c_str());
+		display_startup();
 		return TRUE;
 	}
 
 	if (STATE_CLEANUP == LLStartUp::getStartupState())
 	{
 		set_startup_status(1.0, "", "");
+		display_startup();
 
 		// Let the map know about the inventory.
 		LLFloaterWorldMap* floater_world_map = LLFloaterWorldMap::getInstance();
@@ -2011,6 +2103,7 @@ bool idle_startup()
 		//gViewerWindow->revealIntroPanel();
 		gViewerWindow->setStartupComplete(); 
 		gViewerWindow->setProgressCancelButtonVisible(FALSE);
+		display_startup();
 
 		// We're not away from keyboard, even though login might have taken
 		// a while. JC
@@ -2046,6 +2139,7 @@ bool idle_startup()
 		// LLUserAuth::getInstance()->reset();
 
 		LLStartUp::setStartupState( STATE_STARTED );
+		display_startup();
 
 		// Unmute audio if desired and setup volumes.
 		// Unmute audio if desired and setup volumes.
@@ -2070,6 +2164,7 @@ bool idle_startup()
 		LLAgentPicksInfo::getInstance()->requestNumberOfPicks();
 
 		LLIMFloater::initIMFloater();
+		display_startup();
 
 		return TRUE;
 	}
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
index e8abee2fb76c07d55ef61f92ca5642f3792d6010..9f5cbf6ec8829d9afe86fce543129b6185ca65c0 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/newview/lltexlayer.cpp
@@ -216,22 +216,22 @@ void LLTexLayerSetBuffer::cancelUpload()
 
 void LLTexLayerSetBuffer::pushProjection() const
 {
-	glMatrixMode(GL_PROJECTION);
+	gGL.matrixMode(LLRender::MM_PROJECTION);
 	gGL.pushMatrix();
-	glLoadIdentity();
-	glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
+	gGL.loadIdentity();
+	gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
 
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.pushMatrix();
-	glLoadIdentity();
+	gGL.loadIdentity();
 }
 
 void LLTexLayerSetBuffer::popProjection() const
 {
-	glMatrixMode(GL_PROJECTION);
+	gGL.matrixMode(LLRender::MM_PROJECTION);
 	gGL.popMatrix();
 
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.popMatrix();
 }
 
@@ -294,18 +294,22 @@ BOOL LLTexLayerSetBuffer::render()
 	const BOOL update_now = mNeedsUpdate && isReadyToUpdate();
 	
 	BOOL success = TRUE;
-
-	//hack to use fixed function when updating tex layer sets
-	bool no_ff = LLGLSLShader::sNoFixedFunction;
-	LLGLSLShader::sNoFixedFunction = false;
 	
+	bool use_shaders = LLGLSLShader::sNoFixedFunction;
+
+	if (use_shaders)
+	{
+		gAlphaMaskProgram.bind();
+		gAlphaMaskProgram.setAlphaRange(0.004f, 1.f);
+	}
+
+	LLVertexBuffer::unbind();
+
 	// Composite the color data
 	LLGLSUIDefault gls_ui;
 	success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight );
 	gGL.flush();
 
-	LLGLSLShader::sNoFixedFunction = no_ff;
-	
 	if(upload_now)
 	{
 		if (!success)
@@ -335,6 +339,13 @@ BOOL LLTexLayerSetBuffer::render()
 		doUpdate();
 	}
 
+	if (use_shaders)
+	{
+		gAlphaMaskProgram.unbind();
+	}
+
+	LLVertexBuffer::unbind();
+	
 	// reset GL state
 	gGL.setColorMask(true, true);
 	gGL.setSceneBlendType(LLRender::BT_ALPHA);
@@ -924,6 +935,8 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
 		}
 	}
 
+	bool use_shaders = LLGLSLShader::sNoFixedFunction;
+
 	LLGLSUIDefault gls_ui;
 	LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE);
 	gGL.setColorMask(true, true);
@@ -932,12 +945,20 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
 	{
 		gGL.flush();
 		LLGLDisable no_alpha(GL_ALPHA_TEST);
+		if (use_shaders)
+		{
+			gAlphaMaskProgram.setAlphaRange(0.0f, 1.f);
+		}
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.color4f( 0.f, 0.f, 0.f, 1.f );
 
 		gl_rect_2d_simple( width, height );
 
 		gGL.flush();
+		if (use_shaders)
+		{
+			gAlphaMaskProgram.setAlphaRange(0.004f, 1.f);
+		}
 	}
 
 	if (mIsVisible)
@@ -964,6 +985,11 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
 
 		gGL.setSceneBlendType(LLRender::BT_REPLACE);
 		LLGLDisable no_alpha(GL_ALPHA_TEST);
+		if (use_shaders)
+		{
+			gAlphaMaskProgram.setAlphaRange(0.f, 1.f);
+		}
+
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.color4f( 0.f, 0.f, 0.f, 0.f );
 
@@ -971,7 +997,10 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
 		gGL.setSceneBlendType(LLRender::BT_ALPHA);
 
 		gGL.flush();
-
+		if (use_shaders)
+		{
+			gAlphaMaskProgram.setAlphaRange(0.004f, 1.f);
+		}
 	}
 
 	return success;
@@ -1078,13 +1107,14 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height,
 {
 	const LLTexLayerSetInfo *info = getInfo();
 	
+	bool use_shaders = LLGLSLShader::sNoFixedFunction;
+
 	gGL.setColorMask(false, true);
 	gGL.setSceneBlendType(LLRender::BT_REPLACE);
 	
 	// (Optionally) replace alpha with a single component image from a tga file.
 	if (!info->mStaticAlphaFileName.empty())
 	{
-		LLGLSNoAlphaTest gls_no_alpha_test;
 		gGL.flush();
 		{
 			LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(info->mStaticAlphaFileName, TRUE);
@@ -1103,12 +1133,20 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height,
 		// Set the alpha channel to one (clean up after previous blending)
 		gGL.flush();
 		LLGLDisable no_alpha(GL_ALPHA_TEST);
+		if (use_shaders)
+		{
+			gAlphaMaskProgram.setAlphaRange(0.f, 1.f);
+		}
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.color4f( 0.f, 0.f, 0.f, 1.f );
 		
 		gl_rect_2d_simple( width, height );
 		
 		gGL.flush();
+		if (use_shaders)
+		{
+			gAlphaMaskProgram.setAlphaRange(0.004f, 1.f);
+		}
 	}
 	
 	// (Optional) Mask out part of the baked texture with alpha masks
@@ -1593,6 +1631,8 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 	LLGLEnable color_mat(GL_COLOR_MATERIAL);
 	gPipeline.disableLights();
 
+	bool use_shaders = LLGLSLShader::sNoFixedFunction;
+
 	LLColor4 net_color;
 	BOOL color_specified = findNetColor(&net_color);
 	
@@ -1673,8 +1713,13 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 			{
 				if( tex )
 				{
-					LLGLDisable alpha_test(getInfo()->mWriteAllChannels ? GL_ALPHA_TEST : 0);
-
+					bool no_alpha_test = getInfo()->mWriteAllChannels;
+					LLGLDisable alpha_test(no_alpha_test ? GL_ALPHA_TEST : 0);
+					if (use_shaders && no_alpha_test)
+					{
+						gAlphaMaskProgram.setAlphaRange(0.f, 1.f);
+					}
+					
 					LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode();
 					
 					gGL.getTexUnit(0)->bind(tex, TRUE);
@@ -1684,6 +1729,11 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 
 					gGL.getTexUnit(0)->setTextureAddressMode(old_mode);
 					gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+					if (use_shaders && no_alpha_test)
+					{
+						gAlphaMaskProgram.setAlphaRange(0.004f, 1.f);
+					}
+					
 				}
 			}
 //			else
@@ -1716,9 +1766,17 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 		color_specified )
 	{
 		LLGLDisable no_alpha(GL_ALPHA_TEST);
+		if (use_shaders)
+		{
+			gAlphaMaskProgram.setAlphaRange(0.f, 1.f);
+		}
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.color4fv( net_color.mV );
 		gl_rect_2d_simple( width, height );
+		if (use_shaders)
+		{
+			gAlphaMaskProgram.setAlphaRange(0.004f, 1.f);
+		}
 	}
 
 	if( alpha_mask_specified || getInfo()->mWriteAllChannels )
@@ -1806,15 +1864,25 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)
 
 	gGL.flush();
 	
+	bool use_shaders = LLGLSLShader::sNoFixedFunction;
+
 	if( !getInfo()->mStaticImageFileName.empty() )
 	{
 		LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask );
 		if( tex )
 		{
 			LLGLSNoAlphaTest gls_no_alpha_test;
+			if (use_shaders)
+			{
+				gAlphaMaskProgram.setAlphaRange(0.f, 1.f);
+			}
 			gGL.getTexUnit(0)->bind(tex, TRUE);
 			gl_rect_2d_simple_tex( width, height );
 			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+			if (use_shaders)
+			{
+				gAlphaMaskProgram.setAlphaRange(0.004f, 1.f);
+			}
 		}
 		else
 		{
@@ -1829,10 +1897,18 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)
 			if (tex)
 			{
 				LLGLSNoAlphaTest gls_no_alpha_test;
+				if (use_shaders)
+				{
+					gAlphaMaskProgram.setAlphaRange(0.f, 1.f);
+				}
 				gGL.getTexUnit(0)->bind(tex);
 				gl_rect_2d_simple_tex( width, height );
 				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 				success = TRUE;
+				if (use_shaders)
+				{
+					gAlphaMaskProgram.setAlphaRange(0.004f, 1.f);
+				}
 			}
 		}
 	}
@@ -1851,6 +1927,13 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
 
 	llassert( !mParamAlphaList.empty() );
 
+	bool use_shaders = LLGLSLShader::sNoFixedFunction;
+
+	if (use_shaders)
+	{
+		gAlphaMaskProgram.setAlphaRange(0.f, 1.f);
+	}
+
 	gGL.setColorMask(false, true);
 
 	LLTexLayerParamAlpha* first_param = *mParamAlphaList.begin();
@@ -1888,7 +1971,6 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
 		if( tex && (tex->getComponents() == 4) )
 		{
 			LLGLSNoAlphaTest gls_no_alpha_test;
-
 			LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode();
 			
 			gGL.getTexUnit(0)->bind(tex, TRUE);
@@ -1927,6 +2009,10 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
 		gl_rect_2d_simple( width, height );
 	}
 
+	if (use_shaders)
+	{
+		gAlphaMaskProgram.setAlphaRange(0.004f, 1.f);
+	}
 
 	LLGLSUIDefault gls_ui;
 
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 6547154bc481e879817ab4b02adfa2b45161a6e2..1c89766b2672b61d5a0bf446c5154d83c04b5d78 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -527,11 +527,12 @@ void LLGLTexMemBar::draw()
 	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,
 											 text_color, LLFontGL::LEFT, LLFontGL::TOP);
 
-	text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d",
+	text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d",
 					total_mem,
 					max_total_mem,
 					bound_mem,
 					max_bound_mem,
+					LLRenderTarget::sBytesAllocated/(1024*1024),
 					LLImageRaw::sGlobalRawMemory >> 20,	discard_bias,
 					cache_usage, cache_max_usage, total_texture_downloaded, total_object_downloaded, total_http_requests);
 	//, cache_entries, cache_max_entries
@@ -571,7 +572,7 @@ void LLGLTexMemBar::draw()
 	color = (total_mem < llfloor(max_total_mem * texmem_lower_bound_scale)) ? LLColor4::green :
 		  	(total_mem < max_total_mem) ? LLColor4::yellow : LLColor4::red;
 	color[VALPHA] = .75f;
-	glColor4fv(color.mV);
+	gGL.diffuseColor4fv(color.mV);
 	
 	gl_rect_2d(left, top, right, bottom); // red/yellow/green
 
@@ -594,7 +595,7 @@ void LLGLTexMemBar::draw()
 	color = (bound_mem < llfloor(max_bound_mem * texmem_lower_bound_scale)) ? LLColor4::green :
 		  	(bound_mem < max_bound_mem) ? LLColor4::yellow : LLColor4::red;
 	color[VALPHA] = .75f;
-	glColor4fv(color.mV);
+	gGL.diffuseColor4fv(color.mV);
 
 	gl_rect_2d(left, top, right, bottom);
 #else
diff --git a/indra/newview/lltoolbrush.cpp b/indra/newview/lltoolbrush.cpp
index 9782b90cf1b3f2233cf75c3072d4004c5491ea9a..aba43a971534def7c0b709438c1104522f0dd09c 100644
--- a/indra/newview/lltoolbrush.cpp
+++ b/indra/newview/lltoolbrush.cpp
@@ -507,12 +507,12 @@ void LLToolBrushLand::render()
 void LLToolBrushLand::renderOverlay(LLSurface& land, const LLVector3& pos_region,
 									const LLVector3& pos_world)
 {
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	LLGLDepthTest mDepthTest(GL_TRUE);
-	glPushMatrix();
+	gGL.pushMatrix();
 	gGL.color4fv(OVERLAY_COLOR.mV);
-	glTranslatef(0.0f, 0.0f, 1.0f);
+	gGL.translatef(0.0f, 0.0f, 1.0f);
 	
 	S32 i = (S32) pos_region.mV[VX];
 	S32 j = (S32) pos_region.mV[VY];
@@ -566,7 +566,7 @@ void LLToolBrushLand::renderOverlay(LLSurface& land, const LLVector3& pos_region
 	}
 	gGL.end();
 
-	glPopMatrix();
+	gGL.popMatrix();
 }
 
 void LLToolBrushLand::determineAffectedRegions(region_list_t& regions,
diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp
index 964b17d3a665b1bc1f3cadc4d12cb86a30db15d8..718201e381ad43dbea301b0618632dbb76da10ee 100644
--- a/indra/newview/lltoolmorph.cpp
+++ b/indra/newview/lltoolmorph.cpp
@@ -169,23 +169,28 @@ BOOL LLVisualParamHint::render()
 	gGL.pushUIMatrix();
 	gGL.loadUIIdentity();
 
-	glMatrixMode(GL_PROJECTION);
+	gGL.matrixMode(LLRender::MM_PROJECTION);
 	gGL.pushMatrix();
-	glLoadIdentity();
-	glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
+	gGL.loadIdentity();
+	gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
 
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.pushMatrix();
-	glLoadIdentity();
+	gGL.loadIdentity();
+
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		gUIProgram.bind();
+	}
 
 	LLGLSUIDefault gls_ui;
 	//LLGLState::verify(TRUE);
 	mBackgroundp->draw(0, 0, mFullWidth, mFullHeight);
 
-	glMatrixMode(GL_PROJECTION);
+	gGL.matrixMode(LLRender::MM_PROJECTION);
 	gGL.popMatrix();
 
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.popMatrix();
 
 	mNeedsUpdate = FALSE;
diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp
index efe9bb8da7cdeb27f0ea6c1c16959ee1f77a358c..bf1f8808a7028a43658683c8a195f8ede6aae07d 100644
--- a/indra/newview/lltracker.cpp
+++ b/indra/newview/lltracker.cpp
@@ -509,9 +509,10 @@ void LLTracker::renderBeacon(LLVector3d pos_global,
 	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
 	
 	
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
-		glTranslatef(pos_agent.mV[0], pos_agent.mV[1], pos_agent.mV[2]);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.pushMatrix();
+	{
+		gGL.translatef(pos_agent.mV[0], pos_agent.mV[1], pos_agent.mV[2]);
 		
 		draw_shockwave(1024.f, gRenderStartTime.getElapsedTimeF32(), 32, fogged_color);
 
@@ -563,9 +564,8 @@ void LLTracker::renderBeacon(LLVector3d pos_global,
 			
 			gGL.end();
 		}
-							
-		//gCylinder.render(1000);
-	glPopMatrix();
+	}
+	gGL.popMatrix();
 
 	std::string text;
 	text = llformat( "%.0f m", to_vec.magVec());
diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp
index 36c8b42a5223eab5369e9d4b2bca9728da8bc03f..d042f6283086783baa01118b6f0a44ae69c3cb47 100644
--- a/indra/newview/llviewerassetstorage.cpp
+++ b/indra/newview/llviewerassetstorage.cpp
@@ -116,7 +116,7 @@ void LLViewerAssetStorage::storeAssetData(
 	F64 timeout)
 {
 	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
-	llinfos << "LLViewerAssetStorage::storeAssetData (legacy) " << tid << ":" << LLAssetType::lookup(asset_type)
+	LL_DEBUGS("AssetStorage") << "LLViewerAssetStorage::storeAssetData (legacy) " << tid << ":" << LLAssetType::lookup(asset_type)
 			<< " ASSET_ID: " << asset_id << llendl;
 	
 	if (mUpstreamHost.isOk())
@@ -248,9 +248,9 @@ void LLViewerAssetStorage::storeAssetData(
 	}
 	
 	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
-	llinfos << "LLViewerAssetStorage::storeAssetData (legacy)" << asset_id << ":" << LLAssetType::lookup(asset_type) << llendl;
+	LL_DEBUGS("AssetStorage") << "LLViewerAssetStorage::storeAssetData (legacy)" << asset_id << ":" << LLAssetType::lookup(asset_type) << llendl;
 
-	llinfos << "ASSET_ID: " << asset_id << llendl;
+	LL_DEBUGS("AssetStorage") << "ASSET_ID: " << asset_id << llendl;
 
 	S32 size = 0;
 	LLFILE* fp = LLFile::fopen(filename, "rb");
@@ -369,7 +369,7 @@ void LLViewerAssetStorage::_queueDataRequest(
 			tpvf.setAsset(uuid, atype);
 			tpvf.setCallback(downloadCompleteCallback, req);
 
-			llinfos << "Starting transfer for " << uuid << llendl;
+			LL_DEBUGS("AssetStorage") << "Starting transfer for " << uuid << llendl;
 			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(mUpstreamHost, LLTCT_ASSET);
 			ttcp->requestTransfer(spa, tpvf, 100.f + (is_priority ? 1.f : 0.f));
 
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index 7f7366dd3d9ec50b2cf857c28c80e2c05e0938e3..a437a8b3b53624fbfc657507db888792291a474e 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -218,8 +218,15 @@ void LLViewerCamera::calcProjection(const F32 far_distance) const
 void LLViewerCamera::updateFrustumPlanes(LLCamera& camera, BOOL ortho, BOOL zflip, BOOL no_hacks)
 {
 	GLint* viewport = (GLint*) gGLViewport;
-	GLdouble* model = gGLModelView;
-	GLdouble* proj = gGLProjection;
+	F64 model[16];
+	F64 proj[16];
+
+	for (U32 i = 0; i < 16; i++)
+	{
+		model[i] = (F64) gGLModelView[i];
+		proj[i] = (F64) gGLProjection[i];
+	}
+
 	GLdouble objX,objY,objZ;
 
 	LLVector3 frust[8];
@@ -325,8 +332,8 @@ void LLViewerCamera::setPerspective(BOOL for_selection,
 	aspect = getAspect();
 
 	// Load camera view matrix
-	glMatrixMode( GL_PROJECTION );
-	glLoadIdentity();
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.loadIdentity();
 
 	glh::matrix4f proj_mat;
 
@@ -385,14 +392,14 @@ void LLViewerCamera::setPerspective(BOOL for_selection,
 
 	proj_mat *= gl_perspective(fov_y,aspect,z_near,z_far);
 
-	glLoadMatrixf(proj_mat.m);
+	gGL.loadMatrix(proj_mat.m);
 
 	for (U32 i = 0; i < 16; i++)
 	{
 		gGLProjection[i] = proj_mat.m[i];
 	}
 
-	glMatrixMode( GL_MODELVIEW );
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 
 	glh::matrix4f modelview((GLfloat*) OGL_TO_CFR_ROTATION);
 
@@ -402,7 +409,7 @@ void LLViewerCamera::setPerspective(BOOL for_selection,
 
 	modelview *= glh::matrix4f(ogl_matrix);
 	
-	glLoadMatrixf(modelview.m);
+	gGL.loadMatrix(modelview.m);
 	
 	if (for_selection && (width > 1 || height > 1))
 	{
@@ -420,7 +427,6 @@ void LLViewerCamera::setPerspective(BOOL for_selection,
 	if (!for_selection && mZoomFactor == 1.f)
 	{
 		// Save GL matrices for access elsewhere in code, especially project_world_to_screen
-		//glGetDoublev(GL_MODELVIEW_MATRIX, gGLModelView);
 		for (U32 i = 0; i < 16; i++)
 		{
 			gGLModelView[i] = modelview.m[i];
@@ -428,14 +434,6 @@ void LLViewerCamera::setPerspective(BOOL for_selection,
 	}
 
 	updateFrustumPlanes(*this);
-
-	/*if (gSavedSettings.getBOOL("CameraOffset"))
-	{
-		glMatrixMode(GL_PROJECTION);
-		glTranslatef(0,0,-50);
-		glRotatef(20.0,1,0,0);
-		glMatrixMode(GL_MODELVIEW);
-	}*/
 }
 
 
@@ -443,11 +441,20 @@ void LLViewerCamera::setPerspective(BOOL for_selection,
 // screen coordinates to the agent's region.
 void LLViewerCamera::projectScreenToPosAgent(const S32 screen_x, const S32 screen_y, LLVector3* pos_agent) const
 {
-
 	GLdouble x, y, z;
+
+	F64 mdlv[16];
+	F64 proj[16];
+
+	for (U32 i = 0; i < 16; i++)
+	{
+		mdlv[i] = (F64) gGLModelView[i];
+		proj[i] = (F64) gGLProjection[i];
+	}
+
 	gluUnProject(
 		GLdouble(screen_x), GLdouble(screen_y), 0.0,
-		gGLModelView, gGLProjection, (GLint*)gGLViewport,
+		mdlv, proj, (GLint*)gGLViewport,
 		&x,
 		&y,
 		&z );
@@ -484,8 +491,17 @@ BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord
 	viewport[2] = world_view_rect.getWidth();
 	viewport[3] = world_view_rect.getHeight();
 
+	F64 mdlv[16];
+	F64 proj[16];
+
+	for (U32 i = 0; i < 16; i++)
+	{
+		mdlv[i] = (F64) gGLModelView[i];
+		proj[i] = (F64) gGLProjection[i];
+	}
+
 	if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ],
-								gGLModelView, gGLProjection, (GLint*)viewport,
+								mdlv, proj, (GLint*)viewport,
 								&x, &y, &z))
 	{
 		// convert screen coordinates to virtual UI coordinates
@@ -587,9 +603,19 @@ BOOL LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent,
 	viewport[2] = world_view_rect.getWidth();
 	viewport[3] = world_view_rect.getHeight();
 	GLdouble	x, y, z;			// object's window coords, GL-style
+
+	F64 mdlv[16];
+	F64 proj[16];
+
+	for (U32 i = 0; i < 16; i++)
+	{
+		mdlv[i] = (F64) gGLModelView[i];
+		proj[i] = (F64) gGLProjection[i];
+	}
+
 	if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY],
-							  pos_agent.mV[VZ], gGLModelView,
-							  gGLProjection, (GLint*)viewport,
+							  pos_agent.mV[VZ], mdlv,
+							  proj, (GLint*)viewport,
 							  &x, &y, &z))
 	{
 		x /= gViewerWindow->getDisplayScale().mV[VX];
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 967e26be0ceef439be1dbd84f5ef0244b76dc863..d9210877dd23a9205a37f5c8ac470b5647e5bae6 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -118,12 +118,6 @@ static bool handleSetShaderChanged(const LLSD& newvalue)
 	gBumpImageList.destroyGL();
 	gBumpImageList.restoreGL();
 
-	// Changing shader also changes the terrain detail to high, reflect that change here
-	if (newvalue.asBoolean())
-	{
-		// shaders enabled, set terrain detail to high
-		gSavedSettings.setS32("RenderTerrainDetail", 1);
-	}
 	// else, leave terrain detail as is
 	LLViewerShaderMgr::instance()->setShaders();
 	return true;
@@ -187,21 +181,6 @@ static bool handleReleaseGLBufferChanged(const LLSD& newvalue)
 	return true;
 }
 
-static bool handleFSAASamplesChanged(const LLSD& newvalue)
-{
-	if (gPipeline.isInit())
-	{
-		gPipeline.releaseGLBuffers();
-		gPipeline.createGLBuffers();
-
-		if (LLPipeline::sRenderDeferred)
-		{
-			LLViewerShaderMgr::instance()->setShaders();
-		}
-	}
-	return true;
-}
-
 static bool handleAnisotropicChanged(const LLSD& newvalue)
 {
 	LLImageGL::sGlobalUseAnisotropic = newvalue.asBoolean();
@@ -403,6 +382,7 @@ static bool handleRenderDeferredChanged(const LLSD& newvalue)
 	LLRenderTarget::sUseFBO = newvalue.asBoolean();
 	if (gPipeline.isInit())
 	{
+		LLPipeline::refreshCachedSettings();
 		gPipeline.updateRenderDeferred();
 		gPipeline.releaseGLBuffers();
 		gPipeline.createGLBuffers();
@@ -588,7 +568,7 @@ void settings_setup_listeners()
 	gSavedSettings.getControl("OctreeMaxNodeCapacity")->getSignal()->connect(boost::bind(&handleRepartition, _2));
 	gSavedSettings.getControl("OctreeAlphaDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
 	gSavedSettings.getControl("OctreeAttachmentSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
-	gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
+	gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
 	gSavedSettings.getControl("RenderUseTriStrips")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
 	gSavedSettings.getControl("RenderAnimateTrees")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
 	gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
@@ -597,12 +577,10 @@ void settings_setup_listeners()
 	gSavedSettings.getControl("RenderSpecularResX")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
 	gSavedSettings.getControl("RenderSpecularResY")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
 	gSavedSettings.getControl("RenderSpecularExponent")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
-	gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleFSAASamplesChanged, _2));
 	gSavedSettings.getControl("RenderAnisotropic")->getSignal()->connect(boost::bind(&handleAnisotropicChanged, _2));
 	gSavedSettings.getControl("RenderShadowResolutionScale")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
 	gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
 	gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
-	gSavedSettings.getControl("EnableRippleWater")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
 	gSavedSettings.getControl("RenderGlowResolutionPow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
 	gSavedSettings.getControl("RenderAvatarCloth")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
 	gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
@@ -633,7 +611,6 @@ void settings_setup_listeners()
 	gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleRenderDeferredChanged, _2));
 	gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
 	gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
-	gSavedSettings.getControl("RenderDeferredGI")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
 	gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2));
 	gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2));
 	gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _2));
@@ -658,6 +635,7 @@ void settings_setup_listeners()
 	gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
 	gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
 	gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
+	gSavedSettings.getControl("RenderUseVAO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
 	gSavedSettings.getControl("RenderVBOMappingDisable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
 	gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
 	gSavedSettings.getControl("RenderPreferStreamDraw")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index d6512207aebe3db0c5150792ffb247a3fdd78d34..86102e9a150ae21d1203ad9c0e2a0d020aa9d7fe 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -124,7 +124,8 @@ void display_startup()
 
 	// Update images?
 	//gImageList.updateImages(0.01f);
-	
+	LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
+
 	LLGLSDefault gls_default;
 
 	// Required for HTML update in login screen
@@ -212,6 +213,10 @@ static LLFastTimer::DeclareTimer FTM_RENDER("Render", true);
 static LLFastTimer::DeclareTimer FTM_UPDATE_SKY("Update Sky");
 static LLFastTimer::DeclareTimer FTM_UPDATE_TEXTURES("Update Textures");
 static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE("Update Images");
+static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_CLASS("Class");
+static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_BUMP("Bump");
+static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_LIST("List");
+static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_DELETE("Delete");
 
 // Paint the display!
 void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
@@ -224,6 +229,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 		gGL.flush();
 		glClear(GL_COLOR_BUFFER_BIT);
 		gViewerWindow->getWindow()->swapBuffers();
+		LLPipeline::refreshCachedSettings();
+		LLPipeline::refreshRenderDeferred();
 		gPipeline.resizeScreenTexture();
 		gResizeScreenTexture = FALSE;
 		gWindowResized = FALSE;
@@ -523,10 +530,9 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 	// Note that these are not the same as GL defaults...
 
 	stop_glerror();
-	F32 one[4] =	{1.f, 1.f, 1.f, 1.f};
-	glLightModelfv (GL_LIGHT_MODEL_AMBIENT,one);
+	gGL.setAmbientLightColor(LLColor4::white);
 	stop_glerror();
-		
+			
 	/////////////////////////////////////
 	//
 	// Render
@@ -611,12 +617,10 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 		//Increment drawable frame counter
 		LLDrawable::incrementVisible();
 
+		LLPipeline::refreshCachedSettings();
+		LLPipeline::refreshRenderDeferred();
+
 		LLSpatialGroup::sNoDelete = TRUE;
-		LLPipeline::sUseOcclusion = 
-				(!gUseWireframe
-				&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") 
-				&& gSavedSettings.getBOOL("UseOcclusion") 
-				&& gGLManager.mHasOcclusionQuery) ? 2 : 0;
 		LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
 
 		/*if (LLPipeline::sUseOcclusion && LLPipeline::sRenderDeferred)
@@ -624,12 +628,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 			LLPipeline::sUseOcclusion = 3;
 		}*/
 
-		LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred");
-		LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred");
-		LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip");
-		LLVOAvatar::sMaxVisible = (U32)gSavedSettings.getS32("RenderAvatarMaxVisible");
-		LLPipeline::sDelayVBUpdate = gSavedSettings.getBOOL("RenderDelayVBUpdate");
-
 		S32 occlusion = LLPipeline::sUseOcclusion;
 		if (gDepthDirty)
 		{ //depth buffer is invalid, don't overwrite occlusion state
@@ -657,10 +655,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 		
 		{ 
 			LLMemType mt_ds(LLMemType::MTYPE_DISPLAY_SWAP);
-			{
- 				LLFastTimer ftm(FTM_CLIENT_COPY);
-				LLVertexBuffer::clientCopy(0.016);
-			}
 
 			if (gResizeScreenTexture)
 			{
@@ -701,10 +695,10 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 
 				glh_set_current_projection(proj);
 				glh_set_current_modelview(mod);
-				glMatrixMode(GL_PROJECTION);
-				glLoadMatrixf(proj.m);
-				glMatrixMode(GL_MODELVIEW);
-				glLoadMatrixf(mod.m);
+				gGL.matrixMode(LLRender::MM_PROJECTION);
+				gGL.loadMatrix(proj.m);
+				gGL.matrixMode(LLRender::MM_MODELVIEW);
+				gGL.loadMatrix(mod.m);
 				gViewerWindow->setup3DViewport();
 
 				LLGLState::checkStates();
@@ -724,6 +718,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 			LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery");
 			gPipeline.generateWaterReflection(*LLViewerCamera::getInstance());
 			gPipeline.generateHighlight(*LLViewerCamera::getInstance());
+			gPipeline.renderPhysicsDisplay();
 		}
 
 		LLGLState::checkStates();
@@ -742,18 +737,31 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 			LLMemType mt_iu(LLMemType::MTYPE_DISPLAY_IMAGE_UPDATE);
 			LLFastTimer t(FTM_IMAGE_UPDATE);
 			
-			LLViewerTexture::updateClass(LLViewerCamera::getInstance()->getVelocityStat()->getMean(),
-										LLViewerCamera::getInstance()->getAngularVelocityStat()->getMean());
+			{
+				LLFastTimer t(FTM_IMAGE_UPDATE_CLASS);
+				LLViewerTexture::updateClass(LLViewerCamera::getInstance()->getVelocityStat()->getMean(),
+											LLViewerCamera::getInstance()->getAngularVelocityStat()->getMean());
+			}
 
-			gBumpImageList.updateImages();  // must be called before gTextureList version so that it's textures are thrown out first.
+			
+			{
+				LLFastTimer t(FTM_IMAGE_UPDATE_BUMP);
+				gBumpImageList.updateImages();  // must be called before gTextureList version so that it's textures are thrown out first.
+			}
 
-			F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds; // 50 ms/second decode time
-			max_image_decode_time = llclamp(max_image_decode_time, 0.002f, 0.005f ); // min 2ms/frame, max 5ms/frame)
-			gTextureList.updateImages(max_image_decode_time);
+			{
+				LLFastTimer t(FTM_IMAGE_UPDATE_LIST);
+				F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds; // 50 ms/second decode time
+				max_image_decode_time = llclamp(max_image_decode_time, 0.002f, 0.005f ); // min 2ms/frame, max 5ms/frame)
+				gTextureList.updateImages(max_image_decode_time);
+			}
 
-			//remove dead textures from GL
-			LLImageGL::deleteDeadTextures();
-			stop_glerror();
+			{
+				LLFastTimer t(FTM_IMAGE_UPDATE_DELETE);
+				//remove dead textures from GL
+				LLImageGL::deleteDeadTextures();
+				stop_glerror();
+			}
 		}
 
 		LLGLState::checkStates();
@@ -812,13 +820,13 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 		//// assumes frontmost floater with focus is opaque
 		//if (frontmost_floaterp && gFocusMgr.childHasKeyboardFocus(frontmost_floaterp))
 		//{
-		//	glMatrixMode(GL_MODELVIEW);
-		//	glPushMatrix();
+		//	gGL.matrixMode(LLRender::MM_MODELVIEW);
+		//	gGL.pushMatrix();
 		//	{
 		//		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 		//		glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
-		//		glLoadIdentity();
+		//		gGL.loadIdentity();
 
 		//		LLRect floater_rect = frontmost_floaterp->calcScreenRect();
 		//		// deflate by one pixel so rounding errors don't occlude outside of floater extents
@@ -828,8 +836,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 		//								(F32)floater_rect.mRight / (F32)gViewerWindow->getWindowWidthScaled(),
 		//								(F32)floater_rect.mBottom / (F32)gViewerWindow->getWindowHeightScaled());
 		//		floater_3d_rect.translate(-0.5f, -0.5f);
-		//		glTranslatef(0.f, 0.f, -LLViewerCamera::getInstance()->getNear());
-		//		glScalef(LLViewerCamera::getInstance()->getNear() * LLViewerCamera::getInstance()->getAspect() / sinf(LLViewerCamera::getInstance()->getView()), LLViewerCamera::getInstance()->getNear() / sinf(LLViewerCamera::getInstance()->getView()), 1.f);
+		//		gGL.translatef(0.f, 0.f, -LLViewerCamera::getInstance()->getNear());
+		//		gGL.scalef(LLViewerCamera::getInstance()->getNear() * LLViewerCamera::getInstance()->getAspect() / sinf(LLViewerCamera::getInstance()->getView()), LLViewerCamera::getInstance()->getNear() / sinf(LLViewerCamera::getInstance()->getView()), 1.f);
 		//		gGL.color4fv(LLColor4::white.mV);
 		//		gGL.begin(LLVertexBuffer::QUADS);
 		//		{
@@ -841,11 +849,10 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 		//		gGL.end();
 		//		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
 		//	}
-		//	glPopMatrix();
+		//	gGL.popMatrix();
 		//}
 
 		LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
-		LLPipeline::refreshRenderDeferred();
 		
 		LLGLState::checkStates();
 		LLGLState::checkClientArrays();
@@ -865,6 +872,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 			else
 			{
 				gPipeline.mScreen.bindTarget();
+				if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders())
+				{
+					const LLColor4 &col = LLDrawPoolWater::sWaterFogColor;
+					glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
+				}
 				gPipeline.mScreen.clear();
 			}
 			
@@ -978,10 +990,10 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 void render_hud_attachments()
 {
 	LLMemType mt_ra(LLMemType::MTYPE_DISPLAY_RENDER_ATTACHMENTS);
-	glMatrixMode(GL_PROJECTION);
-	glPushMatrix();
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.pushMatrix();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.pushMatrix();
 		
 	glh::matrix4f current_proj = glh_get_current_projection();
 	glh::matrix4f current_mod = glh_get_current_modelview();
@@ -1067,10 +1079,10 @@ void render_hud_attachments()
 		}
 		LLPipeline::sUseOcclusion = use_occlusion;
 	}
-	glMatrixMode(GL_PROJECTION);
-	glPopMatrix();
-	glMatrixMode(GL_MODELVIEW);
-	glPopMatrix();
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.popMatrix();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.popMatrix();
 	
 	glh_set_current_projection(current_proj);
 	glh_set_current_modelview(current_mod);
@@ -1153,12 +1165,12 @@ BOOL setup_hud_matrices(const LLRect& screen_region)
 	if (!result) return result;
 	
 	// set up transform to keep HUD objects in front of camera
-	glMatrixMode(GL_PROJECTION);
-	glLoadMatrixf(proj.m);
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.loadMatrix(proj.m);
 	glh_set_current_projection(proj);
 	
-	glMatrixMode(GL_MODELVIEW);
-	glLoadMatrixf(model.m);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.loadMatrix(model.m);
 	glh_set_current_modelview(model);
 	return TRUE;
 }
@@ -1174,8 +1186,8 @@ void render_ui(F32 zoom_factor, int subfield)
 
 	if (!gSnapshot)
 	{
-		glPushMatrix();
-		glLoadMatrixd(gGLLastModelView);
+		gGL.pushMatrix();
+		gGL.loadMatrix(gGLLastModelView);
 		glh_set_current_modelview(glh_copy_matrix(gGLLastModelView));
 	}
 	
@@ -1231,7 +1243,7 @@ void render_ui(F32 zoom_factor, int subfield)
 	if (!gSnapshot)
 	{
 		glh_set_current_modelview(saved_view);
-		glPopMatrix();
+		gGL.popMatrix();
 	}
 
 	if (gDisplaySwapBuffers)
@@ -1304,10 +1316,10 @@ void draw_axes()
 		gGL.vertex3f(0.0f, 0.0f, 40.0f);
 	gGL.end();
 	// Some coordinate axes
-	glPushMatrix();
-		glTranslatef( v.mV[VX], v.mV[VY], v.mV[VZ] );
+	gGL.pushMatrix();
+		gGL.translatef( v.mV[VX], v.mV[VY], v.mV[VZ] );
 		renderCoordinateAxes();
-	glPopMatrix();
+	gGL.popMatrix();
 }
 
 void render_ui_3d()
@@ -1336,7 +1348,12 @@ void render_ui_3d()
 	}
 
 	stop_glerror();
-		
+	
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		gUIProgram.bind();
+	}
+
 	gViewerWindow->renderSelections(FALSE, FALSE, TRUE); // Non HUD call in render_hud_elements
 	stop_glerror();
 }
@@ -1377,10 +1394,10 @@ void render_ui_2d()
 		gGL.pushMatrix();
 		S32 half_width = (gViewerWindow->getWorldViewWidthScaled() / 2);
 		S32 half_height = (gViewerWindow->getWorldViewHeightScaled() / 2);
-		glScalef(LLUI::sGLScaleFactor.mV[0], LLUI::sGLScaleFactor.mV[1], 1.f);
-		glTranslatef((F32)half_width, (F32)half_height, 0.f);
+		gGL.scalef(LLUI::sGLScaleFactor.mV[0], LLUI::sGLScaleFactor.mV[1], 1.f);
+		gGL.translatef((F32)half_width, (F32)half_height, 0.f);
 		F32 zoom = gAgentCamera.mHUDCurZoom;
-		glScalef(zoom,zoom,1.f);
+		gGL.scalef(zoom,zoom,1.f);
 		gGL.color4fv(LLColor4::white.mV);
 		gl_rect_2d(-half_width, half_height, half_width, -half_height, FALSE);
 		gGL.popMatrix();
@@ -1459,6 +1476,11 @@ void render_ui_2d()
 
 void render_disconnected_background()
 {
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		gUIProgram.bind();
+	}
+
 	gGL.color4f(1,1,1,1);
 	if (!gDisconnectedImagep && gDisconnected)
 	{
@@ -1512,22 +1534,28 @@ void render_disconnected_background()
 	{
 		LLGLSUIDefault gls_ui;
 		gViewerWindow->setup2DRender();
-		glPushMatrix();
+		gGL.pushMatrix();
 		{
 			// scale ui to reflect UIScaleFactor
 			// this can't be done in setup2DRender because it requires a
 			// pushMatrix/popMatrix pair
 			const LLVector2& display_scale = gViewerWindow->getDisplayScale();
-			glScalef(display_scale.mV[VX], display_scale.mV[VY], 1.f);
+			gGL.scalef(display_scale.mV[VX], display_scale.mV[VY], 1.f);
 
 			gGL.getTexUnit(0)->bind(gDisconnectedImagep);
 			gGL.color4f(1.f, 1.f, 1.f, 1.f);
 			gl_rect_2d_simple_tex(width, height);
 			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		}
-		glPopMatrix();
+		gGL.popMatrix();
 	}
 	gGL.flush();
+
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		gUIProgram.unbind();
+	}
+
 }
 
 void display_cleanup()
diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp
index baf85d68848ea60cce2fa8cbbaad3a32a30123bf..a907f102f87f55a4680224c1d522b024b0577158 100644
--- a/indra/newview/llviewerjoint.cpp
+++ b/indra/newview/llviewerjoint.cpp
@@ -126,7 +126,7 @@ void LLViewerJoint::setValid( BOOL valid, BOOL recursive )
 // 	//----------------------------------------------------------------
 // 	// push matrix stack
 // 	//----------------------------------------------------------------
-// 	glPushMatrix();
+// 	gGL.pushMatrix();
 
 // 	//----------------------------------------------------------------
 // 	// render the bone to my parent
@@ -140,8 +140,8 @@ void LLViewerJoint::setValid( BOOL valid, BOOL recursive )
 // 	// offset to joint position and 
 // 	// rotate to our orientation
 // 	//----------------------------------------------------------------
-// 	glLoadIdentity();
-// 	glMultMatrixf( &getWorldMatrix().mMatrix[0][0] );
+// 	gGL.loadIdentity();
+// 	gGL.multMatrix( &getWorldMatrix().mMatrix[0][0] );
 
 // 	//----------------------------------------------------------------
 // 	// render joint axes
@@ -233,7 +233,7 @@ void LLViewerJoint::setValid( BOOL valid, BOOL recursive )
 // 	//----------------------------------------------------------------
 // 	// pop matrix stack
 // 	//----------------------------------------------------------------
-// 	glPopMatrix();
+// 	gGL.popMatrix();
 // }
 
 
@@ -346,7 +346,7 @@ U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
 // 	F32 boneSize = 0.02f;
 
 // 	// rotate to point to child (bone direction)
-// 	glPushMatrix();
+// 	gGL.pushMatrix();
 
 // 	LLVector3 boneX = getPosition();
 // 	F32 length = boneX.normVec();
@@ -362,7 +362,7 @@ U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
 // 	rotateMat.setFwdRow( boneX );
 // 	rotateMat.setLeftRow( boneY );
 // 	rotateMat.setUpRow( boneZ );
-// 	glMultMatrixf( &rotateMat.mMatrix[0][0] );
+// 	gGL.multMatrix( &rotateMat.mMatrix[0][0] );
 
 // 	// render the bone
 // 	gGL.color3f( 0.5f, 0.5f, 0.0f );
@@ -388,7 +388,7 @@ U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
 // 	gGL.end();
 
 // 	// restore matrix
-// 	glPopMatrix();
+// 	gGL.popMatrix();
 // }
 
 //--------------------------------------------------------------------
@@ -541,9 +541,9 @@ void LLViewerJointCollisionVolume::renderCollision()
 	updateWorldMatrix();
 	
 	gGL.pushMatrix();
-	glMultMatrixf( &mXform.getWorldMatrix().mMatrix[0][0] );
+	gGL.multMatrix( &mXform.getWorldMatrix().mMatrix[0][0] );
 
-	gGL.color3f( 0.f, 0.f, 1.f );
+	gGL.diffuseColor3f( 0.f, 0.f, 1.f );
 	
 	gGL.begin(LLRender::LINES);
 	
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index 77c8bb032949d7bd9b9f0bd94252b0e2e0ba3f8a..3e20abecb7dd7747aff1cac56527881abd76efe6 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -459,7 +459,10 @@ void LLViewerJointMesh::uploadJointMatrices()
 			}
 		}
 		stop_glerror();
-		glUniform4fvARB(gAvatarMatrixParam, 45, mat);
+		if (LLGLSLShader::sCurBoundShaderPtr)
+		{
+			LLGLSLShader::sCurBoundShaderPtr->uniform4fv(LLViewerShaderMgr::AVATAR_MATRIX, 45, mat);
+		}
 		stop_glerror();
 	}
 	else
@@ -512,7 +515,8 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
 {
 	if (!mValid || !mMesh || !mFace || !mVisible || 
 		!mFace->getVertexBuffer() ||
-		mMesh->getNumFaces() == 0) 
+		mMesh->getNumFaces() == 0 ||
+		(LLGLSLShader::sNoFixedFunction && LLGLSLShader::sCurBoundShaderPtr == NULL))
 	{
 		return 0;
 	}
@@ -527,13 +531,13 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
 	// setup current color
 	//----------------------------------------------------------------
 	if (is_dummy)
-		glColor4fv(LLVOAvatar::getDummyColor().mV);
+		gGL.diffuseColor4fv(LLVOAvatar::getDummyColor().mV);
 	else
-		glColor4fv(mColor.mV);
+		gGL.diffuseColor4fv(mColor.mV);
 
 	stop_glerror();
 	
-	LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), mFace->getPool()->getVertexShaderLevel() > 0 ? 0.f : mShiny);
+	LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), (mFace->getPool()->getVertexShaderLevel() > 0 || LLGLSLShader::sNoFixedFunction) ? 0.f : mShiny);
 
 	//----------------------------------------------------------------
 	// setup current texture
@@ -547,11 +551,11 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
 
 		if (mIsTransparent)
 		{
-			glColor4f(1.f, 1.f, 1.f, 1.f);
+			gGL.diffuseColor4f(1.f, 1.f, 1.f, 1.f);
 		}
 		else
 		{
-			glColor4f(0.7f, 0.6f, 0.3f, 1.f);
+			gGL.diffuseColor4f(0.7f, 0.6f, 0.3f, 1.f);
 			gGL.getTexUnit(diffuse_channel)->setTextureColorBlend(LLTexUnit::TBO_LERP_TEX_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
 		}
 	}
@@ -582,13 +586,16 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
 		gGL.getTexUnit(diffuse_channel)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT));
 	}
 	
-	mFace->getVertexBuffer()->setBuffer(sRenderMask);
+	
+	U32 mask = sRenderMask;
 
 	U32 start = mMesh->mFaceVertexOffset;
 	U32 end = start + mMesh->mFaceVertexCount - 1;
 	U32 count = mMesh->mFaceIndexCount;
 	U32 offset = mMesh->mFaceIndexOffset;
 
+	LLVertexBuffer* buff = mFace->getVertexBuffer();
+
 	if (mMesh->hasWeights())
 	{
 		if ((mFace->getPool()->getVertexShaderLevel() > 0))
@@ -597,17 +604,24 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
 			{
 				uploadJointMatrices();
 			}
+			mask = mask | LLVertexBuffer::MAP_WEIGHT;
+			if (mFace->getPool()->getVertexShaderLevel() > 1)
+			{
+				mask = mask | LLVertexBuffer::MAP_CLOTHWEIGHT;
+			}
 		}
 		
-		mFace->getVertexBuffer()->drawRange(LLRender::TRIANGLES, start, end, count, offset);
+		buff->setBuffer(mask);
+		buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
 	}
 	else
 	{
-		glPushMatrix();
+		gGL.pushMatrix();
 		LLMatrix4 jointToWorld = getWorldMatrix();
-		glMultMatrixf((GLfloat*)jointToWorld.mMatrix);
-		mFace->getVertexBuffer()->drawRange(LLRender::TRIANGLES, start, end, count, offset);
-		glPopMatrix();
+		gGL.multMatrix((GLfloat*)jointToWorld.mMatrix);
+		buff->setBuffer(mask);
+		buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
+		gGL.popMatrix();
 	}
 	gPipeline.addTrianglesDrawn(count);
 
@@ -692,9 +706,9 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w
 
 		if (num_verts)
 		{
-			face->getGeometryAvatar(verticesp, normalsp, tex_coordsp, vertex_weightsp, clothing_weightsp);
 			face->getVertexBuffer()->getIndexStrider(indicesp);
-
+			face->getGeometryAvatar(verticesp, normalsp, tex_coordsp, vertex_weightsp, clothing_weightsp);
+			
 			verticesp += mMesh->mFaceVertexOffset;
 			normalsp += mMesh->mFaceVertexOffset;
 			
@@ -803,7 +817,7 @@ void LLViewerJointMesh::updateGeometryOriginal(LLFace *mFace, LLPolyMesh *mMesh)
 		}
 	}
 
-	buffer->setBuffer(0);
+	buffer->flush();
 }
 
 const U32 UPDATE_GEOMETRY_CALL_MASK			= 0x1FFF; // 8K samples before overflow
diff --git a/indra/newview/llviewerjointmesh_sse.cpp b/indra/newview/llviewerjointmesh_sse.cpp
index 400b49d04602a58cba668a69362d5dc3cb9c1da1..00ed47e091b129da929e5bf82fb62ee1fc9e2092 100644
--- a/indra/newview/llviewerjointmesh_sse.cpp
+++ b/indra/newview/llviewerjointmesh_sse.cpp
@@ -101,7 +101,7 @@ void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh)
 		((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]);
 	}
 
-	buffer->setBuffer(0);
+	buffer->flush();
 }
 
 #else
diff --git a/indra/newview/llviewerjointmesh_vec.cpp b/indra/newview/llviewerjointmesh_vec.cpp
index 6600d01d171072cc52b5b8b626cae8f2d35f2036..a8713b6f0580bb506346868504f9371303ddc256 100644
--- a/indra/newview/llviewerjointmesh_vec.cpp
+++ b/indra/newview/llviewerjointmesh_vec.cpp
@@ -92,6 +92,6 @@ void LLViewerJointMesh::updateGeometryVectorized(LLFace *face, LLPolyMesh *mesh)
 		((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]);
 	}
 
-	buffer->setBuffer(0);
+	buffer->flush();
 #endif
 }
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 53e951e483f0fa05a90bc7cce55b67ad1d947ac7..a77725c1ca1e949b8b74ec9b66bcd29bc3d9ac72 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -1,4 +1,4 @@
-/** 
+/**
  * @file llviewerobject.h
  * @brief Description of LLViewerObject class, which is the base class for most objects in the viewer.
  *
@@ -811,7 +811,7 @@ class LLAlphaObject : public LLViewerObject
 
 	virtual F32 getPartSize(S32 idx);
 	virtual void getGeometry(S32 idx,
-								LLStrider<LLVector3>& verticesp,
+								LLStrider<LLVector4a>& verticesp,
 								LLStrider<LLVector3>& normalsp, 
 								LLStrider<LLVector2>& texcoordsp,
 								LLStrider<LLColor4U>& colorsp, 
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index e619b89f9b98216ff956fd57b2b03222a83cd545..a0cf2fc803634023f0a9f33dc989a8fa9195b210 100644
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -884,14 +884,14 @@ S32 LLViewerParcelOverlay::renderPropertyLines	()
 	// Always fudge a little vertically.
 	pull_toward_camera.mV[VZ] += 0.01f;
 
-	glMatrixMode( GL_MODELVIEW );
-	glPushMatrix();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.pushMatrix();
 
 	// Move to appropriate region coords
 	LLVector3 origin = mRegion->getOriginAgent();
-	glTranslatef( origin.mV[VX], origin.mV[VY], origin.mV[VZ] );
+	gGL.translatef( origin.mV[VX], origin.mV[VY], origin.mV[VZ] );
 
-	glTranslatef(pull_toward_camera.mV[VX], pull_toward_camera.mV[VY],
+	gGL.translatef(pull_toward_camera.mV[VX], pull_toward_camera.mV[VY],
 		pull_toward_camera.mV[VZ]);
 
 	// Include +1 because vertices are fenceposts.
@@ -990,7 +990,7 @@ S32 LLViewerParcelOverlay::renderPropertyLines	()
 		
 	}
 
-	glPopMatrix();
+	gGL.popMatrix();
 
 	return drawn;
 }
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 36106752a260338bcfc3c651cd161465152f7279..e50625af600c8b41f9c65552a6f0ef96df5151dc 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -32,6 +32,7 @@
 
 #include "llfile.h"
 #include "llviewerwindow.h"
+#include "llwindow.h"
 #include "llviewercontrol.h"
 #include "pipeline.h"
 #include "llworld.h"
@@ -58,6 +59,7 @@ using std::make_pair;
 using std::string;
 
 BOOL				LLViewerShaderMgr::sInitialized = FALSE;
+bool				LLViewerShaderMgr::sSkipReload = false;
 
 LLVector4			gShinyOrigin;
 
@@ -65,15 +67,23 @@ LLVector4			gShinyOrigin;
 LLGLSLShader	gOcclusionProgram;
 LLGLSLShader	gCustomAlphaProgram;
 LLGLSLShader	gGlowCombineProgram;
+LLGLSLShader	gSplatTextureRectProgram;
+LLGLSLShader	gGlowCombineFXAAProgram;
 LLGLSLShader	gTwoTextureAddProgram;
+LLGLSLShader	gOneTextureNoColorProgram;
+LLGLSLShader	gDebugProgram;
+LLGLSLShader	gAlphaMaskProgram;
 
 //object shaders
 LLGLSLShader		gObjectSimpleProgram;
+LLGLSLShader		gObjectPreviewProgram;
 LLGLSLShader		gObjectSimpleWaterProgram;
 LLGLSLShader		gObjectSimpleAlphaMaskProgram;
 LLGLSLShader		gObjectSimpleWaterAlphaMaskProgram;
 LLGLSLShader		gObjectFullbrightProgram;
 LLGLSLShader		gObjectFullbrightWaterProgram;
+LLGLSLShader		gObjectEmissiveProgram;
+LLGLSLShader		gObjectEmissiveWaterProgram;
 LLGLSLShader		gObjectFullbrightAlphaMaskProgram;
 LLGLSLShader		gObjectFullbrightWaterAlphaMaskProgram;
 LLGLSLShader		gObjectFullbrightShinyProgram;
@@ -81,13 +91,23 @@ LLGLSLShader		gObjectFullbrightShinyWaterProgram;
 LLGLSLShader		gObjectShinyProgram;
 LLGLSLShader		gObjectShinyWaterProgram;
 LLGLSLShader		gObjectBumpProgram;
+LLGLSLShader		gTreeProgram;
+LLGLSLShader		gTreeWaterProgram;
+LLGLSLShader		gObjectFullbrightNoColorProgram;
+LLGLSLShader		gObjectFullbrightNoColorWaterProgram;
 
 LLGLSLShader		gObjectSimpleNonIndexedProgram;
+LLGLSLShader		gObjectSimpleNonIndexedTexGenProgram;
+LLGLSLShader		gObjectSimpleNonIndexedTexGenWaterProgram;
 LLGLSLShader		gObjectSimpleNonIndexedWaterProgram;
 LLGLSLShader		gObjectAlphaMaskNonIndexedProgram;
 LLGLSLShader		gObjectAlphaMaskNonIndexedWaterProgram;
+LLGLSLShader		gObjectAlphaMaskNoColorProgram;
+LLGLSLShader		gObjectAlphaMaskNoColorWaterProgram;
 LLGLSLShader		gObjectFullbrightNonIndexedProgram;
 LLGLSLShader		gObjectFullbrightNonIndexedWaterProgram;
+LLGLSLShader		gObjectEmissiveNonIndexedProgram;
+LLGLSLShader		gObjectEmissiveNonIndexedWaterProgram;
 LLGLSLShader		gObjectFullbrightShinyNonIndexedProgram;
 LLGLSLShader		gObjectFullbrightShinyNonIndexedWaterProgram;
 LLGLSLShader		gObjectShinyNonIndexedProgram;
@@ -96,11 +116,13 @@ LLGLSLShader		gObjectShinyNonIndexedWaterProgram;
 //object hardware skinning shaders
 LLGLSLShader		gSkinnedObjectSimpleProgram;
 LLGLSLShader		gSkinnedObjectFullbrightProgram;
+LLGLSLShader		gSkinnedObjectEmissiveProgram;
 LLGLSLShader		gSkinnedObjectFullbrightShinyProgram;
 LLGLSLShader		gSkinnedObjectShinySimpleProgram;
 
 LLGLSLShader		gSkinnedObjectSimpleWaterProgram;
 LLGLSLShader		gSkinnedObjectFullbrightWaterProgram;
+LLGLSLShader		gSkinnedObjectEmissiveWaterProgram;
 LLGLSLShader		gSkinnedObjectFullbrightShinyWaterProgram;
 LLGLSLShader		gSkinnedObjectShinySimpleWaterProgram;
 
@@ -124,6 +146,7 @@ LLGLSLShader		gImpostorProgram;
 LLGLSLShader			gWLSkyProgram;
 LLGLSLShader			gWLCloudProgram;
 
+
 // Effects Shaders
 LLGLSLShader			gGlowProgram;
 LLGLSLShader			gGlowExtractProgram;
@@ -132,18 +155,19 @@ LLGLSLShader			gPostNightVisionProgram;
 
 // Deferred rendering shaders
 LLGLSLShader			gDeferredImpostorProgram;
-LLGLSLShader			gDeferredEdgeProgram;
 LLGLSLShader			gDeferredWaterProgram;
 LLGLSLShader			gDeferredDiffuseProgram;
 LLGLSLShader			gDeferredDiffuseAlphaMaskProgram;
 LLGLSLShader			gDeferredNonIndexedDiffuseProgram;
 LLGLSLShader			gDeferredNonIndexedDiffuseAlphaMaskProgram;
+LLGLSLShader			gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;
 LLGLSLShader			gDeferredSkinnedDiffuseProgram;
 LLGLSLShader			gDeferredSkinnedBumpProgram;
 LLGLSLShader			gDeferredSkinnedAlphaProgram;
 LLGLSLShader			gDeferredBumpProgram;
 LLGLSLShader			gDeferredTerrainProgram;
 LLGLSLShader			gDeferredTreeProgram;
+LLGLSLShader			gDeferredTreeShadowProgram;
 LLGLSLShader			gDeferredAvatarProgram;
 LLGLSLShader			gDeferredAvatarAlphaProgram;
 LLGLSLShader			gDeferredLightProgram;
@@ -160,25 +184,21 @@ LLGLSLShader			gDeferredAttachmentShadowProgram;
 LLGLSLShader			gDeferredAlphaProgram;
 LLGLSLShader			gDeferredAvatarEyesProgram;
 LLGLSLShader			gDeferredFullbrightProgram;
-LLGLSLShader			gDeferredGIProgram;
-LLGLSLShader			gDeferredGIFinalProgram;
-LLGLSLShader			gDeferredPostGIProgram;
+LLGLSLShader			gDeferredEmissiveProgram;
 LLGLSLShader			gDeferredPostProgram;
+LLGLSLShader			gFXAAProgram;
 LLGLSLShader			gDeferredPostNoDoFProgram;
 LLGLSLShader			gDeferredWLSkyProgram;
 LLGLSLShader			gDeferredWLCloudProgram;
 LLGLSLShader			gDeferredStarProgram;
-LLGLSLShader			gLuminanceGatherProgram;
-
-
-//current avatar shader parameter pointer
-GLint				gAvatarMatrixParam;
+LLGLSLShader			gNormalMapGenProgram;
 
 LLViewerShaderMgr::LLViewerShaderMgr() :
 	mVertexShaderLevel(SHADER_COUNT, 0),
 	mMaxAvatarShaderLevel(0)
 {	
 	/// Make sure WL Sky is the first program
+	//ONLY shaders that need WL Param management should be added here
 	mShaderList.push_back(&gWLSkyProgram);
 	mShaderList.push_back(&gWLCloudProgram);
 	mShaderList.push_back(&gAvatarProgram);
@@ -187,33 +207,42 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
 	mShaderList.push_back(&gWaterProgram);
 	mShaderList.push_back(&gAvatarEyeballProgram); 
 	mShaderList.push_back(&gObjectSimpleProgram);
+	mShaderList.push_back(&gObjectPreviewProgram);
 	mShaderList.push_back(&gImpostorProgram);
+	mShaderList.push_back(&gObjectFullbrightNoColorProgram);
+	mShaderList.push_back(&gObjectFullbrightNoColorWaterProgram);
 	mShaderList.push_back(&gObjectSimpleAlphaMaskProgram);
 	mShaderList.push_back(&gObjectBumpProgram);
-	mShaderList.push_back(&gUIProgram);
-	mShaderList.push_back(&gCustomAlphaProgram);
-	mShaderList.push_back(&gGlowCombineProgram);
-	mShaderList.push_back(&gTwoTextureAddProgram);
-	mShaderList.push_back(&gSolidColorProgram);
-	mShaderList.push_back(&gOcclusionProgram);
+	mShaderList.push_back(&gObjectEmissiveProgram);
+	mShaderList.push_back(&gObjectEmissiveWaterProgram);
 	mShaderList.push_back(&gObjectFullbrightProgram);
 	mShaderList.push_back(&gObjectFullbrightAlphaMaskProgram);
 	mShaderList.push_back(&gObjectFullbrightShinyProgram);
 	mShaderList.push_back(&gObjectFullbrightShinyWaterProgram);
 	mShaderList.push_back(&gObjectSimpleNonIndexedProgram);
+	mShaderList.push_back(&gObjectSimpleNonIndexedTexGenProgram);
+	mShaderList.push_back(&gObjectSimpleNonIndexedTexGenWaterProgram);
 	mShaderList.push_back(&gObjectSimpleNonIndexedWaterProgram);
 	mShaderList.push_back(&gObjectAlphaMaskNonIndexedProgram);
 	mShaderList.push_back(&gObjectAlphaMaskNonIndexedWaterProgram);
+	mShaderList.push_back(&gObjectAlphaMaskNoColorProgram);
+	mShaderList.push_back(&gObjectAlphaMaskNoColorWaterProgram);
+	mShaderList.push_back(&gTreeProgram);
+	mShaderList.push_back(&gTreeWaterProgram);
 	mShaderList.push_back(&gObjectFullbrightNonIndexedProgram);
 	mShaderList.push_back(&gObjectFullbrightNonIndexedWaterProgram);
+	mShaderList.push_back(&gObjectEmissiveNonIndexedProgram);
+	mShaderList.push_back(&gObjectEmissiveNonIndexedWaterProgram);
 	mShaderList.push_back(&gObjectFullbrightShinyNonIndexedProgram);
 	mShaderList.push_back(&gObjectFullbrightShinyNonIndexedWaterProgram);
 	mShaderList.push_back(&gSkinnedObjectSimpleProgram);
 	mShaderList.push_back(&gSkinnedObjectFullbrightProgram);
+	mShaderList.push_back(&gSkinnedObjectEmissiveProgram);
 	mShaderList.push_back(&gSkinnedObjectFullbrightShinyProgram);
 	mShaderList.push_back(&gSkinnedObjectShinySimpleProgram);
 	mShaderList.push_back(&gSkinnedObjectSimpleWaterProgram);
 	mShaderList.push_back(&gSkinnedObjectFullbrightWaterProgram);
+	mShaderList.push_back(&gSkinnedObjectEmissiveWaterProgram);
 	mShaderList.push_back(&gSkinnedObjectFullbrightShinyWaterProgram);
 	mShaderList.push_back(&gSkinnedObjectShinySimpleWaterProgram);
 	mShaderList.push_back(&gTerrainProgram);
@@ -227,24 +256,16 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
 	mShaderList.push_back(&gObjectShinyNonIndexedWaterProgram);
 	mShaderList.push_back(&gUnderWaterProgram);
 	mShaderList.push_back(&gDeferredSunProgram);
-	mShaderList.push_back(&gDeferredBlurLightProgram);
 	mShaderList.push_back(&gDeferredSoftenProgram);
-	mShaderList.push_back(&gDeferredLightProgram);
-	mShaderList.push_back(&gDeferredMultiLightProgram);
 	mShaderList.push_back(&gDeferredAlphaProgram);
 	mShaderList.push_back(&gDeferredSkinnedAlphaProgram);
 	mShaderList.push_back(&gDeferredFullbrightProgram);
+	mShaderList.push_back(&gDeferredEmissiveProgram);
 	mShaderList.push_back(&gDeferredAvatarEyesProgram);
-	mShaderList.push_back(&gDeferredPostGIProgram);
-	mShaderList.push_back(&gDeferredEdgeProgram);
-	mShaderList.push_back(&gDeferredPostProgram);
-	mShaderList.push_back(&gDeferredGIProgram);
-	mShaderList.push_back(&gDeferredGIFinalProgram);
 	mShaderList.push_back(&gDeferredWaterProgram);
 	mShaderList.push_back(&gDeferredAvatarAlphaProgram);
 	mShaderList.push_back(&gDeferredWLSkyProgram);
 	mShaderList.push_back(&gDeferredWLCloudProgram);
-	mShaderList.push_back(&gDeferredStarProgram);
 }
 
 LLViewerShaderMgr::~LLViewerShaderMgr()
@@ -268,80 +289,13 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void)
 {
 	if (mReservedAttribs.empty())
 	{
-		mReservedAttribs.push_back("materialColor");
-		mReservedAttribs.push_back("specularColor");
-		mReservedAttribs.push_back("binormal");
-		mReservedAttribs.push_back("object_weight");
-
-		mAvatarAttribs.reserve(5);
-		mAvatarAttribs.push_back("weight");
-		mAvatarAttribs.push_back("clothing");
-		mAvatarAttribs.push_back("gWindDir");
-		mAvatarAttribs.push_back("gSinWaveParams");
-		mAvatarAttribs.push_back("gGravity");
+		LLShaderMgr::initAttribsAndUniforms();
 
 		mAvatarUniforms.push_back("matrixPalette");
+		mAvatarUniforms.push_back("gWindDir");
+		mAvatarUniforms.push_back("gSinWaveParams");
+		mAvatarUniforms.push_back("gGravity");
 
-		mReservedUniforms.reserve(24);
-		mReservedUniforms.push_back("diffuseMap");
-		mReservedUniforms.push_back("specularMap");
-		mReservedUniforms.push_back("bumpMap");
-		mReservedUniforms.push_back("environmentMap");
-		mReservedUniforms.push_back("cloude_noise_texture");
-		mReservedUniforms.push_back("fullbright");
-		mReservedUniforms.push_back("lightnorm");
-		mReservedUniforms.push_back("sunlight_color");
-		mReservedUniforms.push_back("ambient");
-		mReservedUniforms.push_back("blue_horizon");
-		mReservedUniforms.push_back("blue_density");
-		mReservedUniforms.push_back("haze_horizon");
-		mReservedUniforms.push_back("haze_density");
-		mReservedUniforms.push_back("cloud_shadow");
-		mReservedUniforms.push_back("density_multiplier");
-		mReservedUniforms.push_back("distance_multiplier");
-		mReservedUniforms.push_back("max_y");
-		mReservedUniforms.push_back("glow");
-		mReservedUniforms.push_back("cloud_color");
-		mReservedUniforms.push_back("cloud_pos_density1");
-		mReservedUniforms.push_back("cloud_pos_density2");
-		mReservedUniforms.push_back("cloud_scale");
-		mReservedUniforms.push_back("gamma");
-		mReservedUniforms.push_back("scene_light_strength");
-
-		mReservedUniforms.push_back("depthMap");
-		mReservedUniforms.push_back("shadowMap0");
-		mReservedUniforms.push_back("shadowMap1");
-		mReservedUniforms.push_back("shadowMap2");
-		mReservedUniforms.push_back("shadowMap3");
-		mReservedUniforms.push_back("shadowMap4");
-		mReservedUniforms.push_back("shadowMap5");
-
-		mReservedUniforms.push_back("normalMap");
-		mReservedUniforms.push_back("positionMap");
-		mReservedUniforms.push_back("diffuseRect");
-		mReservedUniforms.push_back("specularRect");
-		mReservedUniforms.push_back("noiseMap");
-		mReservedUniforms.push_back("lightFunc");
-		mReservedUniforms.push_back("lightMap");
-		mReservedUniforms.push_back("luminanceMap");
-		mReservedUniforms.push_back("giLightMap");
-		mReservedUniforms.push_back("giMip");
-		mReservedUniforms.push_back("edgeMap");
-		mReservedUniforms.push_back("bloomMap");
-		mReservedUniforms.push_back("sunLightMap");
-		mReservedUniforms.push_back("localLightMap");
-		mReservedUniforms.push_back("projectionMap");
-		mReservedUniforms.push_back("diffuseGIMap");
-		mReservedUniforms.push_back("specularGIMap");
-		mReservedUniforms.push_back("normalGIMap");
-		mReservedUniforms.push_back("minpGIMap");
-		mReservedUniforms.push_back("maxpGIMap");
-		mReservedUniforms.push_back("depthGIMap");
-		mReservedUniforms.push_back("lastDiffuseGIMap");
-		mReservedUniforms.push_back("lastNormalGIMap");
-		mReservedUniforms.push_back("lastMinpGIMap");
-		mReservedUniforms.push_back("lastMaxpGIMap");
-					
 		mWLUniforms.push_back("camPosLocal");
 
 		mTerrainUniforms.reserve(5);
@@ -397,17 +351,33 @@ void LLViewerShaderMgr::setShaders()
 	//setShaders might be called redundantly by gSavedSettings, so return on reentrance
 	static bool reentrance = false;
 	
-	if (!gPipeline.mInitialized || !sInitialized || reentrance)
+	if (!gPipeline.mInitialized || !sInitialized || reentrance || sSkipReload)
 	{
 		return;
 	}
 
-	//setup preprocessor definitions
-	LLShaderMgr::instance()->mDefinitions["samples"] = llformat("%d", gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples")));
-	LLShaderMgr::instance()->mDefinitions["NUM_TEX_UNITS"] = llformat("%d", gGLManager.mNumTextureImageUnits);
+	LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits, (S32) gSavedSettings.getU32("RenderMaxTextureIndex")), 1);
+
+	//NEVER use more than 16 texture channels (work around for prevalent driver bug)
+	LLGLSLShader::sIndexedTextureChannels = llmin(LLGLSLShader::sIndexedTextureChannels, 16);
 
 	reentrance = true;
 
+	if (LLRender::sGLCoreProfile || gGLManager.mGLVersion >= 2.f)
+	{  //ALWAYS use shaders where available
+		if (!gSavedSettings.getBOOL("VertexShaderEnable"))
+		{ //vertex shaders MUST be enabled to use core profile
+			gSavedSettings.setBOOL("VertexShaderEnable", TRUE);
+		}
+	}
+	else if (gGLManager.mGLVersion < 2.f)
+	{ //NEVER use shaders on a pre 2.0 context
+		gSavedSettings.setBOOL("VertexShaderEnable", FALSE);
+	}
+	
+	//setup preprocessor definitions
+	LLShaderMgr::instance()->mDefinitions["NUM_TEX_UNITS"] = llformat("%d", gGLManager.mNumTextureImageUnits);
+	
 	// Make sure the compiled shader map is cleared before we recompile shaders.
 	mShaderObjects.clear();
 	
@@ -446,6 +416,7 @@ void LLViewerShaderMgr::setShaders()
 	mMaxAvatarShaderLevel = 0;
 
 	LLGLSLShader::sNoFixedFunction = false;
+	LLVertexBuffer::unbind();
 	if (LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") 
 		&& gSavedSettings.getBOOL("VertexShaderEnable"))
 	{
@@ -466,15 +437,8 @@ void LLViewerShaderMgr::setShaders()
 			gSavedSettings.getBOOL("WindLightUseAtmosShaders"))
 		{
 			if (gSavedSettings.getS32("RenderShadowDetail") > 0)
-			{
-				if (gSavedSettings.getBOOL("RenderDeferredGI"))
-				{ //shadows + gi
-					deferred_class = 3;
-				}
-				else
-				{ //shadows
-					deferred_class = 2;
-				}
+			{ //shadows
+				deferred_class = 2;
 			}
 			else
 			{ //no shadows
@@ -497,11 +461,7 @@ void LLViewerShaderMgr::setShaders()
 			wl_class = 1;
 		}
 
-		if(!gSavedSettings.getBOOL("EnableRippleWater"))
-		{
-			water_class = 0;
-		}
-
+		
 		// Trigger a full rebuild of the fallback skybox / cubemap if we've toggled windlight shaders
 		if (mVertexShaderLevel[SHADER_WINDLIGHT] != wl_class && gSky.mVOSkyp.notNull())
 		{
@@ -624,6 +584,7 @@ void LLViewerShaderMgr::setShaders()
 	if (gViewerWindow)
 	{
 		gViewerWindow->setCursor(UI_CURSOR_ARROW);
+		gViewerWindow->getWindow()->restore();
 	}
 	gPipeline.createGLBuffers();
 
@@ -633,13 +594,21 @@ void LLViewerShaderMgr::setShaders()
 void LLViewerShaderMgr::unloadShaders()
 {
 	gOcclusionProgram.unload();
+	gDebugProgram.unload();
+	gAlphaMaskProgram.unload();
 	gUIProgram.unload();
 	gCustomAlphaProgram.unload();
 	gGlowCombineProgram.unload();
+	gSplatTextureRectProgram.unload();
+	gGlowCombineFXAAProgram.unload();
 	gTwoTextureAddProgram.unload();
+	gOneTextureNoColorProgram.unload();
 	gSolidColorProgram.unload();
 
+	gObjectFullbrightNoColorProgram.unload();
+	gObjectFullbrightNoColorWaterProgram.unload();
 	gObjectSimpleProgram.unload();
+	gObjectPreviewProgram.unload();
 	gImpostorProgram.unload();
 	gObjectSimpleAlphaMaskProgram.unload();
 	gObjectBumpProgram.unload();
@@ -647,6 +616,8 @@ void LLViewerShaderMgr::unloadShaders()
 	gObjectSimpleWaterAlphaMaskProgram.unload();
 	gObjectFullbrightProgram.unload();
 	gObjectFullbrightWaterProgram.unload();
+	gObjectEmissiveProgram.unload();
+	gObjectEmissiveWaterProgram.unload();
 	gObjectFullbrightAlphaMaskProgram.unload();
 	gObjectFullbrightWaterAlphaMaskProgram.unload();
 
@@ -656,11 +627,19 @@ void LLViewerShaderMgr::unloadShaders()
 	gObjectShinyWaterProgram.unload();
 
 	gObjectSimpleNonIndexedProgram.unload();
+	gObjectSimpleNonIndexedTexGenProgram.unload();
+	gObjectSimpleNonIndexedTexGenWaterProgram.unload();
 	gObjectSimpleNonIndexedWaterProgram.unload();
 	gObjectAlphaMaskNonIndexedProgram.unload();
 	gObjectAlphaMaskNonIndexedWaterProgram.unload();
+	gObjectAlphaMaskNoColorProgram.unload();
+	gObjectAlphaMaskNoColorWaterProgram.unload();
 	gObjectFullbrightNonIndexedProgram.unload();
 	gObjectFullbrightNonIndexedWaterProgram.unload();
+	gObjectEmissiveNonIndexedProgram.unload();
+	gObjectEmissiveNonIndexedWaterProgram.unload();
+	gTreeProgram.unload();
+	gTreeWaterProgram.unload();
 
 	gObjectShinyNonIndexedProgram.unload();
 	gObjectFullbrightShinyNonIndexedProgram.unload();
@@ -669,11 +648,13 @@ void LLViewerShaderMgr::unloadShaders()
 
 	gSkinnedObjectSimpleProgram.unload();
 	gSkinnedObjectFullbrightProgram.unload();
+	gSkinnedObjectEmissiveProgram.unload();
 	gSkinnedObjectFullbrightShinyProgram.unload();
 	gSkinnedObjectShinySimpleProgram.unload();
 	
 	gSkinnedObjectSimpleWaterProgram.unload();
 	gSkinnedObjectFullbrightWaterProgram.unload();
+	gSkinnedObjectEmissiveWaterProgram.unload();
 	gSkinnedObjectFullbrightShinyWaterProgram.unload();
 	gSkinnedObjectShinySimpleWaterProgram.unload();
 	
@@ -699,6 +680,7 @@ void LLViewerShaderMgr::unloadShaders()
 	gDeferredDiffuseProgram.unload();
 	gDeferredDiffuseAlphaMaskProgram.unload();
 	gDeferredNonIndexedDiffuseAlphaMaskProgram.unload();
+	gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload();
 	gDeferredNonIndexedDiffuseProgram.unload();
 	gDeferredSkinnedDiffuseProgram.unload();
 	gDeferredSkinnedBumpProgram.unload();
@@ -750,8 +732,8 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
 	// (in order of shader function call depth for reference purposes, deepest level first)
 
 	vector< pair<string, S32> > shaders;
-	shaders.reserve(10);
 	shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl",		mVertexShaderLevel[SHADER_WINDLIGHT] ) );
+	shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterV.glsl",		mVertexShaderLevel[SHADER_WINDLIGHT] ) );
 	shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl",	mVertexShaderLevel[SHADER_WINDLIGHT] ) );
 	shaders.push_back( make_pair( "lighting/lightFuncV.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) );
 	shaders.push_back( make_pair( "lighting/sumLightsV.glsl",				sum_lights_class ) );
@@ -762,6 +744,8 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
 	shaders.push_back( make_pair( "windlight/atmosphericsV.glsl",			mVertexShaderLevel[SHADER_WINDLIGHT] ) );
 	shaders.push_back( make_pair( "avatar/avatarSkinV.glsl",				1 ) );
 	shaders.push_back( make_pair( "avatar/objectSkinV.glsl",				1 ) );
+	shaders.push_back( make_pair( "objects/indexedTextureV.glsl",			1 ) );
+	shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl",		1 ) );
 
 	// We no longer have to bind the shaders to global glhandles, they are automatically added to a map now.
 	for (U32 i = 0; i < shaders.size(); i++)
@@ -777,8 +761,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
 	// (in order of shader function call depth for reference purposes, deepest level first)
 
 	shaders.clear();
-	shaders.reserve(13);
-	S32 ch = gGLManager.mNumTextureImageUnits-1;
+	S32 ch = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 
 	if (gGLManager.mGLVersion < 3.1f)
 	{ //force to 1 texture index channel for old drivers
@@ -787,6 +770,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
 
 	std::vector<S32> index_channels;
 	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl",		mVertexShaderLevel[SHADER_WINDLIGHT] ) );
+	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterF.glsl",		mVertexShaderLevel[SHADER_WINDLIGHT] ) );
 	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/gammaF.glsl",					mVertexShaderLevel[SHADER_WINDLIGHT]) );
 	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/atmosphericsF.glsl",			mVertexShaderLevel[SHADER_WINDLIGHT] ) );
 	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/transportF.glsl",				mVertexShaderLevel[SHADER_WINDLIGHT] ) );	
@@ -950,9 +934,6 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
 {
 	BOOL success = TRUE;
 
-	U32 samples = gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples"));
-	bool multisample = samples > 1 && LLPipeline::sRenderDeferred && gGLManager.mHasTextureMultisample;
-
 	if (mVertexShaderLevel[SHADER_EFFECT] == 0)
 	{
 		gGlowProgram.unload();
@@ -978,21 +959,10 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
 	
 	if (success)
 	{
-		std::string fragment;
-
-		if (multisample)
-		{
-			fragment = "effects/glowExtractMSF.glsl";
-		}
-		else
-		{
-			fragment = "effects/glowExtractF.glsl";
-		}
-
 		gGlowExtractProgram.mName = "Glow Extract Shader (Post)";
 		gGlowExtractProgram.mShaderFiles.clear();
 		gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB));
-		gGlowExtractProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));
+		gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB));
 		gGlowExtractProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT];
 		success = gGlowExtractProgram.createShader(NULL, &mGlowExtractUniforms);
 		if (!success)
@@ -1001,51 +971,6 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
 		}
 	}
 	
-#if 0
-	// disabling loading of postprocess shaders until we fix
-	// ATI sampler2DRect compatibility.
-	
-	//load Color Filter Shader
-	if (success)
-	{
-		vector<string> shaderUniforms;
-		shaderUniforms.reserve(7);
-		shaderUniforms.push_back("RenderTexture");
-		shaderUniforms.push_back("gamma");
-		shaderUniforms.push_back("brightness");
-		shaderUniforms.push_back("contrast");
-		shaderUniforms.push_back("contrastBase");
-		shaderUniforms.push_back("saturation");
-		shaderUniforms.push_back("lumWeights");
-
-		gPostColorFilterProgram.mName = "Color Filter Shader (Post)";
-		gPostColorFilterProgram.mShaderFiles.clear();
-		gPostColorFilterProgram.mShaderFiles.push_back(make_pair("effects/colorFilterF.glsl", GL_FRAGMENT_SHADER_ARB));
-		gPostColorFilterProgram.mShaderFiles.push_back(make_pair("effects/drawQuadV.glsl", GL_VERTEX_SHADER_ARB));
-		gPostColorFilterProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT];
-		success = gPostColorFilterProgram.createShader(NULL, &shaderUniforms);
-	}
-
-	//load Night Vision Shader
-	if (success)
-	{
-		vector<string> shaderUniforms;
-		shaderUniforms.reserve(5);
-		shaderUniforms.push_back("RenderTexture");
-		shaderUniforms.push_back("NoiseTexture");
-		shaderUniforms.push_back("brightMult");
-		shaderUniforms.push_back("noiseStrength");
-		shaderUniforms.push_back("lumWeights");
-
-		gPostNightVisionProgram.mName = "Night Vision Shader (Post)";
-		gPostNightVisionProgram.mShaderFiles.clear();
-		gPostNightVisionProgram.mShaderFiles.push_back(make_pair("effects/nightVisionF.glsl", GL_FRAGMENT_SHADER_ARB));
-		gPostNightVisionProgram.mShaderFiles.push_back(make_pair("effects/drawQuadV.glsl", GL_VERTEX_SHADER_ARB));
-		gPostNightVisionProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT];
-		success = gPostNightVisionProgram.createShader(NULL, &shaderUniforms);
-	}
-	#endif
-
 	return success;
 
 }
@@ -1055,9 +980,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 	if (mVertexShaderLevel[SHADER_DEFERRED] == 0)
 	{
 		gDeferredTreeProgram.unload();
+		gDeferredTreeShadowProgram.unload();
 		gDeferredDiffuseProgram.unload();
 		gDeferredDiffuseAlphaMaskProgram.unload();
 		gDeferredNonIndexedDiffuseAlphaMaskProgram.unload();
+		gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload();
 		gDeferredNonIndexedDiffuseProgram.unload();
 		gDeferredSkinnedDiffuseProgram.unload();
 		gDeferredSkinnedBumpProgram.unload();
@@ -1080,34 +1007,27 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredAvatarAlphaProgram.unload();
 		gDeferredAlphaProgram.unload();
 		gDeferredFullbrightProgram.unload();
+		gDeferredEmissiveProgram.unload();
 		gDeferredAvatarEyesProgram.unload();
-		gDeferredPostGIProgram.unload();		
-		gDeferredEdgeProgram.unload();		
 		gDeferredPostProgram.unload();		
-		gLuminanceGatherProgram.unload();
-		gDeferredGIProgram.unload();
-		gDeferredGIFinalProgram.unload();
+		gFXAAProgram.unload();
 		gDeferredWaterProgram.unload();
 		gDeferredWLSkyProgram.unload();
 		gDeferredWLCloudProgram.unload();
 		gDeferredStarProgram.unload();
+		gNormalMapGenProgram.unload();
 		return TRUE;
 	}
 
-	mVertexShaderLevel[SHADER_AVATAR] = 1;
-
 	BOOL success = TRUE;
 
-	U32 samples = gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples"));
-	bool multisample = samples > 1 && gGLManager.mHasTextureMultisample;
-
 	if (success)
 	{
 		gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader";
 		gDeferredDiffuseProgram.mShaderFiles.clear();
 		gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));
 		gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));
-		gDeferredDiffuseProgram.mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits;
+		gDeferredDiffuseProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
 		gDeferredDiffuseProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
 		success = gDeferredDiffuseProgram.createShader(NULL, NULL);
 	}
@@ -1118,7 +1038,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredDiffuseAlphaMaskProgram.mShaderFiles.clear();
 		gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));
 		gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));
-		gDeferredDiffuseAlphaMaskProgram.mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits;
+		gDeferredDiffuseAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
 		gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
 		success = gDeferredDiffuseAlphaMaskProgram.createShader(NULL, NULL);
 	}
@@ -1132,6 +1052,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
 		success = gDeferredNonIndexedDiffuseAlphaMaskProgram.createShader(NULL, NULL);
 	}
+	
+	if (success)
+	{
+		gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader";
+		gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.clear();
+		gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseNoColorV.glsl", GL_VERTEX_SHADER_ARB));
+		gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskNoColorF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+		success = gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.createShader(NULL, NULL);
+	}
 
 	if (success)
 	{
@@ -1203,6 +1133,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		success = gDeferredTreeProgram.createShader(NULL, NULL);
 	}
 
+	if (success)
+	{
+		gDeferredTreeShadowProgram.mName = "Deferred Tree Shadow Shader";
+		gDeferredTreeShadowProgram.mShaderFiles.clear();
+		gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowV.glsl", GL_VERTEX_SHADER_ARB));
+		gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gDeferredTreeShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+		success = gDeferredTreeShadowProgram.createShader(NULL, NULL);
+	}
+
 	if (success)
 	{
 		gDeferredImpostorProgram.mName = "Deferred Impostor Shader";
@@ -1214,84 +1154,41 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 	}
 
 	if (success)
-	{
-		std::string fragment;
-
-		if (multisample)
-		{
-			fragment = "deferred/pointLightMSF.glsl";
-		}
-		else
-		{
-			fragment = "deferred/pointLightF.glsl";
-		}
-
+	{		
 		gDeferredLightProgram.mName = "Deferred Light Shader";
 		gDeferredLightProgram.mShaderFiles.clear();
 		gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));
-		gDeferredLightProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));
+		gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER_ARB));
 		gDeferredLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
 		success = gDeferredLightProgram.createShader(NULL, NULL);
 	}
 
 	if (success)
 	{
-		std::string fragment;
-		if (multisample)
-		{
-			fragment = "deferred/multiPointLightMSF.glsl";
-		}
-		else
-		{
-			fragment = "deferred/multiPointLightF.glsl";
-		}
-
 		gDeferredMultiLightProgram.mName = "Deferred MultiLight Shader";
 		gDeferredMultiLightProgram.mShaderFiles.clear();
 		gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));
-		gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));
+		gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB));
 		gDeferredMultiLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
 		success = gDeferredMultiLightProgram.createShader(NULL, NULL);
 	}
 
 	if (success)
 	{
-		std::string fragment;
-
-		if (multisample)
-		{
-			fragment = "deferred/spotLightMSF.glsl";
-		}
-		else
-		{
-			fragment = "deferred/multiSpotLightF.glsl";
-		}
-
 		gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader";
 		gDeferredSpotLightProgram.mShaderFiles.clear();
 		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));
-		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));
+		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB));
 		gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
 		success = gDeferredSpotLightProgram.createShader(NULL, NULL);
 	}
 
 	if (success)
 	{
-		std::string fragment;
-
-		if (multisample)
-		{
-			fragment = "deferred/multiSpotLightMSF.glsl";
-		}
-		else
-		{
-			fragment = "deferred/multiSpotLightF.glsl";
-		}
-
 		gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader";
 		gDeferredMultiSpotLightProgram.mShaderFiles.clear();
 		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));
-		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));
+		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB));
 		gDeferredMultiSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
 		success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL);
 	}
@@ -1302,25 +1199,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 
 		if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
 		{
-			if (multisample)
-			{
-				fragment = "deferred/sunLightSSAOMSF.glsl";
-			}
-			else
-			{
-				fragment = "deferred/sunLightSSAOF.glsl";
-			}
+			fragment = "deferred/sunLightSSAOF.glsl";
 		}
 		else
 		{
-			if (multisample)
-			{
-				fragment = "deferred/sunLightMSF.glsl";
-			}
-			else
-			{
-				fragment = "deferred/sunLightF.glsl";
-			}
+			fragment = "deferred/sunLightF.glsl";
 		}
 
 		gDeferredSunProgram.mName = "Deferred Sun Shader";
@@ -1333,21 +1216,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 
 	if (success)
 	{
-		std::string fragment;
-
-		if (multisample)
-		{
-			fragment = "deferred/blurLightMSF.glsl";
-		}
-		else
-		{
-			fragment = "deferred/blurLightF.glsl";
-		}
-
 		gDeferredBlurLightProgram.mName = "Deferred Blur Light Shader";
 		gDeferredBlurLightProgram.mShaderFiles.clear();
 		gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER_ARB));
-		gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));
+		gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER_ARB));
 		gDeferredBlurLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
 		success = gDeferredBlurLightProgram.createShader(NULL, NULL);
 	}
@@ -1363,11 +1235,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
 		if (mVertexShaderLevel[SHADER_DEFERRED] < 1)
 		{
-			gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits;
+			gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
 		}
 		else
 		{ //shave off some texture units for shadow maps
-			gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits - 6;
+			gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
 		}
 			
 		gDeferredAlphaProgram.mShaderFiles.clear();
@@ -1397,7 +1269,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredFullbrightProgram.mFeatures.calculatesAtmospherics = true;
 		gDeferredFullbrightProgram.mFeatures.hasGamma = true;
 		gDeferredFullbrightProgram.mFeatures.hasTransport = true;
-		gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits;
+		gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
 		gDeferredFullbrightProgram.mShaderFiles.clear();
 		gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
 		gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
@@ -1405,6 +1277,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		success = gDeferredFullbrightProgram.createShader(NULL, NULL);
 	}
 
+	if (success)
+	{
+		gDeferredEmissiveProgram.mName = "Deferred Emissive Shader";
+		gDeferredEmissiveProgram.mFeatures.calculatesAtmospherics = true;
+		gDeferredEmissiveProgram.mFeatures.hasGamma = true;
+		gDeferredEmissiveProgram.mFeatures.hasTransport = true;
+		gDeferredEmissiveProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+		gDeferredEmissiveProgram.mShaderFiles.clear();
+		gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
+		gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gDeferredEmissiveProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+		success = gDeferredEmissiveProgram.createShader(NULL, NULL);
+	}
+
 	if (success)
 	{
 		// load water shader
@@ -1421,21 +1307,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 
 	if (success)
 	{
-		std::string fragment;
-
-		if (multisample)
-		{
-			fragment = "deferred/softenLightMSF.glsl";
-		}
-		else
-		{
-			fragment = "deferred/softenLightF.glsl";
-		}
-
 		gDeferredSoftenProgram.mName = "Deferred Soften Shader";
 		gDeferredSoftenProgram.mShaderFiles.clear();
 		gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB));
-		gDeferredSoftenProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));
+		gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB));
 
 		gDeferredSoftenProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
 
@@ -1475,7 +1350,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER_ARB));
 		gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
 		gDeferredAvatarShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
-		success = gDeferredAvatarShadowProgram.createShader(&mAvatarAttribs, &mAvatarUniforms);
+		success = gDeferredAvatarShadowProgram.createShader(NULL, &mAvatarUniforms);
 	}
 
 	if (success)
@@ -1507,7 +1382,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER_ARB));
 		gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER_ARB));
 		gDeferredAvatarProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
-		success = gDeferredAvatarProgram.createShader(&mAvatarAttribs, &mAvatarUniforms);
+		success = gDeferredAvatarProgram.createShader(NULL, &mAvatarUniforms);
 	}
 
 	if (success)
@@ -1522,47 +1397,37 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true;
 		gDeferredAvatarAlphaProgram.mShaderFiles.clear();
 		gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaV.glsl", GL_VERTEX_SHADER_ARB));
-		gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedNoColorF.glsl", GL_FRAGMENT_SHADER_ARB));
 		gDeferredAvatarAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
-		success = gDeferredAvatarAlphaProgram.createShader(&mAvatarAttribs, &mAvatarUniforms);
+		success = gDeferredAvatarAlphaProgram.createShader(NULL, &mAvatarUniforms);
 	}
 
 	if (success)
 	{
-		std::string fragment;
-		if (multisample)
-		{
-			fragment = "deferred/postDeferredMSF.glsl";
-		}
-		else
-		{
-			fragment = "deferred/postDeferredF.glsl";
-		}
+		gFXAAProgram.mName = "FXAA Shader";
+		gFXAAProgram.mShaderFiles.clear();
+		gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB));
+		gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/fxaaF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gFXAAProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+		success = gFXAAProgram.createShader(NULL, NULL);
+	}
 
+	if (success)
+	{
 		gDeferredPostProgram.mName = "Deferred Post Shader";
 		gDeferredPostProgram.mShaderFiles.clear();
 		gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB));
-		gDeferredPostProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));
+		gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER_ARB));
 		gDeferredPostProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
 		success = gDeferredPostProgram.createShader(NULL, NULL);
 	}
 
 	if (success)
 	{
-		std::string fragment;
-		if (multisample)
-		{
-			fragment = "deferred/postDeferredNoDoFMSF.glsl";
-		}
-		else
-		{
-			fragment = "deferred/postDeferredNoDoFF.glsl";
-		}
-
 		gDeferredPostNoDoFProgram.mName = "Deferred Post Shader";
 		gDeferredPostNoDoFProgram.mShaderFiles.clear();
 		gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB));
-		gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));
+		gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER_ARB));
 		gDeferredPostNoDoFProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
 		success = gDeferredPostNoDoFProgram.createShader(NULL, NULL);
 	}
@@ -1601,70 +1466,15 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		success = gDeferredStarProgram.createShader(NULL, &mWLUniforms);
 	}
 
-	if (mVertexShaderLevel[SHADER_DEFERRED] > 1)
-	{
-		if (success)
-		{
-			std::string fragment;
-			if (multisample)
-			{
-				fragment = "deferred/edgeMSF.glsl";
-			}
-			else
-			{
-				fragment = "deferred/edgeF.glsl";
-			}
-
-			gDeferredEdgeProgram.mName = "Deferred Edge Shader";
-			gDeferredEdgeProgram.mShaderFiles.clear();
-			gDeferredEdgeProgram.mShaderFiles.push_back(make_pair("deferred/edgeV.glsl", GL_VERTEX_SHADER_ARB));
-			gDeferredEdgeProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));
-			gDeferredEdgeProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
-			success = gDeferredEdgeProgram.createShader(NULL, NULL);
-		}
-	}
-
-	if (mVertexShaderLevel[SHADER_DEFERRED] > 2)
+	if (success)
 	{
-		if (success)
-		{
-			gDeferredPostGIProgram.mName = "Deferred Post GI Shader";
-			gDeferredPostGIProgram.mShaderFiles.clear();
-			gDeferredPostGIProgram.mShaderFiles.push_back(make_pair("deferred/postgiV.glsl", GL_VERTEX_SHADER_ARB));
-			gDeferredPostGIProgram.mShaderFiles.push_back(make_pair("deferred/postgiF.glsl", GL_FRAGMENT_SHADER_ARB));
-			gDeferredPostGIProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
-			success = gDeferredPostGIProgram.createShader(NULL, NULL);
-		}
-
-		if (success)
-		{
-			gDeferredGIProgram.mName = "Deferred GI Shader";
-			gDeferredGIProgram.mShaderFiles.clear();
-			gDeferredGIProgram.mShaderFiles.push_back(make_pair("deferred/giV.glsl", GL_VERTEX_SHADER_ARB));
-			gDeferredGIProgram.mShaderFiles.push_back(make_pair("deferred/giF.glsl", GL_FRAGMENT_SHADER_ARB));
-			gDeferredGIProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
-			success = gDeferredGIProgram.createShader(NULL, NULL);
-		}
-
-		if (success)
-		{
-			gDeferredGIFinalProgram.mName = "Deferred GI Final Shader";
-			gDeferredGIFinalProgram.mShaderFiles.clear();
-			gDeferredGIFinalProgram.mShaderFiles.push_back(make_pair("deferred/giFinalV.glsl", GL_VERTEX_SHADER_ARB));
-			gDeferredGIFinalProgram.mShaderFiles.push_back(make_pair("deferred/giFinalF.glsl", GL_FRAGMENT_SHADER_ARB));
-			gDeferredGIFinalProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
-			success = gDeferredGIFinalProgram.createShader(NULL, NULL);
-		}
-
-		if (success)
-		{
-			gLuminanceGatherProgram.mName = "Luminance Gather Shader";
-			gLuminanceGatherProgram.mShaderFiles.clear();
-			gLuminanceGatherProgram.mShaderFiles.push_back(make_pair("deferred/luminanceV.glsl", GL_VERTEX_SHADER_ARB));
-			gLuminanceGatherProgram.mShaderFiles.push_back(make_pair("deferred/luminanceF.glsl", GL_FRAGMENT_SHADER_ARB));
-			gLuminanceGatherProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
-			success = gLuminanceGatherProgram.createShader(NULL, NULL);
-		}
+		gNormalMapGenProgram.mName = "Normal Map Generation Program";
+		gNormalMapGenProgram.mShaderFiles.clear();
+		gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenV.glsl", GL_VERTEX_SHADER_ARB));
+		gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gNormalMapGenProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+		gNormalMapGenProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+		success = gNormalMapGenProgram.createShader(NULL, NULL);
 	}
 
 	return success;
@@ -1680,12 +1490,17 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 		gObjectFullbrightShinyProgram.unload();
 		gObjectFullbrightShinyWaterProgram.unload();
 		gObjectShinyWaterProgram.unload();
+		gObjectFullbrightNoColorProgram.unload();
+		gObjectFullbrightNoColorWaterProgram.unload();
 		gObjectSimpleProgram.unload();
+		gObjectPreviewProgram.unload();
 		gImpostorProgram.unload();
 		gObjectSimpleAlphaMaskProgram.unload();
 		gObjectBumpProgram.unload();
 		gObjectSimpleWaterProgram.unload();
 		gObjectSimpleWaterAlphaMaskProgram.unload();
+		gObjectEmissiveProgram.unload();
+		gObjectEmissiveWaterProgram.unload();
 		gObjectFullbrightProgram.unload();
 		gObjectFullbrightAlphaMaskProgram.unload();
 		gObjectFullbrightWaterProgram.unload();
@@ -1694,20 +1509,29 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 		gObjectFullbrightShinyNonIndexedProgram.unload();
 		gObjectFullbrightShinyNonIndexedWaterProgram.unload();
 		gObjectShinyNonIndexedWaterProgram.unload();
-		gObjectSimpleNonIndexedProgram.unload();
+		gObjectSimpleNonIndexedTexGenProgram.unload();
+		gObjectSimpleNonIndexedTexGenWaterProgram.unload();
 		gObjectSimpleNonIndexedWaterProgram.unload();
 		gObjectAlphaMaskNonIndexedProgram.unload();
 		gObjectAlphaMaskNonIndexedWaterProgram.unload();
+		gObjectAlphaMaskNoColorProgram.unload();
+		gObjectAlphaMaskNoColorWaterProgram.unload();
 		gObjectFullbrightNonIndexedProgram.unload();
 		gObjectFullbrightNonIndexedWaterProgram.unload();
+		gObjectEmissiveNonIndexedProgram.unload();
+		gObjectEmissiveNonIndexedWaterProgram.unload();
 		gSkinnedObjectSimpleProgram.unload();
 		gSkinnedObjectFullbrightProgram.unload();
+		gSkinnedObjectEmissiveProgram.unload();
 		gSkinnedObjectFullbrightShinyProgram.unload();
 		gSkinnedObjectShinySimpleProgram.unload();
 		gSkinnedObjectSimpleWaterProgram.unload();
 		gSkinnedObjectFullbrightWaterProgram.unload();
+		gSkinnedObjectEmissiveWaterProgram.unload();
 		gSkinnedObjectFullbrightShinyWaterProgram.unload();
 		gSkinnedObjectShinySimpleWaterProgram.unload();
+		gTreeProgram.unload();
+		gTreeWaterProgram.unload();
 	
 		return TRUE;
 	}
@@ -1728,6 +1552,23 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 		success = gObjectSimpleNonIndexedProgram.createShader(NULL, NULL);
 	}
 	
+	if (success)
+	{
+		gObjectSimpleNonIndexedTexGenProgram.mName = "Non indexed tex-gen Shader";
+		gObjectSimpleNonIndexedTexGenProgram.mFeatures.calculatesLighting = true;
+		gObjectSimpleNonIndexedTexGenProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectSimpleNonIndexedTexGenProgram.mFeatures.hasGamma = true;
+		gObjectSimpleNonIndexedTexGenProgram.mFeatures.hasAtmospherics = true;
+		gObjectSimpleNonIndexedTexGenProgram.mFeatures.hasLighting = true;
+		gObjectSimpleNonIndexedTexGenProgram.mFeatures.disableTextureIndex = true;
+		gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.clear();
+		gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.push_back(make_pair("objects/simpleTexGenV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectSimpleNonIndexedTexGenProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		success = gObjectSimpleNonIndexedTexGenProgram.createShader(NULL, NULL);
+	}
+	
+
 	if (success)
 	{
 		gObjectSimpleNonIndexedWaterProgram.mName = "Non indexed Water Shader";
@@ -1745,6 +1586,23 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 		success = gObjectSimpleNonIndexedWaterProgram.createShader(NULL, NULL);
 	}
 
+	if (success)
+	{
+		gObjectSimpleNonIndexedTexGenWaterProgram.mName = "Non indexed tex-gen Water Shader";
+		gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.calculatesLighting = true;
+		gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.hasWaterFog = true;
+		gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.hasAtmospherics = true;
+		gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.hasLighting = true;
+		gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.disableTextureIndex = true;
+		gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.clear();
+		gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleTexGenV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectSimpleNonIndexedTexGenWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		gObjectSimpleNonIndexedTexGenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+		success = gObjectSimpleNonIndexedTexGenWaterProgram.createShader(NULL, NULL);
+	}
+
 	if (success)
 	{
 		gObjectAlphaMaskNonIndexedProgram.mName = "Non indexed alpha mask Shader";
@@ -1756,7 +1614,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 		gObjectAlphaMaskNonIndexedProgram.mFeatures.disableTextureIndex = true;
 		gObjectAlphaMaskNonIndexedProgram.mFeatures.hasAlphaMask = true;
 		gObjectAlphaMaskNonIndexedProgram.mShaderFiles.clear();
-		gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleNonIndexedV.glsl", GL_VERTEX_SHADER_ARB));
 		gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
 		gObjectAlphaMaskNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
 		success = gObjectAlphaMaskNonIndexedProgram.createShader(NULL, NULL);
@@ -1773,13 +1631,83 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 		gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.disableTextureIndex = true;
 		gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.hasAlphaMask = true;
 		gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.clear();
-		gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNonIndexedV.glsl", GL_VERTEX_SHADER_ARB));
 		gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
 		gObjectAlphaMaskNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
 		gObjectAlphaMaskNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
 		success = gObjectAlphaMaskNonIndexedWaterProgram.createShader(NULL, NULL);
 	}
 
+	if (success)
+	{
+		gObjectAlphaMaskNoColorProgram.mName = "No color alpha mask Shader";
+		gObjectAlphaMaskNoColorProgram.mFeatures.calculatesLighting = true;
+		gObjectAlphaMaskNoColorProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectAlphaMaskNoColorProgram.mFeatures.hasGamma = true;
+		gObjectAlphaMaskNoColorProgram.mFeatures.hasAtmospherics = true;
+		gObjectAlphaMaskNoColorProgram.mFeatures.hasLighting = true;
+		gObjectAlphaMaskNoColorProgram.mFeatures.disableTextureIndex = true;
+		gObjectAlphaMaskNoColorProgram.mFeatures.hasAlphaMask = true;
+		gObjectAlphaMaskNoColorProgram.mShaderFiles.clear();
+		gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectAlphaMaskNoColorProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		success = gObjectAlphaMaskNoColorProgram.createShader(NULL, NULL);
+	}
+	
+	if (success)
+	{
+		gObjectAlphaMaskNoColorWaterProgram.mName = "No color alpha mask Water Shader";
+		gObjectAlphaMaskNoColorWaterProgram.mFeatures.calculatesLighting = true;
+		gObjectAlphaMaskNoColorWaterProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasWaterFog = true;
+		gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasAtmospherics = true;
+		gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasLighting = true;
+		gObjectAlphaMaskNoColorWaterProgram.mFeatures.disableTextureIndex = true;
+		gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasAlphaMask = true;
+		gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.clear();
+		gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectAlphaMaskNoColorWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		gObjectAlphaMaskNoColorWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+		success = gObjectAlphaMaskNoColorWaterProgram.createShader(NULL, NULL);
+	}
+
+	if (success)
+	{
+		gTreeProgram.mName = "Tree Shader";
+		gTreeProgram.mFeatures.calculatesLighting = true;
+		gTreeProgram.mFeatures.calculatesAtmospherics = true;
+		gTreeProgram.mFeatures.hasGamma = true;
+		gTreeProgram.mFeatures.hasAtmospherics = true;
+		gTreeProgram.mFeatures.hasLighting = true;
+		gTreeProgram.mFeatures.disableTextureIndex = true;
+		gTreeProgram.mFeatures.hasAlphaMask = true;
+		gTreeProgram.mShaderFiles.clear();
+		gTreeProgram.mShaderFiles.push_back(make_pair("objects/treeV.glsl", GL_VERTEX_SHADER_ARB));
+		gTreeProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gTreeProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		success = gTreeProgram.createShader(NULL, NULL);
+	}
+	
+	if (success)
+	{
+		gTreeWaterProgram.mName = "Tree Water Shader";
+		gTreeWaterProgram.mFeatures.calculatesLighting = true;
+		gTreeWaterProgram.mFeatures.calculatesAtmospherics = true;
+		gTreeWaterProgram.mFeatures.hasWaterFog = true;
+		gTreeWaterProgram.mFeatures.hasAtmospherics = true;
+		gTreeWaterProgram.mFeatures.hasLighting = true;
+		gTreeWaterProgram.mFeatures.disableTextureIndex = true;
+		gTreeWaterProgram.mFeatures.hasAlphaMask = true;
+		gTreeWaterProgram.mShaderFiles.clear();
+		gTreeWaterProgram.mShaderFiles.push_back(make_pair("objects/treeV.glsl", GL_VERTEX_SHADER_ARB));
+		gTreeWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gTreeWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		gTreeWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+		success = gTreeWaterProgram.createShader(NULL, NULL);
+	}
+
 	if (success)
 	{
 		gObjectFullbrightNonIndexedProgram.mName = "Non Indexed Fullbright Shader";
@@ -1811,6 +1739,68 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 		success = gObjectFullbrightNonIndexedWaterProgram.createShader(NULL, NULL);
 	}
 
+	if (success)
+	{
+		gObjectEmissiveNonIndexedProgram.mName = "Non Indexed Emissive Shader";
+		gObjectEmissiveNonIndexedProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectEmissiveNonIndexedProgram.mFeatures.hasGamma = true;
+		gObjectEmissiveNonIndexedProgram.mFeatures.hasTransport = true;
+		gObjectEmissiveNonIndexedProgram.mFeatures.isFullbright = true;
+		gObjectEmissiveNonIndexedProgram.mFeatures.disableTextureIndex = true;
+		gObjectEmissiveNonIndexedProgram.mShaderFiles.clear();
+		gObjectEmissiveNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectEmissiveNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectEmissiveNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		success = gObjectEmissiveNonIndexedProgram.createShader(NULL, NULL);
+	}
+
+	if (success)
+	{
+		gObjectEmissiveNonIndexedWaterProgram.mName = "Non Indexed Emissive Water Shader";
+		gObjectEmissiveNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectEmissiveNonIndexedWaterProgram.mFeatures.isFullbright = true;
+		gObjectEmissiveNonIndexedWaterProgram.mFeatures.hasWaterFog = true;		
+		gObjectEmissiveNonIndexedWaterProgram.mFeatures.hasTransport = true;
+		gObjectEmissiveNonIndexedWaterProgram.mFeatures.disableTextureIndex = true;
+		gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.clear();
+		gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectEmissiveNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		gObjectEmissiveNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+		success = gObjectEmissiveNonIndexedWaterProgram.createShader(NULL, NULL);
+	}
+
+	if (success)
+	{
+		gObjectFullbrightNoColorProgram.mName = "Non Indexed no color Fullbright Shader";
+		gObjectFullbrightNoColorProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectFullbrightNoColorProgram.mFeatures.hasGamma = true;
+		gObjectFullbrightNoColorProgram.mFeatures.hasTransport = true;
+		gObjectFullbrightNoColorProgram.mFeatures.isFullbright = true;
+		gObjectFullbrightNoColorProgram.mFeatures.disableTextureIndex = true;
+		gObjectFullbrightNoColorProgram.mShaderFiles.clear();
+		gObjectFullbrightNoColorProgram.mShaderFiles.push_back(make_pair("objects/fullbrightNoColorV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectFullbrightNoColorProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectFullbrightNoColorProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		success = gObjectFullbrightNoColorProgram.createShader(NULL, NULL);
+	}
+
+	if (success)
+	{
+		gObjectFullbrightNoColorWaterProgram.mName = "Non Indexed no color Fullbright Water Shader";
+		gObjectFullbrightNoColorWaterProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectFullbrightNoColorWaterProgram.mFeatures.isFullbright = true;
+		gObjectFullbrightNoColorWaterProgram.mFeatures.hasWaterFog = true;		
+		gObjectFullbrightNoColorWaterProgram.mFeatures.hasTransport = true;
+		gObjectFullbrightNoColorWaterProgram.mFeatures.disableTextureIndex = true;
+		gObjectFullbrightNoColorWaterProgram.mShaderFiles.clear();
+		gObjectFullbrightNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightNoColorV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectFullbrightNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectFullbrightNoColorWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		gObjectFullbrightNoColorWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+		success = gObjectFullbrightNoColorWaterProgram.createShader(NULL, NULL);
+	}
+
 	if (success)
 	{
 		gObjectShinyNonIndexedProgram.mName = "Non Indexed Shiny Shader";
@@ -1889,6 +1879,23 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 		success = gImpostorProgram.createShader(NULL, NULL);
 	}
 
+	if (success)
+	{
+		gObjectPreviewProgram.mName = "Simple Shader";
+		gObjectPreviewProgram.mFeatures.calculatesLighting = true;
+		gObjectPreviewProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectPreviewProgram.mFeatures.hasGamma = true;
+		gObjectPreviewProgram.mFeatures.hasAtmospherics = true;
+		gObjectPreviewProgram.mFeatures.hasLighting = true;
+		gObjectPreviewProgram.mFeatures.mIndexedTextureChannels = 0;
+		gObjectPreviewProgram.mFeatures.disableTextureIndex = true;
+		gObjectPreviewProgram.mShaderFiles.clear();
+		gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectPreviewProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		success = gObjectPreviewProgram.createShader(NULL, NULL);
+	}
+
 	if (success)
 	{
 		gObjectSimpleProgram.mName = "Simple Shader";
@@ -1907,19 +1914,19 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 
 	if (success)
 	{
-		gObjectSimpleAlphaMaskProgram.mName = "Simple Alpha Mask Shader";
-		gObjectSimpleAlphaMaskProgram.mFeatures.calculatesLighting = true;
-		gObjectSimpleAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
-		gObjectSimpleAlphaMaskProgram.mFeatures.hasGamma = true;
-		gObjectSimpleAlphaMaskProgram.mFeatures.hasAtmospherics = true;
-		gObjectSimpleAlphaMaskProgram.mFeatures.hasLighting = true;
-		gObjectSimpleAlphaMaskProgram.mFeatures.hasAlphaMask = true;
-		gObjectSimpleAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0;
-		gObjectSimpleAlphaMaskProgram.mShaderFiles.clear();
-		gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
-		gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
-		gObjectSimpleAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
-		success = gObjectSimpleAlphaMaskProgram.createShader(NULL, NULL);
+		gObjectSimpleWaterProgram.mName = "Simple Water Shader";
+		gObjectSimpleWaterProgram.mFeatures.calculatesLighting = true;
+		gObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectSimpleWaterProgram.mFeatures.hasWaterFog = true;
+		gObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true;
+		gObjectSimpleWaterProgram.mFeatures.hasLighting = true;
+		gObjectSimpleWaterProgram.mFeatures.mIndexedTextureChannels = 0;
+		gObjectSimpleWaterProgram.mShaderFiles.clear();
+		gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectSimpleWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		gObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+		success = gObjectSimpleWaterProgram.createShader(NULL, NULL);
 	}
 	
 	if (success)
@@ -1936,25 +1943,34 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 		gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER_ARB));
 		gObjectBumpProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
 		success = gObjectBumpProgram.createShader(NULL, NULL);
+
+		if (success)
+		{ //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1
+			gObjectBumpProgram.bind();
+			gObjectBumpProgram.uniform1i("texture0", 0);
+			gObjectBumpProgram.uniform1i("texture1", 1);
+			gObjectBumpProgram.unbind();
+		}
 	}
 	
+	
 	if (success)
 	{
-		gObjectSimpleWaterProgram.mName = "Simple Water Shader";
-		gObjectSimpleWaterProgram.mFeatures.calculatesLighting = true;
-		gObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true;
-		gObjectSimpleWaterProgram.mFeatures.hasWaterFog = true;
-		gObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true;
-		gObjectSimpleWaterProgram.mFeatures.hasLighting = true;
-		gObjectSimpleWaterProgram.mFeatures.mIndexedTextureChannels = 0;
-		gObjectSimpleWaterProgram.mShaderFiles.clear();
-		gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
-		gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
-		gObjectSimpleWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
-		gObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
-		success = gObjectSimpleWaterProgram.createShader(NULL, NULL);
+		gObjectSimpleAlphaMaskProgram.mName = "Simple Alpha Mask Shader";
+		gObjectSimpleAlphaMaskProgram.mFeatures.calculatesLighting = true;
+		gObjectSimpleAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectSimpleAlphaMaskProgram.mFeatures.hasGamma = true;
+		gObjectSimpleAlphaMaskProgram.mFeatures.hasAtmospherics = true;
+		gObjectSimpleAlphaMaskProgram.mFeatures.hasLighting = true;
+		gObjectSimpleAlphaMaskProgram.mFeatures.hasAlphaMask = true;
+		gObjectSimpleAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0;
+		gObjectSimpleAlphaMaskProgram.mShaderFiles.clear();
+		gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectSimpleAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		success = gObjectSimpleAlphaMaskProgram.createShader(NULL, NULL);
 	}
-	
+
 	if (success)
 	{
 		gObjectSimpleWaterAlphaMaskProgram.mName = "Simple Water Alpha Mask Shader";
@@ -2004,6 +2020,37 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 		success = gObjectFullbrightWaterProgram.createShader(NULL, NULL);
 	}
 
+	if (success)
+	{
+		gObjectEmissiveProgram.mName = "Emissive Shader";
+		gObjectEmissiveProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectEmissiveProgram.mFeatures.hasGamma = true;
+		gObjectEmissiveProgram.mFeatures.hasTransport = true;
+		gObjectEmissiveProgram.mFeatures.isFullbright = true;
+		gObjectEmissiveProgram.mFeatures.mIndexedTextureChannels = 0;
+		gObjectEmissiveProgram.mShaderFiles.clear();
+		gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectEmissiveProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		success = gObjectEmissiveProgram.createShader(NULL, NULL);
+	}
+
+	if (success)
+	{
+		gObjectEmissiveWaterProgram.mName = "Emissive Water Shader";
+		gObjectEmissiveWaterProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectEmissiveWaterProgram.mFeatures.isFullbright = true;
+		gObjectEmissiveWaterProgram.mFeatures.hasWaterFog = true;		
+		gObjectEmissiveWaterProgram.mFeatures.hasTransport = true;
+		gObjectEmissiveWaterProgram.mFeatures.mIndexedTextureChannels = 0;
+		gObjectEmissiveWaterProgram.mShaderFiles.clear();
+		gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectEmissiveWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		gObjectEmissiveWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+		success = gObjectEmissiveWaterProgram.createShader(NULL, NULL);
+	}
+
 	if (success)
 	{
 		gObjectFullbrightAlphaMaskProgram.mName = "Fullbright Alpha Mask Shader";
@@ -2139,6 +2186,39 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 			success = gSkinnedObjectFullbrightProgram.createShader(NULL, NULL);
 		}
 
+		if (success)
+		{
+			gSkinnedObjectEmissiveProgram.mName = "Skinned Emissive Shader";
+			gSkinnedObjectEmissiveProgram.mFeatures.calculatesAtmospherics = true;
+			gSkinnedObjectEmissiveProgram.mFeatures.hasGamma = true;
+			gSkinnedObjectEmissiveProgram.mFeatures.hasTransport = true;
+			gSkinnedObjectEmissiveProgram.mFeatures.isFullbright = true;
+			gSkinnedObjectEmissiveProgram.mFeatures.hasObjectSkinning = true;
+			gSkinnedObjectEmissiveProgram.mFeatures.disableTextureIndex = true;
+			gSkinnedObjectEmissiveProgram.mShaderFiles.clear();
+			gSkinnedObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
+			gSkinnedObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+			gSkinnedObjectEmissiveProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+			success = gSkinnedObjectEmissiveProgram.createShader(NULL, NULL);
+		}
+
+		if (success)
+		{
+			gSkinnedObjectEmissiveWaterProgram.mName = "Skinned Emissive Water Shader";
+			gSkinnedObjectEmissiveWaterProgram.mFeatures.calculatesAtmospherics = true;
+			gSkinnedObjectEmissiveWaterProgram.mFeatures.hasGamma = true;
+			gSkinnedObjectEmissiveWaterProgram.mFeatures.hasTransport = true;
+			gSkinnedObjectEmissiveWaterProgram.mFeatures.isFullbright = true;
+			gSkinnedObjectEmissiveWaterProgram.mFeatures.hasObjectSkinning = true;
+			gSkinnedObjectEmissiveWaterProgram.mFeatures.disableTextureIndex = true;
+			gSkinnedObjectEmissiveWaterProgram.mFeatures.hasWaterFog = true;
+			gSkinnedObjectEmissiveWaterProgram.mShaderFiles.clear();
+			gSkinnedObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
+			gSkinnedObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+			gSkinnedObjectEmissiveWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+			success = gSkinnedObjectEmissiveWaterProgram.createShader(NULL, NULL);
+		}
+
 		if (success)
 		{
 			gSkinnedObjectFullbrightShinyProgram.mName = "Skinned Fullbright Shiny Shader";
@@ -2287,7 +2367,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
 		gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));
 		gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER_ARB));
 		gAvatarProgram.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR];
-		success = gAvatarProgram.createShader(&mAvatarAttribs, &mAvatarUniforms);
+		success = gAvatarProgram.createShader(NULL, &mAvatarUniforms);
 			
 		if (success)
 		{
@@ -2306,7 +2386,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
 			// Note: no cloth under water:
 			gAvatarWaterProgram.mShaderLevel = llmin(mVertexShaderLevel[SHADER_AVATAR], 1);	
 			gAvatarWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;				
-			success = gAvatarWaterProgram.createShader(&mAvatarAttribs, &mAvatarUniforms);
+			success = gAvatarWaterProgram.createShader(NULL, &mAvatarUniforms);
 		}
 
 		/// Keep track of avatar levels
@@ -2325,7 +2405,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
 		gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER_ARB));
 		gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER_ARB));
 		gAvatarPickProgram.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR];
-		success = gAvatarPickProgram.createShader(&mAvatarAttribs, &mAvatarUniforms);
+		success = gAvatarPickProgram.createShader(NULL, &mAvatarUniforms);
 	}
 
 	if (success)
@@ -2396,6 +2476,22 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
 		success = gCustomAlphaProgram.createShader(NULL, NULL);
 	}
 
+	if (success)
+	{
+		gSplatTextureRectProgram.mName = "Splat Texture Rect Shader";
+		gSplatTextureRectProgram.mShaderFiles.clear();
+		gSplatTextureRectProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER_ARB));
+		gSplatTextureRectProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gSplatTextureRectProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+		success = gSplatTextureRectProgram.createShader(NULL, NULL);
+		if (success)
+		{
+			gSplatTextureRectProgram.bind();
+			gSplatTextureRectProgram.uniform1i("screenMap", 0);
+			gSplatTextureRectProgram.unbind();
+		}
+	}
+
 	if (success)
 	{
 		gGlowCombineProgram.mName = "Glow Combine Shader";
@@ -2413,6 +2509,24 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
 		}
 	}
 
+	if (success)
+	{
+		gGlowCombineFXAAProgram.mName = "Glow CombineFXAA Shader";
+		gGlowCombineFXAAProgram.mShaderFiles.clear();
+		gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER_ARB));
+		gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gGlowCombineFXAAProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+		success = gGlowCombineFXAAProgram.createShader(NULL, NULL);
+		if (success)
+		{
+			gGlowCombineFXAAProgram.bind();
+			gGlowCombineFXAAProgram.uniform1i("glowMap", 0);
+			gGlowCombineFXAAProgram.uniform1i("screenMap", 1);
+			gGlowCombineFXAAProgram.unbind();
+		}
+	}
+
+
 	if (success)
 	{
 		gTwoTextureAddProgram.mName = "Two Texture Add Shader";
@@ -2429,6 +2543,21 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
 		}
 	}
 
+	if (success)
+	{
+		gOneTextureNoColorProgram.mName = "One Texture No Color Shader";
+		gOneTextureNoColorProgram.mShaderFiles.clear();
+		gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorV.glsl", GL_VERTEX_SHADER_ARB));
+		gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gOneTextureNoColorProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+		success = gOneTextureNoColorProgram.createShader(NULL, NULL);
+		if (success)
+		{
+			gOneTextureNoColorProgram.bind();
+			gOneTextureNoColorProgram.uniform1i("tex0", 0);
+		}
+	}
+
 	if (success)
 	{
 		gSolidColorProgram.mName = "Solid Color Shader";
@@ -2455,6 +2584,26 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
 		success = gOcclusionProgram.createShader(NULL, NULL);
 	}
 
+	if (success)
+	{
+		gDebugProgram.mName = "Debug Shader";
+		gDebugProgram.mShaderFiles.clear();
+		gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER_ARB));
+		gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gDebugProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+		success = gDebugProgram.createShader(NULL, NULL);
+	}
+
+	if (success)
+	{
+		gAlphaMaskProgram.mName = "Alpha Mask Shader";
+		gAlphaMaskProgram.mShaderFiles.clear();
+		gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER_ARB));
+		gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+		success = gAlphaMaskProgram.createShader(NULL, NULL);
+	}
+
 	if( !success )
 	{
 		mVertexShaderLevel[SHADER_INTERFACE] = 0;
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index d4040f11e1ffcf7344213ff0353309f3618bb626..3f670dfb1459615c402247b2c05875041d5a6049 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -33,6 +33,7 @@ class LLViewerShaderMgr: public LLShaderMgr
 {
 public:
 	static BOOL sInitialized;
+	static bool sSkipReload;
 
 	LLViewerShaderMgr();
 	/* virtual */ ~LLViewerShaderMgr();
@@ -71,76 +72,6 @@ class LLViewerShaderMgr: public LLShaderMgr
 		SHADER_COUNT
 	};
 
-	typedef enum 
-	{
-		MATERIAL_COLOR = 0,
-		SPECULAR_COLOR,
-		BINORMAL,
-		OBJECT_WEIGHT,
-		END_RESERVED_ATTRIBS
-	} eGLSLReservedAttribs;
-	
-	typedef enum
-	{
-		DIFFUSE_MAP = 0,
-		SPECULAR_MAP,
-		BUMP_MAP,
-		ENVIRONMENT_MAP,
-		CLOUD_NOISE_MAP,
-		FULLBRIGHT,
-		LIGHTNORM,
-		SUNLIGHT_COLOR,
-		AMBIENT,
-		BLUE_HORIZON,
-		BLUE_DENSITY,
-		HAZE_HORIZON,
-		HAZE_DENSITY,
-		CLOUD_SHADOW,
-		DENSITY_MULTIPLIER,
-		DISTANCE_MULTIPLIER,
-		MAX_Y,
-		GLOW,
-		CLOUD_COLOR,
-		CLOUD_POS_DENSITY1,
-		CLOUD_POS_DENSITY2,
-		CLOUD_SCALE,
-		GAMMA,
-		SCENE_LIGHT_STRENGTH,
-		DEFERRED_DEPTH,
-		DEFERRED_SHADOW0,
-		DEFERRED_SHADOW1,
-		DEFERRED_SHADOW2,
-		DEFERRED_SHADOW3,
-		DEFERRED_SHADOW4,
-		DEFERRED_SHADOW5,
-		DEFERRED_NORMAL,
-		DEFERRED_POSITION,
-		DEFERRED_DIFFUSE,
-		DEFERRED_SPECULAR,
-		DEFERRED_NOISE,
-		DEFERRED_LIGHTFUNC,
-		DEFERRED_LIGHT,
-		DEFERRED_LUMINANCE,
-		DEFERRED_GI_LIGHT,
-		DEFERRED_GI_MIP,
-		DEFERRED_EDGE,
-		DEFERRED_BLOOM,
-		DEFERRED_SUN_LIGHT,
-		DEFERRED_LOCAL_LIGHT,
-		DEFERRED_PROJECTION,
-		DEFERRED_GI_DIFFUSE,
-		DEFERRED_GI_SPECULAR,
-		DEFERRED_GI_NORMAL,
-		DEFERRED_GI_MIN_POS,
-		DEFERRED_GI_MAX_POS,
-		DEFERRED_GI_DEPTH,
-		DEFERRED_GI_LAST_DIFFUSE,
-		DEFERRED_GI_LAST_NORMAL,
-		DEFERRED_GI_LAST_MIN_POS,
-		DEFERRED_GI_LAST_MAX_POS,
-		END_RESERVED_UNIFORMS
-	} eGLSLReservedUniforms;
-
 	typedef enum
 	{
 		SHINY_ORIGIN = END_RESERVED_UNIFORMS
@@ -186,16 +117,10 @@ class LLViewerShaderMgr: public LLShaderMgr
 
 	typedef enum
 	{
-		AVATAR_WEIGHT = END_RESERVED_ATTRIBS,
-		AVATAR_CLOTHING,
+		AVATAR_MATRIX = END_RESERVED_UNIFORMS,
 		AVATAR_WIND,
 		AVATAR_SINWAVE,
-		AVATAR_GRAVITY
-	} eAvatarAttribs;
-
-	typedef enum
-	{
-		AVATAR_MATRIX = END_RESERVED_UNIFORMS
+		AVATAR_GRAVITY,
 	} eAvatarUniforms;
 
 	// simple model of forward iterator
@@ -265,9 +190,6 @@ class LLViewerShaderMgr: public LLShaderMgr
 
 	std::vector<std::string> mGlowExtractUniforms;
 
-	//avatar shader parameter tables
-	std::vector<std::string> mAvatarAttribs;
-
 	std::vector<std::string> mAvatarUniforms;
 
 	// the list of shaders we need to propagate parameters to.
@@ -291,26 +213,45 @@ extern LLVector4			gShinyOrigin;
 extern LLGLSLShader			gOcclusionProgram;
 extern LLGLSLShader			gCustomAlphaProgram;
 extern LLGLSLShader			gGlowCombineProgram;
+extern LLGLSLShader			gSplatTextureRectProgram;
+extern LLGLSLShader			gGlowCombineFXAAProgram;
+extern LLGLSLShader			gDebugProgram;
+extern LLGLSLShader			gAlphaMaskProgram;
 
 //output tex0[tc0] + tex1[tc1]
 extern LLGLSLShader			gTwoTextureAddProgram;
-								
+						
+extern LLGLSLShader			gOneTextureNoColorProgram;
+
 //object shaders
 extern LLGLSLShader			gObjectSimpleProgram;
+extern LLGLSLShader			gObjectPreviewProgram;
 extern LLGLSLShader			gObjectSimpleAlphaMaskProgram;
 extern LLGLSLShader			gObjectSimpleWaterProgram;
 extern LLGLSLShader			gObjectSimpleWaterAlphaMaskProgram;
 extern LLGLSLShader			gObjectSimpleNonIndexedProgram;
+extern LLGLSLShader			gObjectSimpleNonIndexedTexGenProgram;
+extern LLGLSLShader			gObjectSimpleNonIndexedTexGenWaterProgram;
 extern LLGLSLShader			gObjectSimpleNonIndexedWaterProgram;
 extern LLGLSLShader			gObjectAlphaMaskNonIndexedProgram;
 extern LLGLSLShader			gObjectAlphaMaskNonIndexedWaterProgram;
+extern LLGLSLShader			gObjectAlphaMaskNoColorProgram;
+extern LLGLSLShader			gObjectAlphaMaskNoColorWaterProgram;
 extern LLGLSLShader			gObjectFullbrightProgram;
 extern LLGLSLShader			gObjectFullbrightWaterProgram;
+extern LLGLSLShader			gObjectFullbrightNoColorProgram;
+extern LLGLSLShader			gObjectFullbrightNoColorWaterProgram;
+extern LLGLSLShader			gObjectEmissiveProgram;
+extern LLGLSLShader			gObjectEmissiveWaterProgram;
 extern LLGLSLShader			gObjectFullbrightAlphaMaskProgram;
 extern LLGLSLShader			gObjectFullbrightWaterAlphaMaskProgram;
 extern LLGLSLShader			gObjectFullbrightNonIndexedProgram;
 extern LLGLSLShader			gObjectFullbrightNonIndexedWaterProgram;
+extern LLGLSLShader			gObjectEmissiveNonIndexedProgram;
+extern LLGLSLShader			gObjectEmissiveNonIndexedWaterProgram;
 extern LLGLSLShader			gObjectBumpProgram;
+extern LLGLSLShader			gTreeProgram;
+extern LLGLSLShader			gTreeWaterProgram;
 
 extern LLGLSLShader			gObjectSimpleLODProgram;
 extern LLGLSLShader			gObjectFullbrightLODProgram;
@@ -327,11 +268,13 @@ extern LLGLSLShader			gObjectShinyNonIndexedWaterProgram;
 
 extern LLGLSLShader			gSkinnedObjectSimpleProgram;
 extern LLGLSLShader			gSkinnedObjectFullbrightProgram;
+extern LLGLSLShader			gSkinnedObjectEmissiveProgram;
 extern LLGLSLShader			gSkinnedObjectFullbrightShinyProgram;
 extern LLGLSLShader			gSkinnedObjectShinySimpleProgram;
 
 extern LLGLSLShader			gSkinnedObjectSimpleWaterProgram;
 extern LLGLSLShader			gSkinnedObjectFullbrightWaterProgram;
+extern LLGLSLShader			gSkinnedObjectEmissiveWaterProgram;
 extern LLGLSLShader			gSkinnedObjectFullbrightShinyWaterProgram;
 extern LLGLSLShader			gSkinnedObjectShinySimpleWaterProgram;
 
@@ -363,11 +306,11 @@ extern LLGLSLShader			gPostNightVisionProgram;
 
 // Deferred rendering shaders
 extern LLGLSLShader			gDeferredImpostorProgram;
-extern LLGLSLShader			gDeferredEdgeProgram;
 extern LLGLSLShader			gDeferredWaterProgram;
 extern LLGLSLShader			gDeferredDiffuseProgram;
 extern LLGLSLShader			gDeferredDiffuseAlphaMaskProgram;
 extern LLGLSLShader			gDeferredNonIndexedDiffuseAlphaMaskProgram;
+extern LLGLSLShader			gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;
 extern LLGLSLShader			gDeferredNonIndexedDiffuseProgram;
 extern LLGLSLShader			gDeferredSkinnedDiffuseProgram;
 extern LLGLSLShader			gDeferredSkinnedBumpProgram;
@@ -375,34 +318,30 @@ extern LLGLSLShader			gDeferredSkinnedAlphaProgram;
 extern LLGLSLShader			gDeferredBumpProgram;
 extern LLGLSLShader			gDeferredTerrainProgram;
 extern LLGLSLShader			gDeferredTreeProgram;
+extern LLGLSLShader			gDeferredTreeShadowProgram;
 extern LLGLSLShader			gDeferredLightProgram;
 extern LLGLSLShader			gDeferredMultiLightProgram;
 extern LLGLSLShader			gDeferredSpotLightProgram;
 extern LLGLSLShader			gDeferredMultiSpotLightProgram;
 extern LLGLSLShader			gDeferredSunProgram;
-extern LLGLSLShader			gDeferredGIProgram;
-extern LLGLSLShader			gDeferredGIFinalProgram;
 extern LLGLSLShader			gDeferredBlurLightProgram;
 extern LLGLSLShader			gDeferredAvatarProgram;
 extern LLGLSLShader			gDeferredSoftenProgram;
 extern LLGLSLShader			gDeferredShadowProgram;
 extern LLGLSLShader			gDeferredShadowAlphaMaskProgram;
-extern LLGLSLShader			gDeferredPostGIProgram;
 extern LLGLSLShader			gDeferredPostProgram;
+extern LLGLSLShader			gFXAAProgram;
 extern LLGLSLShader			gDeferredPostNoDoFProgram;
 extern LLGLSLShader			gDeferredAvatarShadowProgram;
 extern LLGLSLShader			gDeferredAttachmentShadowProgram;
 extern LLGLSLShader			gDeferredAlphaProgram;
 extern LLGLSLShader			gDeferredFullbrightProgram;
+extern LLGLSLShader			gDeferredEmissiveProgram;
 extern LLGLSLShader			gDeferredAvatarEyesProgram;
 extern LLGLSLShader			gDeferredAvatarAlphaProgram;
 extern LLGLSLShader			gDeferredWLSkyProgram;
 extern LLGLSLShader			gDeferredWLCloudProgram;
 extern LLGLSLShader			gDeferredStarProgram;
-extern LLGLSLShader			gLuminanceGatherProgram;
-
-//current avatar shader parameter pointer
-extern GLint				gAvatarMatrixParam;
-
+extern LLGLSLShader			gNormalMapGenProgram;
 
 #endif
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index c64488251a44f0a31a120139fde99f23e0745c91..eaf177373162bcdf39d8e06d77d728db96d34a5f 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -586,6 +586,11 @@ void LLViewerTextureList::dirtyImage(LLViewerFetchedTexture *image)
 
 ////////////////////////////////////////////////////////////////////////////
 static LLFastTimer::DeclareTimer FTM_IMAGE_MARK_DIRTY("Dirty Images");
+static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_PRIORITIES("Prioritize");
+static LLFastTimer::DeclareTimer FTM_IMAGE_CALLBACKS("Callbacks");
+static LLFastTimer::DeclareTimer FTM_IMAGE_FETCH("Fetch");
+static LLFastTimer::DeclareTimer FTM_IMAGE_CREATE("Create");
+static LLFastTimer::DeclareTimer FTM_IMAGE_STATS("Stats");
 
 void LLViewerTextureList::updateImages(F32 max_time)
 {
@@ -597,14 +602,25 @@ void LLViewerTextureList::updateImages(F32 max_time)
 	LLViewerStats::getInstance()->mGLBoundMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sBoundTextureMemoryInBytes));
 	LLViewerStats::getInstance()->mRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageRaw::sGlobalRawMemory));
 	LLViewerStats::getInstance()->mFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory));
-	
-	updateImagesDecodePriorities();
+
+
+	{
+		LLFastTimer t(FTM_IMAGE_UPDATE_PRIORITIES);
+		updateImagesDecodePriorities();
+	}
 
 	F32 total_max_time = max_time;
-	max_time -= updateImagesFetchTextures(max_time);
+
+	{
+		LLFastTimer t(FTM_IMAGE_FETCH);
+		max_time -= updateImagesFetchTextures(max_time);
+	}
 	
-	max_time = llmax(max_time, total_max_time*.50f); // at least 50% of max_time
-	max_time -= updateImagesCreateTextures(max_time);
+	{
+		LLFastTimer t(FTM_IMAGE_CREATE);
+		max_time = llmax(max_time, total_max_time*.50f); // at least 50% of max_time
+		max_time -= updateImagesCreateTextures(max_time);
+	}
 	
 	if (!mDirtyTextureList.empty())
 	{
@@ -612,24 +628,32 @@ void LLViewerTextureList::updateImages(F32 max_time)
 		gPipeline.dirtyPoolObjectTextures(mDirtyTextureList);
 		mDirtyTextureList.clear();
 	}
-	bool didone = false;
-	for (image_list_t::iterator iter = mCallbackList.begin();
-		iter != mCallbackList.end(); )
+
 	{
-		//trigger loaded callbacks on local textures immediately
-		LLViewerFetchedTexture* image = *iter++;
-		if (!image->getUrl().empty())
+		LLFastTimer t(FTM_IMAGE_CALLBACKS);
+		bool didone = false;
+		for (image_list_t::iterator iter = mCallbackList.begin();
+			iter != mCallbackList.end(); )
 		{
-			// Do stuff to handle callbacks, update priorities, etc.
-			didone = image->doLoadedCallbacks();
-		}
-		else if (!didone)
-		{
-			// Do stuff to handle callbacks, update priorities, etc.
-			didone = image->doLoadedCallbacks();
+			//trigger loaded callbacks on local textures immediately
+			LLViewerFetchedTexture* image = *iter++;
+			if (!image->getUrl().empty())
+			{
+				// Do stuff to handle callbacks, update priorities, etc.
+				didone = image->doLoadedCallbacks();
+			}
+			else if (!didone)
+			{
+				// Do stuff to handle callbacks, update priorities, etc.
+				didone = image->doLoadedCallbacks();
+			}
 		}
 	}
-	updateImagesUpdateStats();
+
+	{
+		LLFastTimer t(FTM_IMAGE_STATS);
+		updateImagesUpdateStats();
+	}
 }
 
 void LLViewerTextureList::updateImagesDecodePriorities()
@@ -747,7 +771,6 @@ void LLViewerTextureList::updateImagesDecodePriorities()
  return type_from_host;
  }
  */
-static LLFastTimer::DeclareTimer FTM_IMAGE_CREATE("Create Images");
 
 F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
 {
@@ -757,8 +780,7 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
 	// Create GL textures for all textures that need them (images which have been
 	// decoded, but haven't been pushed into GL).
 	//
-	LLFastTimer t(FTM_IMAGE_CREATE);
-	
+		
 	LLTimer create_timer;
 	image_list_t::iterator enditer = mCreateTextureList.begin();
 	for (image_list_t::iterator iter = mCreateTextureList.begin();
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 6fcbc401af1bd4700fedbbd02ffeaa951f269259..e3bf6327e7a7605c6f63f0e76774de4316045228 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -534,7 +534,7 @@ class LLDebugText
 			
 			}
 
-			addText(xpos, ypos, llformat("%d MB Vertex Data", LLVertexBuffer::sAllocatedBytes/(1024*1024)));
+			addText(xpos, ypos, llformat("%d MB Vertex Data (%d MB Pooled)", LLVertexBuffer::sAllocatedBytes/(1024*1024), LLVBOPool::sBytesPooled/(1024*1024)));
 			ypos += y_inc;
 
 			addText(xpos, ypos, llformat("%d Vertex Buffers", LLVertexBuffer::sGLCount));
@@ -1586,6 +1586,12 @@ LLViewerWindow::LLViewerWindow(
 		ignore_pixel_depth,
 		gSavedSettings.getBOOL("RenderDeferred") ? 0 : gSavedSettings.getU32("RenderFSAASamples")); //don't use window level anti-aliasing if FBOs are enabled
 
+	if (!LLViewerShaderMgr::sInitialized)
+	{ //immediately initialize shaders
+		LLViewerShaderMgr::sInitialized = TRUE;
+		LLViewerShaderMgr::instance()->setShaders();
+	}
+
 	if (NULL == mWindow)
 	{
 		LLSplashScreen::update(LLTrans::getString("StartupRequireDriverUpdate"));
@@ -1722,32 +1728,30 @@ LLViewerWindow::LLViewerWindow(
 void LLViewerWindow::initGLDefaults()
 {
 	gGL.setSceneBlendType(LLRender::BT_ALPHA);
-	glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
 
-	F32 ambient[4] = {0.f,0.f,0.f,0.f };
-	F32 diffuse[4] = {1.f,1.f,1.f,1.f };
-	glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,ambient);
-	glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,diffuse);
-	
-	glPixelStorei(GL_PACK_ALIGNMENT,1);
-	glPixelStorei(GL_UNPACK_ALIGNMENT,1);
+	if (!LLGLSLShader::sNoFixedFunction)
+	{ //initialize fixed function state
+		glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
 
-	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+		glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,LLColor4::black.mV);
+		glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,LLColor4::white.mV);
 
-	// lights for objects
-	glShadeModel( GL_SMOOTH );
+		// lights for objects
+		glShadeModel( GL_SMOOTH );
 
-	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
-	
-	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+	}
+
+	glPixelStorei(GL_PACK_ALIGNMENT,1);
+	glPixelStorei(GL_UNPACK_ALIGNMENT,1);
 
+	gGL.setAmbientLightColor(LLColor4::black);
+		
 	glCullFace(GL_BACK);
 
 	// RN: Need this for translation and stretch manip.
-	gCone.prerender();
 	gBox.prerender();
-	gSphere.prerender();
-	gCylinder.prerender();
 }
 
 struct MainPanel : public LLPanel
@@ -2256,6 +2260,10 @@ void LLViewerWindow::drawDebugText()
 	gGL.color4f(1,1,1,1);
 	gGL.pushMatrix();
 	gGL.pushUIMatrix();
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		gUIProgram.bind();
+	}
 	{
 		// scale view by UI global scale factor and aspect ratio correction factor
 		gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f);
@@ -2265,6 +2273,10 @@ void LLViewerWindow::drawDebugText()
 	gGL.popMatrix();
 
 	gGL.flush();
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		gUIProgram.unbind();
+	}
 }
 
 void LLViewerWindow::draw()
@@ -2279,9 +2291,9 @@ void LLViewerWindow::draw()
 
 	LLUI::setLineWidth(1.f);
 	// Reset any left-over transforms
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	
-	glLoadIdentity();
+	gGL.loadIdentity();
 
 	//S32 screen_x, screen_y;
 
@@ -2296,7 +2308,7 @@ void LLViewerWindow::draw()
 		// draw timecode block
 		std::string text;
 
-		glLoadIdentity();
+		gGL.loadIdentity();
 
 		microsecondsToTimecodeString(gFrameTime,text);
 		const LLFontGL* font = LLFontGL::getFontSansSerif();
@@ -2332,10 +2344,10 @@ void LLViewerWindow::draw()
 			int pos_y = sub_region / llceil(zoom_factor);
 			int pos_x = sub_region - (pos_y*llceil(zoom_factor));
 			// offset for this tile
-			glTranslatef((F32)getWindowWidthScaled() * -(F32)pos_x, 
+			gGL.translatef((F32)getWindowWidthScaled() * -(F32)pos_x, 
 						(F32)getWindowHeightScaled() * -(F32)pos_y, 
 						0.f);
-			glScalef(zoom_factor, zoom_factor, 1.f);
+			gGL.scalef(zoom_factor, zoom_factor, 1.f);
 			LLUI::sGLScaleFactor *= zoom_factor;
 		}
 
@@ -2364,7 +2376,7 @@ void LLViewerWindow::draw()
 			S32 screen_x, screen_y;
 			top_ctrl->localPointToScreen(0, 0, &screen_x, &screen_y);
 
-			glMatrixMode(GL_MODELVIEW);
+			gGL.matrixMode(LLRender::MM_MODELVIEW);
 			LLUI::pushMatrix();
 			LLUI::translate( (F32) screen_x, (F32) screen_y, 0.f);
 			top_ctrl->draw();	
@@ -3424,17 +3436,17 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
 			LLBBox hud_bbox = gAgentAvatarp->getHUDBBox();
 
 			// set up transform to encompass bounding box of HUD
-			glMatrixMode(GL_PROJECTION);
-			glPushMatrix();
-			glLoadIdentity();
+			gGL.matrixMode(LLRender::MM_PROJECTION);
+			gGL.pushMatrix();
+			gGL.loadIdentity();
 			F32 depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f);
-			glOrtho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, depth);
+			gGL.ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, depth);
 			
-			glMatrixMode(GL_MODELVIEW);
-			glPushMatrix();
-			glLoadIdentity();
-			glLoadMatrixf(OGL_TO_CFR_ROTATION);		// Load Cory's favorite reference frame
-			glTranslatef(-hud_bbox.getCenterLocal().mV[VX] + (depth *0.5f), 0.f, 0.f);
+			gGL.matrixMode(LLRender::MM_MODELVIEW);
+			gGL.pushMatrix();
+			gGL.loadIdentity();
+			gGL.loadMatrix(OGL_TO_CFR_ROTATION);		// Load Cory's favorite reference frame
+			gGL.translatef(-hud_bbox.getCenterLocal().mV[VX] + (depth *0.5f), 0.f, 0.f);
 		}
 
 		// Render light for editing
@@ -3444,12 +3456,12 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
 			LLGLEnable gls_blend(GL_BLEND);
 			LLGLEnable gls_cull(GL_CULL_FACE);
 			LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-			glMatrixMode(GL_MODELVIEW);
-			glPushMatrix();
+			gGL.matrixMode(LLRender::MM_MODELVIEW);
+			gGL.pushMatrix();
 			if (selection->getSelectType() == SELECT_TYPE_HUD)
 			{
 				F32 zoom = gAgentCamera.mHUDCurZoom;
-				glScalef(zoom, zoom, zoom);
+				gGL.scalef(zoom, zoom, zoom);
 			}
 
 			struct f : public LLSelectedObjectFunctor
@@ -3460,33 +3472,33 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
 					if (drawable && drawable->isLight())
 					{
 						LLVOVolume* vovolume = drawable->getVOVolume();
-						glPushMatrix();
+						gGL.pushMatrix();
 
 						LLVector3 center = drawable->getPositionAgent();
-						glTranslatef(center[0], center[1], center[2]);
+						gGL.translatef(center[0], center[1], center[2]);
 						F32 scale = vovolume->getLightRadius();
-						glScalef(scale, scale, scale);
+						gGL.scalef(scale, scale, scale);
 
 						LLColor4 color(vovolume->getLightColor(), .5f);
-						glColor4fv(color.mV);
+						gGL.color4fv(color.mV);
 					
-						F32 pixel_area = 100000.f;
+						//F32 pixel_area = 100000.f;
 						// Render Outside
-						gSphere.render(pixel_area);
+						gSphere.render();
 
 						// Render Inside
 						glCullFace(GL_FRONT);
-						gSphere.render(pixel_area);
+						gSphere.render();
 						glCullFace(GL_BACK);
 					
-						glPopMatrix();
+						gGL.popMatrix();
 					}
 					return true;
 				}
 			} func;
 			LLSelectMgr::getInstance()->getSelection()->applyToObjects(&func);
 			
-			glPopMatrix();
+			gGL.popMatrix();
 		}				
 		
 		// NOTE: The average position for the axis arrows of the selected objects should
@@ -3549,11 +3561,11 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
 			}
 			if (selection->getSelectType() == SELECT_TYPE_HUD && selection->getObjectCount())
 			{
-				glMatrixMode(GL_PROJECTION);
-				glPopMatrix();
+				gGL.matrixMode(LLRender::MM_PROJECTION);
+				gGL.popMatrix();
 
-				glMatrixMode(GL_MODELVIEW);
-				glPopMatrix();
+				gGL.matrixMode(LLRender::MM_MODELVIEW);
+				gGL.popMatrix();
 				stop_glerror();
 			}
 		}
@@ -4667,10 +4679,7 @@ void LLViewerWindow::stopGL(BOOL save_state)
 			gPipeline.destroyGL();
 		}
 		
-		gCone.cleanupGL();
 		gBox.cleanupGL();
-		gSphere.cleanupGL();
-		gCylinder.cleanupGL();
 		
 		if(gPostProcess)
 		{
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index bdab250b49c5db324149bdb17a1bcae838e3ec05..799e1bbfb962d63321f4101e349594b18749613d 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -2117,8 +2117,8 @@ void LLVOAvatar::updateMeshData()
 			}
 			else
 			{
-				if (buff->getRequestedIndices() == num_indices &&
-					buff->getRequestedVerts() == num_vertices)
+				if (buff->getNumIndices() == num_indices &&
+					buff->getNumVerts() == num_vertices)
 				{
 					terse_update = true;
 				}
@@ -2142,7 +2142,7 @@ void LLVOAvatar::updateMeshData()
 			}
 
 			stop_glerror();
-			buff->setBuffer(0);
+			buff->flush();
 
 			if(!f_num)
 			{
@@ -4135,7 +4135,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
 			LLVertexBuffer* vb = mDrawable->getFace(0)->getVertexBuffer();
 			if (vb)
 			{
-				vb->setBuffer(0);
+				vb->flush();
 			}
 		}
 	}
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 59883e0bb19be9867331c0a0c9194a5603d2dd10..581912f8449141948e6672845785fc6221a199be 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -2558,7 +2558,7 @@ void LLVOAvatarSelf::deleteScratchTextures()
 			LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
 			total_tex_size -= tex_size ;
 		}
-		if( sScratchTexNames.checkData( GL_LUMINANCE_ALPHA ) )
+		if( sScratchTexNames.checkData( LLRender::sGLCoreProfile ? GL_RG : GL_LUMINANCE_ALPHA ) )
 		{
 			LLImageGL::decTextureCounter(tex_size, 2, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
 			total_tex_size -= 2 * tex_size ;
@@ -2600,89 +2600,6 @@ void LLVOAvatarSelf::deleteScratchTextures()
 	}
 }
 
-BOOL LLVOAvatarSelf::bindScratchTexture( LLGLenum format )
-{
-	U32 texture_bytes = 0;
-	S32 components = 0; 
-	GLuint gl_name = getScratchTexName( format, components, &texture_bytes );
-	if( gl_name )
-	{
-		gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, gl_name);
-		stop_glerror();
-
-		F32* last_bind_time = sScratchTexLastBindTime.getIfThere( format );
-		if( last_bind_time )
-		{
-			if( *last_bind_time != LLImageGL::sLastFrameTime )
-			{
-				*last_bind_time = LLImageGL::sLastFrameTime;
-				LLImageGL::updateBoundTexMem(texture_bytes, components, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
-			}
-		}
-		else
-		{
-			LLImageGL::updateBoundTexMem(texture_bytes, components, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
-			sScratchTexLastBindTime.addData( format, new F32(LLImageGL::sLastFrameTime) );
-		}
-		return TRUE;
-	}
-	return FALSE;
-}
-
-LLGLuint LLVOAvatarSelf::getScratchTexName( LLGLenum format, S32& components, U32* texture_bytes )
-{	
-	GLenum internal_format;
-	switch( format )
-	{
-		case GL_LUMINANCE:			components = 1; internal_format = GL_LUMINANCE8;		break;
-		case GL_ALPHA:				components = 1; internal_format = GL_ALPHA8;			break;
-		case GL_LUMINANCE_ALPHA:	components = 2; internal_format = GL_LUMINANCE8_ALPHA8;	break;
-		case GL_RGB:				components = 3; internal_format = GL_RGB8;				break;
-		case GL_RGBA:				components = 4; internal_format = GL_RGBA8;				break;
-		default:	llassert(0);	components = 4; internal_format = GL_RGBA8;				break;
-	}
-
-	*texture_bytes = components * SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT;
-	
-	if( sScratchTexNames.checkData( format ) )
-	{
-		return *( sScratchTexNames.getData( format ) );
-	}
-
-	LLGLSUIDefault gls_ui;
-
-	U32 name = 0;
-	LLImageGL::generateTextures(1, &name );
-	stop_glerror();
-
-	gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, name);
-	stop_glerror();
-
-	LLImageGL::setManualImage(
-		GL_TEXTURE_2D, 0, internal_format, 
-		SCRATCH_TEX_WIDTH, SCRATCH_TEX_HEIGHT,
-		format, GL_UNSIGNED_BYTE, NULL );
-	stop_glerror();
-
-	gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
-	gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
-	stop_glerror();
-
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-	stop_glerror();
-
-	sScratchTexNames.addData( format, new LLGLuint( name ) );
-
-	sScratchTexBytes += *texture_bytes;
-	LLImageGL::sGlobalTextureMemoryInBytes += *texture_bytes;
-
-	if(gAuditTexture)
-	{
-		LLImageGL::incTextureCounter(SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT, components, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
-	}
-	return name;
-}
-
 // static 
 void LLVOAvatarSelf::dumpScratchTextureByteCount()
 {
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index 51f06dee5f5246e3572e1e434c6b8baecaeb14f5..74ff47a3e4b1b57d9487c4e7e52e12fd2f5fbedb 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -249,10 +249,7 @@ class LLVOAvatarSelf :
 	// Scratch textures (used for compositing)
 	//--------------------------------------------------------------------
 public:
-	BOOL			bindScratchTexture(LLGLenum format);
 	static void		deleteScratchTextures();
-protected:
-	LLGLuint		getScratchTexName(LLGLenum format, S32& components, U32* texture_bytes);
 private:
 	static S32 		sScratchTexBytes;
 	static LLMap< LLGLenum, LLGLuint*> sScratchTexNames;
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index 32822e11816fe67772964bcefa5451c33d835e18..8a79d564d3a3dfd7dfdbe65958e0559c51713804 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -464,7 +464,7 @@ void LLVOGrass::plantBlades()
 }
 
 void LLVOGrass::getGeometry(S32 idx,
-								LLStrider<LLVector3>& verticesp,
+								LLStrider<LLVector4a>& verticesp,
 								LLStrider<LLVector3>& normalsp, 
 								LLStrider<LLVector2>& texcoordsp,
 								LLStrider<LLColor4U>& colorsp, 
@@ -516,21 +516,24 @@ void LLVOGrass::getGeometry(S32 idx,
 		position.mV[0]  = mPosition.mV[VX] + x + xf;
 		position.mV[1]  = mPosition.mV[VY] + y + yf;
 		position.mV[2]  = mRegionp->getLand().resolveHeightRegion(position);
-		*verticesp++    = v1 = position + mRegionp->getOriginAgent();
-		*verticesp++    = v1;
+		v1 = position + mRegionp->getOriginAgent();
+		(*verticesp++).load3(v1.mV);
+		(*verticesp++).load3(v1.mV);
 
 
 		position.mV[0] += dzx;
 		position.mV[1] += dzy;
 		position.mV[2] += blade_height;
-		*verticesp++    = v2 = position + mRegionp->getOriginAgent();
-		*verticesp++    = v2;
+		v2 = position + mRegionp->getOriginAgent();
+		(*verticesp++).load3(v2.mV);
+		(*verticesp++).load3(v2.mV);
 
 		position.mV[0]  = mPosition.mV[VX] + x - xf;
 		position.mV[1]  = mPosition.mV[VY] + y - xf;
 		position.mV[2]  = mRegionp->getLand().resolveHeightRegion(position);
-		*verticesp++    = v3 = position + mRegionp->getOriginAgent();
-		*verticesp++    = v3;
+		v3 = position + mRegionp->getOriginAgent();
+		(*verticesp++).load3(v3.mV);
+		(*verticesp++).load3(v3.mV);
 
 		LLVector3 normal1 = (v1-v2) % (v2-v3);
 		normal1.mV[VZ] = 0.75f;
@@ -541,8 +544,9 @@ void LLVOGrass::getGeometry(S32 idx,
 		position.mV[0] += dzx;
 		position.mV[1] += dzy;
 		position.mV[2] += blade_height;
-		*verticesp++    = v1 = position + mRegionp->getOriginAgent();
-		*verticesp++    = v1;
+		v1 = position + mRegionp->getOriginAgent();
+		(*verticesp++).load3(v1.mV);
+		(*verticesp++).load3(v1.mV);
 
 		*(normalsp++)   = normal1;
 		*(normalsp++)   = normal2;
diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h
index c262fdcc798ccc922f3cb3903485b7d4fa10d65b..00a59facf742658131024510d544e499c6fa362e 100644
--- a/indra/newview/llvograss.h
+++ b/indra/newview/llvograss.h
@@ -59,7 +59,7 @@ class LLVOGrass : public LLAlphaObject
 	/*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
 	/*virtual*/ BOOL		updateGeometry(LLDrawable *drawable);
 	/*virtual*/ void		getGeometry(S32 idx,
-								LLStrider<LLVector3>& verticesp,
+								LLStrider<LLVector4a>& verticesp,
 								LLStrider<LLVector3>& normalsp, 
 								LLStrider<LLVector2>& texcoordsp,
 								LLStrider<LLColor4U>& colorsp, 
diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp
index ce256fdedf47371272a636bd6a931441f6f88b2b..0060f81ab5043f5235b6b1fd0ae03e868c9a515a 100644
--- a/indra/newview/llvoground.cpp
+++ b/indra/newview/llvoground.cpp
@@ -162,7 +162,7 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable)
 	*(texCoordsp++) = LLVector2(0.f, 1.f);
 	*(texCoordsp++) = LLVector2(0.5f, 0.5f);
 	
-	face->getVertexBuffer()->setBuffer(0);
+	face->getVertexBuffer()->flush();
 	LLPipeline::sCompiles++;
 	return TRUE;
 }
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index a4b0910c926c0abb839fcc7f4d097e43077cfccf..5c10a80b07380af65c80c7e7f57bd713261d0972 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -274,7 +274,7 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
 }
 
 void LLVOPartGroup::getGeometry(S32 idx,
-								LLStrider<LLVector3>& verticesp,
+								LLStrider<LLVector4a>& verticesp,
 								LLStrider<LLVector3>& normalsp, 
 								LLStrider<LLVector2>& texcoordsp,
 								LLStrider<LLColor4U>& colorsp, 
@@ -290,37 +290,54 @@ void LLVOPartGroup::getGeometry(S32 idx,
 	U32 vert_offset = mDrawable->getFace(idx)->getGeomIndex();
 
 	
-	LLVector3 part_pos_agent(part.mPosAgent);
-	LLVector3 camera_agent = getCameraPosition(); 
-	LLVector3 at = part_pos_agent - camera_agent;
-	LLVector3 up;
-	LLVector3 right;
-
-	right = at % LLVector3(0.f, 0.f, 1.f);
-	right.normalize();
-	up = right % at;
-	up.normalize();
+	LLVector4a part_pos_agent;
+	part_pos_agent.load3(part.mPosAgent.mV);
+	LLVector4a camera_agent;
+	camera_agent.load3(getCameraPosition().mV); 
+	LLVector4a at;
+	at.setSub(part_pos_agent, camera_agent);
+	LLVector4a up(0, 0, 1);
+	LLVector4a right;
+
+	right.setCross3(at, up);
+	right.normalize3fast();
+	up.setCross3(right, at);
+	up.normalize3fast();
 
 	if (part.mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK)
 	{
-		LLVector3 normvel = part.mVelocity;
-		normvel.normalize();
+		LLVector4a normvel;
+		normvel.load3(part.mVelocity.mV);
+		normvel.normalize3fast();
 		LLVector2 up_fracs;
-		up_fracs.mV[0] = normvel*right;
-		up_fracs.mV[1] = normvel*up;
+		up_fracs.mV[0] = normvel.dot3(right).getF32();
+		up_fracs.mV[1] = normvel.dot3(up).getF32();
 		up_fracs.normalize();
-		LLVector3 new_up;
-		LLVector3 new_right;
-		new_up = up_fracs.mV[0] * right + up_fracs.mV[1]*up;
-		new_right = up_fracs.mV[1] * right - up_fracs.mV[0]*up;
+		LLVector4a new_up;
+		LLVector4a new_right;
+
+		//new_up = up_fracs.mV[0] * right + up_fracs.mV[1]*up;
+		LLVector4a t = right;
+		t.mul(up_fracs.mV[0]);
+		new_up = up;
+		new_up.mul(up_fracs.mV[1]);
+		new_up.add(t);
+
+		//new_right = up_fracs.mV[1] * right - up_fracs.mV[0]*up;
+		t = right;
+		t.mul(up_fracs.mV[1]);
+		new_right = up;
+		new_right.mul(up_fracs.mV[0]);
+		t.sub(new_right);
+
 		up = new_up;
-		right = new_right;
-		up.normalize();
-		right.normalize();
+		right = t;
+		up.normalize3fast();
+		right.normalize3fast();
 	}
 
-	right *= 0.5f*part.mScale.mV[0];
-	up *= 0.5f*part.mScale.mV[1];
+	right.mul(0.5f*part.mScale.mV[0]);
+	up.mul(0.5f*part.mScale.mV[1]);
 
 
 	LLVector3 normal = -LLViewerCamera::getInstance()->getXAxis();
@@ -329,14 +346,25 @@ void LLVOPartGroup::getGeometry(S32 idx,
 	// this works because there is actually a 4th float stored after the vertex position which is used as a texture index
 	// also, somebody please VECTORIZE THIS
 
-	verticesp->mV[3] = 0.f;
-	*verticesp++ = part_pos_agent + up - right;
-	verticesp->mV[3] = 0.f;
-	*verticesp++ = part_pos_agent - up - right;
-	verticesp->mV[3] = 0.f;
-	*verticesp++ = part_pos_agent + up + right;
-	verticesp->mV[3] = 0.f;
-	*verticesp++ = part_pos_agent - up + right;
+	LLVector4a ppapu;
+	LLVector4a ppamu;
+
+	ppapu.setAdd(part_pos_agent, up);
+	ppamu.setSub(part_pos_agent, up);
+
+	verticesp->setSub(ppapu, right);
+	(*verticesp++).getF32ptr()[3] = 0.f;
+	verticesp->setSub(ppamu, right);
+	(*verticesp++).getF32ptr()[3] = 0.f;
+	verticesp->setAdd(ppapu, right);
+	(*verticesp++).getF32ptr()[3] = 0.f;
+	verticesp->setAdd(ppamu, right);
+	(*verticesp++).getF32ptr()[3] = 0.f;
+
+	//*verticesp++ = part_pos_agent + up - right;
+	//*verticesp++ = part_pos_agent - up - right;
+	//*verticesp++ = part_pos_agent + up + right;
+	//*verticesp++ = part_pos_agent - up + right;
 
 	*colorsp++ = part.mColor;
 	*colorsp++ = part.mColor;
@@ -453,7 +481,7 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
 	LLVertexBuffer* buffer = group->mVertexBuffer;
 
 	LLStrider<U16> indicesp;
-	LLStrider<LLVector3> verticesp;
+	LLStrider<LLVector4a> verticesp;
 	LLStrider<LLVector3> normalsp;
 	LLStrider<LLVector2> texcoordsp;
 	LLStrider<LLColor4U> colorsp;
@@ -513,7 +541,7 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
 		}
 	}
 
-	buffer->setBuffer(0);
+	buffer->flush();
 	mFaceList.clear();
 }
 
diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h
index 4db893b4ef7f47580409446876fd30d386ebf5b6..e58fed86d969ff10d55bf800d3d3bdc1ee306ac4 100644
--- a/indra/newview/llvopartgroup.h
+++ b/indra/newview/llvopartgroup.h
@@ -60,7 +60,7 @@ class LLVOPartGroup : public LLAlphaObject
 	/*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
 	/*virtual*/ BOOL        updateGeometry(LLDrawable *drawable);
 				void		getGeometry(S32 idx,
-								LLStrider<LLVector3>& verticesp,
+								LLStrider<LLVector4a>& verticesp,
 								LLStrider<LLVector3>& normalsp, 
 								LLStrider<LLVector2>& texcoordsp,
 								LLStrider<LLColor4U>& colorsp, 
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index ef21e7373e48a0e51890ef919a12d9a56183182a..e9db37821b1895ee29c0cccb0877da2be45f33b9 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -1267,7 +1267,7 @@ void LLVOSky::updateDummyVertexBuffer()
 	LLStrider<LLVector3> vertices ;
 	mFace[FACE_DUMMY]->getVertexBuffer()->getVertexStrider(vertices,  0);
 	*vertices = mCameraPosAgent ;
-	mFace[FACE_DUMMY]->getVertexBuffer()->setBuffer(0) ;
+	mFace[FACE_DUMMY]->getVertexBuffer()->flush();
 }
 //----------------------------------
 //end of fake vertex buffer updating
@@ -1351,7 +1351,7 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
 			*indicesp++ = index_offset + 3;
 			*indicesp++ = index_offset + 2;
 
-			buff->setBuffer(0);
+			buff->flush();
 		}
 	}
 
@@ -1516,7 +1516,7 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons
 	*indicesp++ = index_offset + 2;
 	*indicesp++ = index_offset + 3;
 
-	facep->getVertexBuffer()->setBuffer(0);
+	facep->getVertexBuffer()->flush();
 
 	if (is_sun)
 	{
@@ -2030,7 +2030,7 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
 		}
 	}
 
-	face->getVertexBuffer()->setBuffer(0);
+	face->getVertexBuffer()->flush();
 }
 
 
@@ -2040,9 +2040,12 @@ void LLVOSky::updateFog(const F32 distance)
 {
 	if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG))
 	{
-		glFogf(GL_FOG_DENSITY, 0);
-		glFogfv(GL_FOG_COLOR, (F32 *) &LLColor4::white.mV);
-		glFogf(GL_FOG_END, 1000000.f);
+		if (!LLGLSLShader::sNoFixedFunction)
+		{
+			glFogf(GL_FOG_DENSITY, 0);
+			glFogfv(GL_FOG_COLOR, (F32 *) &LLColor4::white.mV);
+			glFogf(GL_FOG_END, 1000000.f);
+		}
 		return;
 	}
 
@@ -2112,7 +2115,10 @@ void LLVOSky::updateFog(const F32 distance)
 	if (camera_height > water_height)
 	{
 		LLColor4 fog(render_fog_color);
-		glFogfv(GL_FOG_COLOR, fog.mV);
+		if (!LLGLSLShader::sNoFixedFunction)
+		{
+			glFogfv(GL_FOG_COLOR, fog.mV);
+		}
 		mGLFogCol = fog;
 
 		if (hide_clip_plane)
@@ -2120,13 +2126,19 @@ void LLVOSky::updateFog(const F32 distance)
 			// For now, set the density to extend to the cull distance.
 			const F32 f_log = 2.14596602628934723963618357029f; // sqrt(fabs(log(0.01f)))
 			fog_density = f_log/fog_distance;
-			glFogi(GL_FOG_MODE, GL_EXP2);
+			if (!LLGLSLShader::sNoFixedFunction)
+			{
+				glFogi(GL_FOG_MODE, GL_EXP2);
+			}
 		}
 		else
 		{
 			const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f))
 			fog_density = (f_log)/fog_distance;
-			glFogi(GL_FOG_MODE, GL_EXP);
+			if (!LLGLSLShader::sNoFixedFunction)
+			{
+				glFogi(GL_FOG_MODE, GL_EXP);
+			}
 		}
 	}
 	else
@@ -2146,23 +2158,29 @@ void LLVOSky::updateFog(const F32 distance)
 		fogCol.setAlpha(1);
 
 		// set the gl fog color
-		glFogfv(GL_FOG_COLOR, (F32 *) &fogCol.mV);
 		mGLFogCol = fogCol;
 
 		// set the density based on what the shaders use
 		fog_density = water_fog_density * gSavedSettings.getF32("WaterGLFogDensityScale");
-		glFogi(GL_FOG_MODE, GL_EXP2);
+
+		if (!LLGLSLShader::sNoFixedFunction)
+		{
+			glFogfv(GL_FOG_COLOR, (F32 *) &fogCol.mV);
+			glFogi(GL_FOG_MODE, GL_EXP2);
+		}
 	}
 
 	mFogColor = sky_fog_color;
 	mFogColor.setAlpha(1);
-	LLGLSFog gls_fog;
+	LLDrawPoolWater::sWaterFogEnd = fog_distance*2.2f;
 
-	glFogf(GL_FOG_END, fog_distance*2.2f);
-
-	glFogf(GL_FOG_DENSITY, fog_density);
-
-	glHint(GL_FOG_HINT, GL_NICEST);
+	if (!LLGLSLShader::sNoFixedFunction)
+	{
+		LLGLSFog gls_fog;
+		glFogf(GL_FOG_END, fog_distance*2.2f);
+		glFogf(GL_FOG_DENSITY, fog_density);
+		glHint(GL_FOG_HINT, GL_NICEST);
+	}
 	stop_glerror();
 }
 
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index 510525259f4c9a6f64fee619aafb1785880adf12..bc82b0df130f6ea79a3cdadd6354815d82f2684d 100644
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -57,8 +57,14 @@ class LLVertexBufferTerrain : public LLVertexBuffer
 	};
 
 	// virtual
-	void setupVertexBuffer(U32 data_mask) const
+	void setupVertexBuffer(U32 data_mask)
 	{	
+		if (LLGLSLShader::sNoFixedFunction)
+		{ //just use default if shaders are in play
+			LLVertexBuffer::setupVertexBuffer(data_mask & ~(MAP_TEXCOORD2 | MAP_TEXCOORD3));
+			return;
+		}
+
 		U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
 
 		//assume tex coords 2 and 3 are present
@@ -106,20 +112,6 @@ class LLVertexBufferTerrain : public LLVertexBuffer
 			glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR]));
 		}
 		
-		if (data_mask & MAP_WEIGHT)
-		{
-			glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], (void*)(base + mOffsets[TYPE_WEIGHT]));
-		}
-
-		if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1)
-		{
-			glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], (void*)(base+mOffsets[TYPE_WEIGHT4]));
-		}
-
-		if (data_mask & MAP_CLOTHWEIGHT)
-		{
-			glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE,  LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]));
-		}
 		if (data_mask & MAP_VERTEX)
 		{
 			glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
@@ -1130,7 +1122,7 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group)
 		index_offset += facep->getGeomCount();
 	}
 
-	buffer->setBuffer(0);
+	buffer->flush();
 	mFaceList.clear();
 }
 
diff --git a/indra/newview/llvotextbubble.cpp b/indra/newview/llvotextbubble.cpp
deleted file mode 100644
index a92172fe2306ee662a233490a7533d21a6e0628f..0000000000000000000000000000000000000000
--- a/indra/newview/llvotextbubble.cpp
+++ /dev/null
@@ -1,272 +0,0 @@
-/** 
- * @file llvotextbubble.cpp
- * @brief Viewer-object text bubble.
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llvotextbubble.h"
-
-#include "imageids.h"
-#include "llviewercontrol.h"
-#include "llprimitive.h"
-#include "llrendersphere.h"
-
-#include "llbox.h"
-#include "lldrawable.h"
-#include "llface.h"
-#include "llviewertexturelist.h"
-#include "llvolume.h"
-#include "pipeline.h"
-#include "llvector4a.h"
-#include "llviewerregion.h"
-
-LLVOTextBubble::LLVOTextBubble(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
-:	LLAlphaObject(id, pcode, regionp)
-{
-	setScale(LLVector3(1.5f, 1.5f, 0.25f));
-	mbCanSelect = FALSE;
-	mLOD = MIN_LOD;
-	mVolumeChanged = TRUE;
-	setVelocity(LLVector3(0.f, 0.f, 0.75f));
-	LLVolumeParams volume_params;
-	volume_params.setType(LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE);
-	volume_params.setBeginAndEndS(0.f, 1.f);
-	volume_params.setBeginAndEndT(0.f, 1.f);
-	volume_params.setRatio(0.25f, 0.25f);
-	volume_params.setShear(0.f, 0.f);
-	setVolume(volume_params, 0);
-	mColor = LLColor4(1.0f, 0.0f, 0.0f, 1.f);
-	S32 i;
-	for (i = 0; i < getNumTEs(); i++)
-	{
-		setTEColor(i, mColor);
-		setTETexture(i, LLUUID(IMG_DEFAULT));
-	}
-}
-
-
-LLVOTextBubble::~LLVOTextBubble()
-{
-}
-
-
-BOOL LLVOTextBubble::isActive() const
-{
-	return TRUE;
-}
-
-BOOL LLVOTextBubble::idleUpdate(LLAgent &agent, LLWorld	&world, const F64 &time)
-{
-	static LLFastTimer::DeclareTimer ftm("Text Bubble");
-	LLFastTimer t(ftm);
-
-	F32 dt = mUpdateTimer.getElapsedTimeF32();
-	// Die after a few seconds.
-	if (dt > 1.5f)
-	{
-		return FALSE;
-	}
-
-	LLViewerObject::idleUpdate(agent, world, time);
-
-	setScale(0.5f * (1.f+dt) * LLVector3(1.5f, 1.5f, 0.5f));
-
-	F32 alpha = 0.35f*dt;
-
-	LLColor4 color = mColor;
-	color.mV[VALPHA] -= alpha;
-	if (color.mV[VALPHA] <= 0.05f)
-	{
-		return FALSE;
-	}
-	S32 i;
-	for (i = 0; i < getNumTEs(); i++)
-	{
-		setTEColor(i, color);
-		setTEFullbright(i, TRUE);
-	}
-
-	gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
-	return TRUE;
-}
-
-
-void LLVOTextBubble::updateTextures()
-{
-	// Update the image levels of all textures...
-
-	for (U32 i = 0; i < getNumTEs(); i++)
-	{
-		const LLTextureEntry *te = getTE(i);
-		F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT);
-		texel_area_ratio = llclamp(texel_area_ratio, .125f, 16.f);
-		LLViewerTexture *imagep = getTEImage(i);
-		if (imagep)
-		{
-			imagep->addTextureStats(mPixelArea / texel_area_ratio);
-		}
-	}
-}
-
-
-LLDrawable *LLVOTextBubble::createDrawable(LLPipeline *pipeline)
-{
-	pipeline->allocDrawable(this);
-	mDrawable->setLit(FALSE);
-	mDrawable->setRenderType(LLPipeline::RENDER_TYPE_VOLUME);
-	
-	for (U32 i = 0; i < getNumTEs(); i++)
-	{
-		LLViewerTexture *imagep;
-		const LLTextureEntry *texture_entry = getTE(i);
-		imagep = LLViewerTextureManager::getFetchedTexture(texture_entry->getID());
-
-		mDrawable->addFace((LLFacePool*) NULL, imagep);
-	}
-
-	return mDrawable;
-}
-
-// virtual
-BOOL LLVOTextBubble::setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume)
-{
-	if (LLPrimitive::setVolume(volume_params, mLOD))
-	{
-		if (mDrawable)
-		{
-			gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
-			mVolumeChanged = TRUE;
-		}
-		return TRUE;
-	}
-	return FALSE;
-}
-
-
-BOOL LLVOTextBubble::updateLOD()
-{
-	return FALSE;
-}
-
-BOOL LLVOTextBubble::updateGeometry(LLDrawable *drawable)
-{
- 	if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_VOLUME)))
-		return TRUE;
-	
-	if (mVolumeChanged)
-	{
-		LLVolumeParams volume_params = getVolume()->getParams();
-		setVolume(volume_params, 0);
-
-		LLPipeline::sCompiles++;
-
-		drawable->setNumFaces(getVolume()->getNumFaces(), drawable->getFace(0)->getPool(), getTEImage(0));
-	}
-
-	LLMatrix4 identity4;
-	LLMatrix3 identity3;
-	for (S32 i = 0; i < drawable->getNumFaces(); i++)
-	{
-		LLFace *face = drawable->getFace(i);
-		face->setTEOffset(i);
-		face->setTexture(LLViewerFetchedTexture::sSmokeImagep);
-		face->setState(LLFace::FULLBRIGHT);
-	}
-
-	mVolumeChanged = FALSE;
-
-	mDrawable->movePartition();
-	return TRUE;
-}
-
-void LLVOTextBubble::updateFaceSize(S32 idx)
-{
-	LLFace* face = mDrawable->getFace(idx);
-	
-	if (idx == 0 || idx == 2)
-	{
-		face->setSize(0,0);
-	}
-	else
-	{
-		const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx);
-		face->setSize(vol_face.mNumVertices, vol_face.mNumIndices);
-	}
-}
-
-void LLVOTextBubble::getGeometry(S32 idx,
-								LLStrider<LLVector3>& verticesp,
-								LLStrider<LLVector3>& normalsp, 
-								LLStrider<LLVector2>& texcoordsp,
-								LLStrider<LLColor4U>& colorsp, 
-								LLStrider<U16>& indicesp) 
-{
-	if (idx == 0 || idx == 2)
-	{
-		return;
-	}
-
-	const LLVolumeFace& face = getVolume()->getVolumeFace(idx);
-	
-	LLVector4a pos;
-	pos.load3(getPositionAgent().mV);
-
-	LLVector4a scale;
-	scale.load3(getScale().mV);
-
-	LLColor4U color = LLColor4U(getTE(idx)->getColor());
-	U32 offset = mDrawable->getFace(idx)->getGeomIndex();
-	
-	LLVector4a* dst_pos = (LLVector4a*) verticesp.get();
-	LLVector4a* src_pos = (LLVector4a*) face.mPositions;
-	
-	LLVector4a* dst_norm = (LLVector4a*) normalsp.get();
-	LLVector4a* src_norm  = (LLVector4a*) face.mNormals;
-	
-	LLVector2* dst_tc = (LLVector2*) texcoordsp.get();
-	LLVector2* src_tc = (LLVector2*) face.mTexCoords;
-
-	LLVector4a::memcpyNonAliased16((F32*) dst_norm, (F32*) src_norm, face.mNumVertices*4*sizeof(F32));
-	LLVector4a::memcpyNonAliased16((F32*) dst_tc, (F32*) src_tc, face.mNumVertices*2*sizeof(F32));
-	
-	
-	for (U32 i = 0; i < face.mNumVertices; i++)
-	{
-		LLVector4a t;
-		t.setMul(src_pos[i], scale);
-		dst_pos[i].setAdd(t, pos);
-		*colorsp++ = color;
-	}
-	
-	for (U32 i = 0; i < face.mNumIndices; i++)
-	{
-		*indicesp++ = face.mIndices[i] + offset;
-	}
-}
-
-U32 LLVOTextBubble::getPartitionType() const
-{ 
-	return LLViewerRegion::PARTITION_PARTICLE; 
-}
diff --git a/indra/newview/llvotextbubble.h b/indra/newview/llvotextbubble.h
deleted file mode 100644
index 9c39929711b1275e1c91eb90fc38faa05cbe4996..0000000000000000000000000000000000000000
--- a/indra/newview/llvotextbubble.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/** 
- * @file llvotextbubble.h
- * @brief Description of LLVORock class, which a derivation of LLViewerObject
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLVOTEXTBUBBLE_H
-#define LL_LLVOTEXTBUBBLE_H
-
-#include "llviewerobject.h"
-#include "llframetimer.h"
-
-class LLVOTextBubble : public LLAlphaObject
-{
-public:
-	LLVOTextBubble(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
-
-	/*virtual*/ BOOL    isActive() const; // Whether this object needs to do an idleUpdate.
-	/*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
-
-	/*virtual*/ void updateTextures();
-	/*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
-	/*virtual*/ BOOL		updateGeometry(LLDrawable *drawable);
-	/*virtual*/ BOOL		updateLOD();
-	/*virtual*/ void		updateFaceSize(S32 idx);
-	
-	/*virtual*/ void		getGeometry(S32 idx,
-								LLStrider<LLVector3>& verticesp,
-								LLStrider<LLVector3>& normalsp, 
-								LLStrider<LLVector2>& texcoordsp,
-								LLStrider<LLColor4U>& colorsp, 
-								LLStrider<U16>& indicesp);
-
-	virtual U32 getPartitionType() const;
-
-	LLColor4 mColor;
-	S32 mLOD;
-	BOOL mVolumeChanged;
-
-protected:
-	~LLVOTextBubble();
-	BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false);
-	LLFrameTimer mUpdateTimer;
-};
-
-#endif // LL_VO_TEXT_BUBBLE
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 890861df71fa2bfe79afc48848dc47bf7ea0d822..6486fd24ea4ba12682f91b2a09728038fde37413 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -858,7 +858,7 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
 			slices /= 2; 
 		}
 
-		mReferenceBuffer->setBuffer(0);
+		mReferenceBuffer->flush();
 		llassert(vertex_count == max_vertices);
 		llassert(index_count == max_indices);
 	}
@@ -882,7 +882,7 @@ void LLVOTree::updateMesh()
 	
 	// Translate to tree base  HACK - adjustment in Z plants tree underground
 	const LLVector3 &pos_agent = getPositionAgent();
-	//glTranslatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f);
+	//gGL.translatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f);
 	LLMatrix4 trans_mat;
 	trans_mat.setTranslation(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f);
 	trans_mat *= matrix;
@@ -940,8 +940,8 @@ void LLVOTree::updateMesh()
 
 	genBranchPipeline(vertices, normals, tex_coords, indices, idx_offset, scale_mat, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, 1.0, mTwist, droop, mBranches, alpha);
 	
-	mReferenceBuffer->setBuffer(0);
-	buff->setBuffer(0);
+	mReferenceBuffer->flush();
+	buff->flush();
 }
 
 void LLVOTree::appendMesh(LLStrider<LLVector3>& vertices, 
@@ -1158,7 +1158,8 @@ U32 LLVOTree::drawBranchPipeline(LLMatrix4& matrix, U16* indicesp, S32 trunk_LOD
 				scale_mat.mMatrix[2][2] = scale*length;
 				scale_mat *= matrix;
 
-				glLoadMatrixf((F32*) scale_mat.mMatrix);
+				gGL.loadMatrix((F32*) scale_mat.mMatrix);
+				gGL.syncMatrices();
  				glDrawElements(GL_TRIANGLES, sLODIndexCount[trunk_LOD], GL_UNSIGNED_SHORT, indicesp + sLODIndexOffset[trunk_LOD]);
 				gPipeline.addTrianglesDrawn(LEAF_INDICES);
 				stop_glerror();
@@ -1208,7 +1209,8 @@ U32 LLVOTree::drawBranchPipeline(LLMatrix4& matrix, U16* indicesp, S32 trunk_LOD
 				scale_mat *= matrix;
 
 			
-				glLoadMatrixf((F32*) scale_mat.mMatrix);
+				gGL.loadMatrix((F32*) scale_mat.mMatrix);
+				gGL.syncMatrices();
 				glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_SHORT, indicesp);
 				gPipeline.addTrianglesDrawn(LEAF_INDICES);							
 				stop_glerror();
@@ -1229,19 +1231,20 @@ U32 LLVOTree::drawBranchPipeline(LLMatrix4& matrix, U16* indicesp, S32 trunk_LOD
 
 		scale_mat *= matrix;
 	
-		glMatrixMode(GL_TEXTURE);
-		glTranslatef(0.0, -0.5, 0.0);
-		glMatrixMode(GL_MODELVIEW);
+		gGL.matrixMode(LLRender::MM_TEXTURE);
+		gGL.translatef(0.0, -0.5, 0.0);
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
 					
-		glLoadMatrixf((F32*) scale_mat.mMatrix);
+		gGL.loadMatrix((F32*) scale_mat.mMatrix);
+		gGL.syncMatrices();
 		glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_SHORT, indicesp);
 		gPipeline.addTrianglesDrawn(LEAF_INDICES);
 		stop_glerror();
 		ret += LEAF_INDICES;
 
-		glMatrixMode(GL_TEXTURE);
-		glLoadIdentity();
-		glMatrixMode(GL_MODELVIEW);
+		gGL.matrixMode(LLRender::MM_TEXTURE);
+		gGL.loadIdentity();
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
 	}
 
 	return ret;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 380d63c77b977ce713c188cb315628383e219fa1..b75a0a799a2f1d3f464fe9b7abe8a2adc8668661 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -3976,8 +3976,6 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 		}
 	}
 	
-	U8 glow = (U8) (facep->getTextureEntry()->getGlow() * 255);
-
 	if (idx >= 0 && 
 		draw_vec[idx]->mVertexBuffer == facep->getVertexBuffer() &&
 		draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&
@@ -3986,7 +3984,6 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 		draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange &&
 		draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
 #endif
-		draw_vec[idx]->mGlowColor.mV[3] == glow &&
 		draw_vec[idx]->mFullbright == fullbright &&
 		draw_vec[idx]->mBump == bump &&
 		draw_vec[idx]->mTextureMatrix == tex_mat &&
@@ -4018,7 +4015,6 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 		draw_vec.push_back(draw_info);
 		draw_info->mTextureMatrix = tex_mat;
 		draw_info->mModelMatrix = model_mat;
-		draw_info->mGlowColor.setVec(0,0,0,glow);
 		if (type == LLRenderPass::PASS_ALPHA)
 		{ //for alpha sorting
 			facep->setDrawInfo(draw_info);
@@ -4118,6 +4114,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 
 	U32 cur_total = 0;
 
+	bool emissive = false;
+
 	//get all the faces into a list
 	for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
 	{
@@ -4330,6 +4328,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 				}
 			}
 
+
 			if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0)
 			{
 				facep->clearVertexBuffer();
@@ -4343,6 +4342,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 				const LLTextureEntry* te = facep->getTextureEntry();
 				LLViewerTexture* tex = facep->getTexture();
 
+				if (te->getGlow() >= 1.f/255.f)
+				{
+					emissive = true;
+				}
+
 				if (facep->isState(LLFace::TEXTURE_ANIM))
 				{
 					if (!vobj->mTexAnimMode)
@@ -4459,6 +4463,14 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 	U32 bump_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
 	U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
 
+	if (emissive)
+	{ //emissive faces are present, include emissive byte to preserve batching
+		simple_mask = simple_mask | LLVertexBuffer::MAP_EMISSIVE;
+		alpha_mask = alpha_mask | LLVertexBuffer::MAP_EMISSIVE;
+		bump_mask = bump_mask | LLVertexBuffer::MAP_EMISSIVE;
+		fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_EMISSIVE;
+	}
+
 	bool batch_textures = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1;
 
 	if (batch_textures)
@@ -4551,7 +4563,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
 		
 		for (std::set<LLVertexBuffer*>::iterator iter = mapped_buffers.begin(); iter != mapped_buffers.end(); ++iter)
 		{
-			(*iter)->setBuffer(0);
+			(*iter)->flush();
 		}
 
 		// don't forget alpha
@@ -4559,7 +4571,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
 		   !group->mVertexBuffer.isNull() && 
 		   group->mVertexBuffer->isLocked())
 		{
-			group->mVertexBuffer->setBuffer(0);
+			group->mVertexBuffer->flush();
 		}
 
 		//if not all buffers are unmapped
@@ -4575,7 +4587,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
 					LLVertexBuffer* buff = face->getVertexBuffer();
 					if (face && buff && buff->isLocked())
 					{
-						buff->setBuffer(0) ;
+						buff->flush();
 					}
 				}
 			} 
@@ -4602,10 +4614,6 @@ struct CompareBatchBreakerModified
 		{
 			return lte->getFullbright() < rte->getFullbright();
 		}
-		else  if (lte->getGlow() != rte->getGlow())
-		{
-			return lte->getGlow() < rte->getGlow();
-		}
 		else
 		{
 			return lhs->getTexture() < rhs->getTexture();
@@ -4658,6 +4666,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
 
 	texture_index_channels = llmin(texture_index_channels, (S32) gSavedSettings.getU32("RenderMaxTextureIndex"));
 	
+	//NEVER use more than 16 texture index channels (workaround for prevalent driver bug)
+	texture_index_channels = llmin(texture_index_channels, 16);
 
 	while (face_iter != faces.end())
 	{
@@ -4985,7 +4995,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
 			++face_iter;
 		}
 
-		buffer->setBuffer(0);
+		buffer->flush();
 	}
 
 	group->mBufferMap[mask].clear();
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index e70ac0a2e747600e753a26b59617e02cd6b0886a..7df50ec81502be1d5f462d160b46fe7f80a7e263 100644
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -160,7 +160,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
 	static const unsigned int vertices_per_quad = 4;
 	static const unsigned int indices_per_quad = 6;
 
-	const S32 size = gSavedSettings.getBOOL("RenderTransparentWater") ? 16 : 1;
+	const S32 size = gSavedSettings.getBOOL("RenderTransparentWater") && !LLGLSLShader::sNoFixedFunction ? 16 : 1;
 
 	const S32 num_quads = size * size;
 	face->setSize(vertices_per_quad * num_quads,
@@ -231,7 +231,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
 		}
 	}
 	
-	buff->setBuffer(0);
+	buff->flush();
 
 	mDrawable->movePartition();
 	LLPipeline::sCompiles++;
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index 7b1c7254832b74fc911713ed8d69b52a5d677822..f1c5499d847ae21af7d7679f7f25a031187c5a5a 100644
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -326,7 +326,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
 
 		buildFanBuffer(vertices, texCoords, indices);
 
-		mFanVerts->setBuffer(0);
+		mFanVerts->flush();
 	}
 
 	{
@@ -349,6 +349,9 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
 
 		mStripsVerts.resize(strips_segments, NULL);
 
+		LLTimer timer;
+		timer.start();
+
 		for (U32 i = 0; i < strips_segments ;++i)
 		{
 			LLVertexBuffer * segment = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
@@ -388,8 +391,10 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
 			buildStripsBuffer(begin_stack, end_stack,  vertices, texCoords, indices);
 
 			// and unlock the buffer
-			segment->setBuffer(0);
+			segment->flush();
 		}
+	
+		llinfos << "completed in " << llformat("%.2f", timer.getElapsedTimeF32()) << "seconds" << llendl;
 	}
 #else
 	mStripsVerts = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
@@ -468,7 +473,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
 		}
 	}
 
-	mStripsVerts->setBuffer(0);
+	mStripsVerts->flush();
 #endif
 
 	updateStarColors();
@@ -485,7 +490,7 @@ void LLVOWLSky::drawStars(void)
 	if (mStarsVerts.notNull())
 	{
 		mStarsVerts->setBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK);
-		mStarsVerts->drawArrays(LLRender::QUADS, 0, getStarsNumVerts()*4);
+		mStarsVerts->drawArrays(LLRender::TRIANGLES, 0, getStarsNumVerts()*4);
 	}
 }
 
@@ -511,13 +516,14 @@ void LLVOWLSky::drawDome(void)
 
 		strips_segment->drawRange(
 			LLRender::TRIANGLE_STRIP, 
-			0, strips_segment->getRequestedVerts()-1, strips_segment->getRequestedIndices(), 
+			0, strips_segment->getNumVerts()-1, strips_segment->getNumIndices(), 
 			0);
-		gPipeline.addTrianglesDrawn(strips_segment->getRequestedIndices(), LLRender::TRIANGLE_STRIP);
+		gPipeline.addTrianglesDrawn(strips_segment->getNumIndices(), LLRender::TRIANGLE_STRIP);
 	}
 
 #else
 	mStripsVerts->setBuffer(data_mask);
+	gGL.syncMatrices();
 	glDrawRangeElements(
 		GL_TRIANGLES,
 		0, mStripsVerts->getNumVerts()-1, mStripsVerts->getNumIndices(),
@@ -771,7 +777,7 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable)
 	if (mStarsVerts.isNull())
 	{
 		mStarsVerts = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK, GL_DYNAMIC_DRAW);
-		mStarsVerts->allocateBuffer(getStarsNumVerts()*4, 0, TRUE);
+		mStarsVerts->allocateBuffer(getStarsNumVerts()*6, 0, TRUE);
 	}
  
 	BOOL success = mStarsVerts->getVertexStrider(verticesp)
@@ -806,19 +812,25 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable)
 		*(verticesp++)  = mStarVertices[vtx];
 		*(verticesp++) = mStarVertices[vtx]+left;
 		*(verticesp++) = mStarVertices[vtx]+left+up;
+		*(verticesp++) = mStarVertices[vtx]+left;
+		*(verticesp++) = mStarVertices[vtx]+left+up;
 		*(verticesp++) = mStarVertices[vtx]+up;
 
 		*(texcoordsp++) = LLVector2(0,0);
 		*(texcoordsp++) = LLVector2(0,1);
 		*(texcoordsp++) = LLVector2(1,1);
+		*(texcoordsp++) = LLVector2(0,1);
+		*(texcoordsp++) = LLVector2(1,1);
 		*(texcoordsp++) = LLVector2(1,0);
 
 		*(colorsp++)    = LLColor4U(mStarColors[vtx]);
 		*(colorsp++)    = LLColor4U(mStarColors[vtx]);
 		*(colorsp++)    = LLColor4U(mStarColors[vtx]);
 		*(colorsp++)    = LLColor4U(mStarColors[vtx]);
+		*(colorsp++)    = LLColor4U(mStarColors[vtx]);
+		*(colorsp++)    = LLColor4U(mStarColors[vtx]);
 	}
 
-	mStarsVerts->setBuffer(0);
+	mStarsVerts->flush();
 	return TRUE;
 }
diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp
index 1a98d4c6c25e6043e947ae43758a60f688b9a3e6..20b34637b8cb1ad4beb2b925c2aca7437b813d32 100644
--- a/indra/newview/llwaterparammanager.cpp
+++ b/indra/newview/llwaterparammanager.cpp
@@ -190,6 +190,7 @@ void LLWaterParamManager::updateShaderUniforms(LLGLSLShader * shader)
 		shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, LLWLParamManager::getInstance()->getRotatedLightDir().mV);
 		shader->uniform3fv("camPosLocal", 1, LLViewerCamera::getInstance()->getOrigin().mV);
 		shader->uniform4fv("waterFogColor", 1, LLDrawPoolWater::sWaterFogColor.mV);
+		shader->uniform1f("waterFogEnd", LLDrawPoolWater::sWaterFogEnd);
 		shader->uniform4fv("waterPlane", 1, mWaterPlane.mV);
 		shader->uniform1f("waterFogDensity", getFogDensity());
 		shader->uniform1f("waterFogKS", mWaterFogKS);
diff --git a/indra/newview/llwlparamset.cpp b/indra/newview/llwlparamset.cpp
index 02d914a8124f5c06b0667deea1b54ba5813e9da9..5bb702503102ecf40259348dc364617dacab301d 100644
--- a/indra/newview/llwlparamset.cpp
+++ b/indra/newview/llwlparamset.cpp
@@ -69,12 +69,18 @@ LLWLParamSet::LLWLParamSet(void) :
 */
 }
 
+static LLFastTimer::DeclareTimer FTM_WL_PARAM_UPDATE("WL Param Update");
+
 void LLWLParamSet::update(LLGLSLShader * shader) const 
 {	
+	LLFastTimer t(FTM_WL_PARAM_UPDATE);
+
 	for(LLSD::map_const_iterator i = mParamValues.beginMap();
 		i != mParamValues.endMap();
 		++i)
 	{
+		
+
 		const std::string& param = i->first;
 		
 		if(	param == "star_brightness" || param == "preset_num" || param == "sun_angle" ||
@@ -91,8 +97,9 @@ void LLWLParamSet::update(LLGLSLShader * shader) const
 			val.mV[1] = F32(i->second[1].asReal()) + mCloudScrollYOffset;
 			val.mV[2] = (F32) i->second[2].asReal();
 			val.mV[3] = (F32) i->second[3].asReal();
-			
-			shader->uniform4fv(param, 1, val.mV);	
+			stop_glerror();
+			shader->uniform4fv(param, 1, val.mV);
+			stop_glerror();
 		} 
 		else // param is the uniform name
 		{
@@ -118,8 +125,9 @@ void LLWLParamSet::update(LLGLSLShader * shader) const
 			{
 				val.mV[0] = i->second.asBoolean();
 			}
-			
+			stop_glerror();
 			shader->uniform4fv(param, 1, val.mV);
+			stop_glerror();
 		}
 	}
 }
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index a7ae456f3ce76923d8da794595e505afd7b462f3..6f6e0d23347d751a7d6d0aabf285c50f8e124f79 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -589,22 +589,22 @@ void LLWorld::updateVisibilities()
 {
 	F32 cur_far_clip = LLViewerCamera::getInstance()->getFar();
 
-	LLViewerCamera::getInstance()->setFar(mLandFarClip);
-
-	F32 diagonal_squared = F_SQRT2 * F_SQRT2 * mWidth * mWidth;
-	// Go through the culled list and check for visible regions
+	// Go through the culled list and check for visible regions (region is visible if land is visible)
 	for (region_list_t::iterator iter = mCulledRegionList.begin();
 		 iter != mCulledRegionList.end(); )
 	{
 		region_list_t::iterator curiter = iter++;
 		LLViewerRegion* regionp = *curiter;
-		F32 height = regionp->getLand().getMaxZ() - regionp->getLand().getMinZ();
-		F32 radius = 0.5f*(F32) sqrt(height * height + diagonal_squared);
-		if (!regionp->getLand().hasZData()
-			|| LLViewerCamera::getInstance()->sphereInFrustum(regionp->getCenterAgent(), radius))
+		
+		LLSpatialPartition* part = regionp->getSpatialPartition(LLViewerRegion::PARTITION_TERRAIN);
+		if (part)
 		{
-			mCulledRegionList.erase(curiter);
-			mVisibleRegionList.push_back(regionp);
+			LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0);
+			if (LLViewerCamera::getInstance()->AABBInFrustum(group->mBounds[0], group->mBounds[1]))
+			{
+				mCulledRegionList.erase(curiter);
+				mVisibleRegionList.push_back(regionp);
+			}
 		}
 	}
 	
@@ -619,17 +619,20 @@ void LLWorld::updateVisibilities()
 			continue;
 		}
 
-		F32 height = regionp->getLand().getMaxZ() - regionp->getLand().getMinZ();
-		F32 radius = 0.5f*(F32) sqrt(height * height + diagonal_squared);
-		if (LLViewerCamera::getInstance()->sphereInFrustum(regionp->getCenterAgent(), radius))
+		LLSpatialPartition* part = regionp->getSpatialPartition(LLViewerRegion::PARTITION_TERRAIN);
+		if (part)
 		{
-			regionp->calculateCameraDistance();
-			regionp->getLand().updatePatchVisibilities(gAgent);
-		}
-		else
-		{
-			mVisibleRegionList.erase(curiter);
-			mCulledRegionList.push_back(regionp);
+			LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0);
+			if (LLViewerCamera::getInstance()->AABBInFrustum(group->mBounds[0], group->mBounds[1]))
+			{
+				regionp->calculateCameraDistance();
+				regionp->getLand().updatePatchVisibilities(gAgent);
+			}
+			else
+			{
+				mVisibleRegionList.erase(curiter);
+				mCulledRegionList.push_back(regionp);
+			}
 		}
 	}
 
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 265d5dc801b51798531e18e8cdb9881e6c0eba23..3959e7c073cec53f6dca51095245aad1004c9c32 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -314,7 +314,7 @@ void LLWorldMapView::draw()
 	{
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
-		glMatrixMode(GL_MODELVIEW);
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
 
 		// Clear the background alpha to 0
 		gGL.flush();
@@ -1307,7 +1307,7 @@ void LLWorldMapView::drawTrackingCircle( const LLRect& rect, S32 x, S32 y, const
 		end_theta -= angle_adjust_y;
 	}
 
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.pushMatrix();
 	gGL.translatef((F32)x, (F32)y, 0.f);
 	gl_washer_segment_2d(inner_radius, outer_radius, start_theta, end_theta, 40, color, color);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index a50f66f2829d46690f2475c5a562f0d8a3ec224c..04edc90be9274939068fe2ea6dd1cf3b33000128 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -106,26 +106,6 @@
 #include "llnotifications.h"
 
 
-void check_stack_depth(S32 stack_depth)
-{
-	if (gDebugGL || gDebugSession)
-	{
-		GLint depth;
-		glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth);
-		if (depth != stack_depth)
-		{
-			if (gDebugSession)
-			{
-				ll_fail("GL matrix stack corrupted.");
-			}
-			else
-			{
-				llerrs << "GL matrix stack corrupted!" << llendl;
-			}
-		}
-	}
-}
-	
 #ifdef _DEBUG
 // Debug indices is disabled for now for debug performance - djs 4/24/02
 //#define DEBUG_INDICES
@@ -133,13 +113,86 @@ void check_stack_depth(S32 stack_depth)
 //#define DEBUG_INDICES
 #endif
 
+//cached settings
+BOOL LLPipeline::RenderAvatarVP;
+BOOL LLPipeline::VertexShaderEnable;
+BOOL LLPipeline::WindLightUseAtmosShaders;
+BOOL LLPipeline::RenderDeferred;
+F32 LLPipeline::RenderDeferredSunWash;
+U32 LLPipeline::RenderFSAASamples;
+U32 LLPipeline::RenderResolutionDivisor;
+BOOL LLPipeline::RenderUIBuffer;
+S32 LLPipeline::RenderShadowDetail;
+BOOL LLPipeline::RenderDeferredSSAO;
+F32 LLPipeline::RenderShadowResolutionScale;
+BOOL LLPipeline::RenderLocalLights;
+BOOL LLPipeline::RenderDelayCreation;
+BOOL LLPipeline::RenderAnimateRes;
+BOOL LLPipeline::FreezeTime;
+S32 LLPipeline::DebugBeaconLineWidth;
+F32 LLPipeline::RenderHighlightBrightness;
+LLColor4 LLPipeline::RenderHighlightColor;
+F32 LLPipeline::RenderHighlightThickness;
+BOOL LLPipeline::RenderSpotLightsInNondeferred;
+LLColor4 LLPipeline::PreviewAmbientColor;
+LLColor4 LLPipeline::PreviewDiffuse0;
+LLColor4 LLPipeline::PreviewSpecular0;
+LLColor4 LLPipeline::PreviewDiffuse1;
+LLColor4 LLPipeline::PreviewSpecular1;
+LLColor4 LLPipeline::PreviewDiffuse2;
+LLColor4 LLPipeline::PreviewSpecular2;
+LLVector3 LLPipeline::PreviewDirection0;
+LLVector3 LLPipeline::PreviewDirection1;
+LLVector3 LLPipeline::PreviewDirection2;
+F32 LLPipeline::RenderGlowMinLuminance;
+F32 LLPipeline::RenderGlowMaxExtractAlpha;
+F32 LLPipeline::RenderGlowWarmthAmount;
+LLVector3 LLPipeline::RenderGlowLumWeights;
+LLVector3 LLPipeline::RenderGlowWarmthWeights;
+S32 LLPipeline::RenderGlowResolutionPow;
+S32 LLPipeline::RenderGlowIterations;
+F32 LLPipeline::RenderGlowWidth;
+F32 LLPipeline::RenderGlowStrength;
+BOOL LLPipeline::RenderDepthOfField;
+F32 LLPipeline::CameraFocusTransitionTime;
+F32 LLPipeline::CameraFNumber;
+F32 LLPipeline::CameraFocalLength;
+F32 LLPipeline::CameraFieldOfView;
+F32 LLPipeline::RenderShadowNoise;
+F32 LLPipeline::RenderShadowBlurSize;
+F32 LLPipeline::RenderSSAOScale;
+U32 LLPipeline::RenderSSAOMaxScale;
+F32 LLPipeline::RenderSSAOFactor;
+LLVector3 LLPipeline::RenderSSAOEffect;
+F32 LLPipeline::RenderShadowOffsetError;
+F32 LLPipeline::RenderShadowBiasError;
+F32 LLPipeline::RenderShadowOffset;
+F32 LLPipeline::RenderShadowBias;
+F32 LLPipeline::RenderSpotShadowOffset;
+F32 LLPipeline::RenderSpotShadowBias;
+F32 LLPipeline::RenderEdgeDepthCutoff;
+F32 LLPipeline::RenderEdgeNormCutoff;
+LLVector3 LLPipeline::RenderShadowGaussian;
+F32 LLPipeline::RenderShadowBlurDistFactor;
+BOOL LLPipeline::RenderDeferredAtmospheric;
+S32 LLPipeline::RenderReflectionDetail;
+F32 LLPipeline::RenderHighlightFadeTime;
+LLVector3 LLPipeline::RenderShadowClipPlanes;
+LLVector3 LLPipeline::RenderShadowOrthoClipPlanes;
+LLVector3 LLPipeline::RenderShadowNearDist;
+F32 LLPipeline::RenderFarClip;
+LLVector3 LLPipeline::RenderShadowSplitExponent;
+F32 LLPipeline::RenderShadowErrorCutoff;
+F32 LLPipeline::RenderShadowFOVCutoff;
+BOOL LLPipeline::CameraOffset;
+
 const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f;
 const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f;
 const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f;
 const F32 BACKLIGHT_NIGHT_MAGNITUDE_OBJECT = 0.08f;
 const S32 MAX_OFFSCREEN_GEOMETRY_CHANGES_PER_FRAME = 10;
 const U32 REFLECTION_MAP_RES = 128;
-
+const U32 DEFERRED_VB_MASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
 // Max number of occluders to search for. JC
 const S32 MAX_OCCLUDER_COUNT = 2;
 
@@ -211,23 +264,12 @@ std::string gPoolNames[] =
 
 void drawBox(const LLVector3& c, const LLVector3& r);
 void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
+U32 nhpo2(U32 v);
 
-U32 nhpo2(U32 v) 
-{
-	U32 r = 1;
-	while (r < v) {
-		r *= 2;
-	}
-	return r;
-}
-
-glh::matrix4f glh_copy_matrix(GLdouble* src)
+glh::matrix4f glh_copy_matrix(F32* src)
 {
 	glh::matrix4f ret;
-	for (U32 i = 0; i < 16; i++)
-	{
-		ret.m[i] = (F32) src[i];
-	}
+	ret.set_value(src);
 	return ret;
 }
 
@@ -251,7 +293,7 @@ glh::matrix4f glh_get_last_projection()
 	return glh_copy_matrix(gGLLastProjection);
 }
 
-void glh_copy_matrix(const glh::matrix4f& src, GLdouble* dst)
+void glh_copy_matrix(const glh::matrix4f& src, F32* dst)
 {
 	for (U32 i = 0; i < 16; i++)
 	{
@@ -394,11 +436,14 @@ void LLPipeline::init()
 {
 	LLMemType mt(LLMemType::MTYPE_PIPELINE_INIT);
 
+	refreshCachedSettings();
+
 	gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity");
 	sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");
 	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
 	sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
 	LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
+	LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseVAO");
 	LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw");
 	sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
 	sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles");
@@ -459,6 +504,8 @@ void LLPipeline::init()
 		mSpotLightFade[i] = 1.f;
 	}
 
+	mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0);
+	mDeferredVB->allocateBuffer(8, 0, true);
 	setLightingDetail(-1);
 }
 
@@ -537,6 +584,8 @@ void LLPipeline::cleanup()
 	mMovedBridge.clear();
 
 	mInitialized = FALSE;
+
+	mDeferredVB = NULL;
 }
 
 //============================================================================
@@ -606,12 +655,7 @@ void LLPipeline::allocatePhysicsBuffer()
 
 void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
 {
-	U32 samples = gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples"));
-
-	if (gGLManager.mIsATI)
-	{ //ATI doesn't like the way we use multisample texture
-		samples = 0;
-	}
+	U32 samples = gGLManager.getNumFBOFSAASamples(RenderFSAASamples);
 
 	//try to allocate screen buffers at requested resolution and samples
 	// - on failure, shrink number of samples and try again
@@ -657,11 +701,14 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
 
 bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
 {
+	refreshCachedSettings();
+	refreshRenderDeferred();
+
 	// remember these dimensions
 	mScreenWidth = resX;
 	mScreenHeight = resY;
 	
-	U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor");
+	U32 res_mod = RenderResolutionDivisor;
 
 	if (res_mod > 1 && res_mod < resX && res_mod < resY)
 	{
@@ -669,7 +716,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
 		resY /= res_mod;
 	}
 
-	if (gSavedSettings.getBOOL("RenderUIBuffer"))
+	if (RenderUIBuffer)
 	{
 		if (!mUIScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE))
 		{
@@ -679,79 +726,40 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
 
 	if (LLPipeline::sRenderDeferred)
 	{
-		S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail");
-		BOOL ssao = gSavedSettings.getBOOL("RenderDeferredSSAO");
-		bool gi = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED);
-
+		S32 shadow_detail = RenderShadowDetail;
+		BOOL ssao = RenderDeferredSSAO;
+		
 		//allocate deferred rendering color buffers
 		if (!mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
 		if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
 		if (!addDeferredAttachments(mDeferredScreen)) return false;
 	
 		if (!mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
-		
-#if LL_DARWIN
-		// As of OS X 10.6.7, Apple doesn't support multiple color formats in a single FBO
-		if (!mEdgeMap.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
-#else
-		if (!mEdgeMap.allocate(resX, resY, GL_ALPHA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
-#endif
-
-		if (shadow_detail > 0 || ssao)
-		{ //only need mDeferredLight[0] for shadows OR ssao
-			if (!mDeferredLight[0].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
-		}
-		else
+		if (samples > 0)
 		{
-			mDeferredLight[0].release();
-		}
-
-		if (ssao)
-		{ //only need mDeferredLight[1] for ssao
-			if (!mDeferredLight[1].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, false)) return false;
+			if (!mFXAABuffer.allocate(nhpo2(resX), nhpo2(resY), GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
 		}
 		else
 		{
-			mDeferredLight[1].release();
+			mFXAABuffer.release();
 		}
-
-		if (gi)
-		{ //only need mDeferredLight[2] and mGIMapPost for gi
-			if (!mDeferredLight[2].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, false)) return false;
-			for (U32 i = 0; i < 2; i++)
-			{
-#if LL_DARWIN
-				// As of OS X 10.6.7, Apple doesn't support multiple color formats in a single FBO
-				if (!mGIMapPost[i].allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE)) return false;
-#else
-				if (!mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE)) return false;
-#endif
-			}
+		
+		if (shadow_detail > 0 || ssao)
+		{ //only need mDeferredLight for shadows OR ssao
+			if (!mDeferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
 		}
 		else
 		{
-			mDeferredLight[2].release();
-		
-			for (U32 i = 0; i < 2; i++)
-			{
-				mGIMapPost[i].release();
-			}
+			mDeferredLight.release();
 		}
 
-		F32 scale = gSavedSettings.getF32("RenderShadowResolutionScale");
-
-#if LL_DARWIN
-		U32 shadow_fmt = 0;
-#else
-		//HACK: make alpha masking work on ATI depth shadows (work around for ATI driver bug)
-		U32 shadow_fmt = gGLManager.mIsATI ? GL_ALPHA : 0;
-#endif
+		F32 scale = RenderShadowResolutionScale;
 
 		if (shadow_detail > 0)
 		{ //allocate 4 sun shadow maps
 			for (U32 i = 0; i < 4; i++)
 			{
-				if (!mShadow[i].allocate(U32(resX*scale),U32(resY*scale), shadow_fmt, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE)) return false;
+				if (!mShadow[i].allocate(U32(resX*scale),U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE)) return false;
 			}
 		}
 		else
@@ -769,7 +777,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
 		{ //allocate two spot shadow maps
 			for (U32 i = 4; i < 6; i++)
 			{
-				if (!mShadow[i].allocate(width, height, shadow_fmt, TRUE, FALSE)) return false;
+				if (!mShadow[i].allocate(width, height, 0, TRUE, FALSE)) return false;
 			}
 		}
 		else
@@ -779,31 +787,20 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
 				mShadow[i].release();
 			}
 		}
-
-		width = nhpo2(resX)/2;
-		height = nhpo2(resY)/2;
-		if (!mLuminanceMap.allocate(width,height, GL_RGBA, FALSE, FALSE)) return false;
 	}
 	else
 	{
-		for (U32 i = 0; i < 3; i++)
-		{ 
-			mDeferredLight[i].release();
-		}
-		for (U32 i = 0; i < 2; i++)
-		{
-			mGIMapPost[i].release();
-		}
+		mDeferredLight.release();
+				
 		for (U32 i = 0; i < 6; i++)
 		{
 			mShadow[i].release();
 		}
+		mFXAABuffer.release();
 		mScreen.release();
 		mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first
 		mDeferredDepth.release();
-		mEdgeMap.release();
-		mLuminanceMap.release();
-		
+						
 		if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;		
 	}
 	
@@ -822,12 +819,12 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
 //static
 void LLPipeline::updateRenderDeferred()
 {
-	BOOL deferred = ((gSavedSettings.getBOOL("RenderDeferred") && 
+	BOOL deferred = ((RenderDeferred && 
 					 LLRenderTarget::sUseFBO &&
-					 LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
-					 gSavedSettings.getBOOL("VertexShaderEnable") && 
-					 gSavedSettings.getBOOL("RenderAvatarVP") &&
-					 gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ? TRUE : FALSE) &&
+					 LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&	 
+					 VertexShaderEnable && 
+					 RenderAvatarVP &&
+					 WindLightUseAtmosShaders) ? TRUE : FALSE) &&
 					!gUseWireframe;
 
 	sRenderDeferred = deferred;	
@@ -843,6 +840,94 @@ void LLPipeline::refreshRenderDeferred()
 	updateRenderDeferred();
 }
 
+//static
+void LLPipeline::refreshCachedSettings()
+{
+	LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred");
+	LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred");
+	LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip");
+	LLVOAvatar::sMaxVisible = (U32)gSavedSettings.getS32("RenderAvatarMaxVisible");
+	LLPipeline::sDelayVBUpdate = gSavedSettings.getBOOL("RenderDelayVBUpdate");
+
+	LLPipeline::sUseOcclusion = 
+			(!gUseWireframe
+			&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") 
+			&& gSavedSettings.getBOOL("UseOcclusion") 
+			&& gGLManager.mHasOcclusionQuery) ? 2 : 0;
+	
+	VertexShaderEnable = gSavedSettings.getBOOL("VertexShaderEnable");
+	RenderAvatarVP = gSavedSettings.getBOOL("RenderAvatarVP");
+	WindLightUseAtmosShaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
+	RenderDeferred = gSavedSettings.getBOOL("RenderDeferred");
+	RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash");
+	RenderFSAASamples = gSavedSettings.getU32("RenderFSAASamples");
+	RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor");
+	RenderUIBuffer = gSavedSettings.getBOOL("RenderUIBuffer");
+	RenderShadowDetail = gSavedSettings.getS32("RenderShadowDetail");
+	RenderDeferredSSAO = gSavedSettings.getBOOL("RenderDeferredSSAO");
+	RenderShadowResolutionScale = gSavedSettings.getF32("RenderShadowResolutionScale");
+	RenderLocalLights = gSavedSettings.getBOOL("RenderLocalLights");
+	RenderDelayCreation = gSavedSettings.getBOOL("RenderDelayCreation");
+	RenderAnimateRes = gSavedSettings.getBOOL("RenderAnimateRes");
+	FreezeTime = gSavedSettings.getBOOL("FreezeTime");
+	DebugBeaconLineWidth = gSavedSettings.getS32("DebugBeaconLineWidth");
+	RenderHighlightBrightness = gSavedSettings.getF32("RenderHighlightBrightness");
+	RenderHighlightColor = gSavedSettings.getColor4("RenderHighlightColor");
+	RenderHighlightThickness = gSavedSettings.getF32("RenderHighlightThickness");
+	RenderSpotLightsInNondeferred = gSavedSettings.getBOOL("RenderSpotLightsInNondeferred");
+	PreviewAmbientColor = gSavedSettings.getColor4("PreviewAmbientColor");
+	PreviewDiffuse0 = gSavedSettings.getColor4("PreviewDiffuse0");
+	PreviewSpecular0 = gSavedSettings.getColor4("PreviewSpecular0");
+	PreviewDiffuse1 = gSavedSettings.getColor4("PreviewDiffuse1");
+	PreviewSpecular1 = gSavedSettings.getColor4("PreviewSpecular1");
+	PreviewDiffuse2 = gSavedSettings.getColor4("PreviewDiffuse2");
+	PreviewSpecular2 = gSavedSettings.getColor4("PreviewSpecular2");
+	PreviewDirection0 = gSavedSettings.getVector3("PreviewDirection0");
+	PreviewDirection1 = gSavedSettings.getVector3("PreviewDirection1");
+	PreviewDirection2 = gSavedSettings.getVector3("PreviewDirection2");
+	RenderGlowMinLuminance = gSavedSettings.getF32("RenderGlowMinLuminance");
+	RenderGlowMaxExtractAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha");
+	RenderGlowWarmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount");
+	RenderGlowLumWeights = gSavedSettings.getVector3("RenderGlowLumWeights");
+	RenderGlowWarmthWeights = gSavedSettings.getVector3("RenderGlowWarmthWeights");
+	RenderGlowResolutionPow = gSavedSettings.getS32("RenderGlowResolutionPow");
+	RenderGlowIterations = gSavedSettings.getS32("RenderGlowIterations");
+	RenderGlowWidth = gSavedSettings.getF32("RenderGlowWidth");
+	RenderGlowStrength = gSavedSettings.getF32("RenderGlowStrength");
+	RenderDepthOfField = gSavedSettings.getBOOL("RenderDepthOfField");
+	CameraFocusTransitionTime = gSavedSettings.getF32("CameraFocusTransitionTime");
+	CameraFNumber = gSavedSettings.getF32("CameraFNumber");
+	CameraFocalLength = gSavedSettings.getF32("CameraFocalLength");
+	CameraFieldOfView = gSavedSettings.getF32("CameraFieldOfView");
+	RenderShadowNoise = gSavedSettings.getF32("RenderShadowNoise");
+	RenderShadowBlurSize = gSavedSettings.getF32("RenderShadowBlurSize");
+	RenderSSAOScale = gSavedSettings.getF32("RenderSSAOScale");
+	RenderSSAOMaxScale = gSavedSettings.getU32("RenderSSAOMaxScale");
+	RenderSSAOFactor = gSavedSettings.getF32("RenderSSAOFactor");
+	RenderSSAOEffect = gSavedSettings.getVector3("RenderSSAOEffect");
+	RenderShadowOffsetError = gSavedSettings.getF32("RenderShadowOffsetError");
+	RenderShadowBiasError = gSavedSettings.getF32("RenderShadowBiasError");
+	RenderShadowOffset = gSavedSettings.getF32("RenderShadowOffset");
+	RenderShadowBias = gSavedSettings.getF32("RenderShadowBias");
+	RenderSpotShadowOffset = gSavedSettings.getF32("RenderSpotShadowOffset");
+	RenderSpotShadowBias = gSavedSettings.getF32("RenderSpotShadowBias");
+	RenderEdgeDepthCutoff = gSavedSettings.getF32("RenderEdgeDepthCutoff");
+	RenderEdgeNormCutoff = gSavedSettings.getF32("RenderEdgeNormCutoff");
+	RenderShadowGaussian = gSavedSettings.getVector3("RenderShadowGaussian");
+	RenderShadowBlurDistFactor = gSavedSettings.getF32("RenderShadowBlurDistFactor");
+	RenderDeferredAtmospheric = gSavedSettings.getBOOL("RenderDeferredAtmospheric");
+	RenderReflectionDetail = gSavedSettings.getS32("RenderReflectionDetail");
+	RenderHighlightFadeTime = gSavedSettings.getF32("RenderHighlightFadeTime");
+	RenderShadowClipPlanes = gSavedSettings.getVector3("RenderShadowClipPlanes");
+	RenderShadowOrthoClipPlanes = gSavedSettings.getVector3("RenderShadowOrthoClipPlanes");
+	RenderShadowNearDist = gSavedSettings.getVector3("RenderShadowNearDist");
+	RenderFarClip = gSavedSettings.getF32("RenderFarClip");
+	RenderShadowSplitExponent = gSavedSettings.getVector3("RenderShadowSplitExponent");
+	RenderShadowErrorCutoff = gSavedSettings.getF32("RenderShadowErrorCutoff");
+	RenderShadowFOVCutoff = gSavedSettings.getF32("RenderShadowFOVCutoff");
+	CameraOffset = gSavedSettings.getBOOL("CameraOffset");
+}
+
 void LLPipeline::releaseGLBuffers()
 {
 	assertInitialized();
@@ -883,21 +968,14 @@ void LLPipeline::releaseScreenBuffers()
 {
 	mUIScreen.release();
 	mScreen.release();
+	mFXAABuffer.release();
 	mPhysicsDisplay.release();
 	mDeferredScreen.release();
 	mDeferredDepth.release();
-	for (U32 i = 0; i < 3; i++)
-	{
-		mDeferredLight[i].release();
-	}
-
-	mEdgeMap.release();
-	mGIMap.release();
-	mGIMapPost[0].release();
-	mGIMapPost[1].release();
-	mHighlight.release();
-	mLuminanceMap.release();
+	mDeferredLight.release();
 	
+	mHighlight.release();
+		
 	for (U32 i = 0; i < 6; i++)
 	{
 		mShadow[i].release();
@@ -907,6 +985,7 @@ void LLPipeline::releaseScreenBuffers()
 
 void LLPipeline::createGLBuffers()
 {
+	stop_glerror();
 	LLMemType mt_cb(LLMemType::MTYPE_PIPELINE_CREATE_BUFFERS);
 	assertInitialized();
 
@@ -1011,18 +1090,12 @@ void LLPipeline::createGLBuffers()
 
 			LLImageGL::generateTextures(1, &mLightFunc);
 			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
-			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_ALPHA, lightResX, lightResY, GL_ALPHA, GL_UNSIGNED_BYTE, lg);
+			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, lg);
 			gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
 			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
 
 			delete [] lg;
 		}
-
-		if (gSavedSettings.getBOOL("RenderDeferredGI"))
-		{
-			mGIMap.allocate(512,512,GL_RGBA, TRUE, FALSE);
-			addDeferredAttachments(mGIMap);
-		}
 	}
 
 	gBumpImageList.restoreGL();
@@ -1126,7 +1199,7 @@ S32 LLPipeline::setLightingDetail(S32 level)
 
 	if (level < 0)
 	{
-		if (gSavedSettings.getBOOL("RenderLocalLights"))
+		if (RenderLocalLights)
 		{
 			level = 1;
 		}
@@ -1447,7 +1520,7 @@ U32 LLPipeline::addObject(LLViewerObject *vobj)
 {
 	LLMemType mt_ao(LLMemType::MTYPE_PIPELINE_ADD_OBJECT);
 
-	if (gSavedSettings.getBOOL("RenderDelayCreation"))
+	if (RenderDelayCreation)
 	{
 		mCreateQ.push_back(vobj);
 	}
@@ -1510,7 +1583,7 @@ void LLPipeline::createObject(LLViewerObject* vobj)
 
 	markRebuild(drawablep, LLDrawable::REBUILD_ALL, TRUE);
 
-	if (drawablep->getVOVolume() && gSavedSettings.getBOOL("RenderAnimateRes"))
+	if (drawablep->getVOVolume() && RenderAnimateRes)
 	{
 		// fun animated res
 		drawablep->updateXform(TRUE);
@@ -1549,7 +1622,7 @@ void LLPipeline::resetFrameStats()
 //external functions for asynchronous updating
 void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep)
 {
-	if (gSavedSettings.getBOOL("FreezeTime"))
+	if (FreezeTime)
 	{
 		return;
 	}
@@ -1579,7 +1652,7 @@ void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep)
 
 void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep)
 {
-	if (gSavedSettings.getBOOL("FreezeTime"))
+	if (FreezeTime)
 	{
 		return;
 	}
@@ -1636,7 +1709,7 @@ void LLPipeline::updateMove()
 	LLFastTimer t(FTM_UPDATE_MOVE);
 	LLMemType mt_um(LLMemType::MTYPE_PIPELINE_UPDATE_MOVE);
 
-	if (gSavedSettings.getBOOL("FreezeTime"))
+	if (FreezeTime)
 	{
 		return;
 	}
@@ -2009,13 +2082,13 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
 		gGL.setColorMask(false, false);
 	}
 
-	glMatrixMode(GL_PROJECTION);
-	glPushMatrix();
-	glLoadMatrixd(gGLLastProjection);
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.pushMatrix();
+	gGL.loadMatrix(gGLLastProjection);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.pushMatrix();
 	gGLLastMatrix = NULL;
-	glLoadMatrixd(gGLLastModelView);
+	gGL.loadMatrix(gGLLastModelView);
 
 
 	LLVertexBuffer::unbind();
@@ -2120,10 +2193,10 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
 	}
 	
 	
-	glMatrixMode(GL_PROJECTION);
-	glPopMatrix();
-	glMatrixMode(GL_MODELVIEW);
-	glPopMatrix();
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.popMatrix();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.popMatrix();
 
 	if (sUseOcclusion > 1)
 	{
@@ -2761,6 +2834,11 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
 			{
 				markVisible(*i, camera);
 			}
+
+			if (!sDelayVBUpdate)
+			{ //rebuild mesh as soon as we know it's visible
+				group->rebuildMesh();
+			}
 		}
 	}
 
@@ -2811,6 +2889,11 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
 		{
 			group->setVisible();
 			stateSort(group, camera);
+
+			if (!sDelayVBUpdate)
+			{ //rebuild mesh as soon as we know it's visible
+				group->rebuildMesh();
+			}
 		}
 	}
 	
@@ -2826,11 +2909,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
 			}
 		}
 	}
-	{
-		LLFastTimer ftm(FTM_CLIENT_COPY);
-		LLVertexBuffer::clientCopy();
-	}
-	
+		
 	postSort(camera);	
 }
 
@@ -2986,7 +3065,7 @@ void renderScriptedBeacons(LLDrawable* drawablep)
 	{
 		if (gPipeline.sRenderBeacons)
 		{
-			gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth"));
+			gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth);
 		}
 
 		if (gPipeline.sRenderHighlight)
@@ -3012,7 +3091,7 @@ void renderScriptedTouchBeacons(LLDrawable* drawablep)
 	{
 		if (gPipeline.sRenderBeacons)
 		{
-			gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth"));
+			gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth);
 		}
 
 		if (gPipeline.sRenderHighlight)
@@ -3037,7 +3116,7 @@ void renderPhysicalBeacons(LLDrawable* drawablep)
 	{
 		if (gPipeline.sRenderBeacons)
 		{
-			gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(0.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth"));
+			gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(0.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth);
 		}
 
 		if (gPipeline.sRenderHighlight)
@@ -3073,7 +3152,7 @@ void renderMOAPBeacons(LLDrawable* drawablep)
 	{
 		if (gPipeline.sRenderBeacons)
 		{
-			gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 1.f, 1.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth"));
+			gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 1.f, 1.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth);
 		}
 
 		if (gPipeline.sRenderHighlight)
@@ -3098,7 +3177,7 @@ void renderParticleBeacons(LLDrawable* drawablep)
 		if (gPipeline.sRenderBeacons)
 		{
 			LLColor4 light_blue(0.5f, 0.5f, 1.f, 0.5f);
-			gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", light_blue, LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth"));
+			gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", light_blue, LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth);
 		}
 
 		if (gPipeline.sRenderHighlight)
@@ -3243,19 +3322,6 @@ void LLPipeline::postSort(LLCamera& camera)
 		
 	if (!sShadowRender)
 	{
-		//sort by texture or bump map
-		for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; ++i)
-		{
-			if (i == LLRenderPass::PASS_BUMP)
-			{
-				std::sort(sCull->beginRenderMap(i), sCull->endRenderMap(i), LLDrawInfo::CompareBump());
-			}
-			else 
-			{
-				std::sort(sCull->beginRenderMap(i), sCull->endRenderMap(i), LLDrawInfo::CompareTexturePtrMatrix());
-			}	
-		}
-
 		std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater());
 	}
 	llpushcallstacks ;
@@ -3304,7 +3370,7 @@ void LLPipeline::postSort(LLCamera& camera)
 				if (gPipeline.sRenderBeacons)
 				{
 					//pos += LLVector3(0.f, 0.f, 0.2f);
-					gObjectList.addDebugBeacon(pos, "", LLColor4(1.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth"));
+					gObjectList.addDebugBeacon(pos, "", LLColor4(1.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), DebugBeaconLineWidth);
 				}
 			}
 			// now deal with highlights for all those seeable sound sources
@@ -3369,7 +3435,7 @@ void render_hud_elements()
 
 	if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
 	{
-		LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0);
+		LLGLEnable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
 		gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d()
 	
 		// Draw the tracking overlays
@@ -3441,10 +3507,10 @@ void LLPipeline::renderHighlights()
 		//gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
 
 		gGL.pushMatrix();
-		glLoadIdentity();
-		glMatrixMode(GL_PROJECTION);
+		gGL.loadIdentity();
+		gGL.matrixMode(LLRender::MM_PROJECTION);
 		gGL.pushMatrix();
-		glLoadIdentity();
+		gGL.loadIdentity();
 
 		gGL.getTexUnit(0)->bind(&mHighlight);
 
@@ -3456,9 +3522,9 @@ void LLPipeline::renderHighlights()
 
 		gGL.begin(LLRender::TRIANGLES);
 				
-		F32 scale = gSavedSettings.getF32("RenderHighlightBrightness");
-		LLColor4 color = gSavedSettings.getColor4("RenderHighlightColor");
-		F32 thickness = gSavedSettings.getF32("RenderHighlightThickness");
+		F32 scale = RenderHighlightBrightness;
+		LLColor4 color = RenderHighlightColor;
+		F32 thickness = RenderHighlightThickness;
 
 		for (S32 pass = 0; pass < 2; ++pass)
 		{
@@ -3504,7 +3570,7 @@ void LLPipeline::renderHighlights()
 		gGL.end();
 
 		gGL.popMatrix();
-		glMatrixMode(GL_MODELVIEW);
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
 		gGL.popMatrix();
 		
 		//gGL.setSceneBlendType(LLRender::BT_ALPHA);
@@ -3513,7 +3579,7 @@ void LLPipeline::renderHighlights()
 	if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
 	{
 		gHighlightProgram.bind();
-		gHighlightProgram.vertexAttrib4f(LLViewerShaderMgr::MATERIAL_COLOR,1,1,1,0.5f);
+		gHighlightProgram.uniform4f(LLShaderMgr::HIGHLIGHT_COLOR,1,1,1,0.5f);
 	}
 	
 	if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED))
@@ -3545,7 +3611,7 @@ void LLPipeline::renderHighlights()
 		color.setVec(1.f, 0.f, 0.f, 0.5f);
 		if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
 		{
-			gHighlightProgram.vertexAttrib4f(LLViewerShaderMgr::MATERIAL_COLOR,1,0,0,0.5f);
+			gHighlightProgram.uniform4f(LLShaderMgr::HIGHLIGHT_COLOR,1,0,0,0.5f);
 		}
 		int count = mHighlightFaces.size();
 		for (S32 i = 0; i < count; i++)
@@ -3575,8 +3641,8 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
 
 	assertInitialized();
 
-	F64 saved_modelview[16];
-	F64 saved_projection[16];
+	F32 saved_modelview[16];
+	F32 saved_projection[16];
 
 	//HACK: preserve/restore matrices around HUD render
 	if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
@@ -3588,13 +3654,6 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
 		}
 	}
 
-	S32 stack_depth = 0;
-
-	if (gDebugGL)
-	{
-		glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &stack_depth);
-	}
-
 	///////////////////////////////////////////
 	//
 	// Sync and verify GL state
@@ -3620,12 +3679,12 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
 	LLAppViewer::instance()->pingMainloopTimeout("Pipeline:ForceVBO");
 	
 	// Initialize lots of GL state to "safe" values
-	glMatrixMode(GL_TEXTURE);
-	glLoadIdentity();
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.loadIdentity();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 
 	LLGLSPipeline gls_pipeline;
-	LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0);
+	LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
 
 	LLGLState gls_color_material(GL_COLOR_MATERIAL, mLightingDetail < 2);
 				
@@ -3691,7 +3750,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
 			{
 				occlude = FALSE;
 				gGLLastMatrix = NULL;
-				glLoadMatrixd(gGLModelView);
+				gGL.loadMatrix(gGLModelView);
 				LLGLSLShader::bindNoShader();
 				doOcclusion(camera);
 			}
@@ -3702,7 +3761,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
 				LLFastTimer t(FTM_POOLRENDER);
 
 				gGLLastMatrix = NULL;
-				glLoadMatrixd(gGLModelView);
+				gGL.loadMatrix(gGLModelView);
 			
 				for( S32 i = 0; i < poolp->getNumPasses(); i++ )
 				{
@@ -3722,7 +3781,6 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
 					LLVertexBuffer::unbind();
 					if (gDebugGL)
 					{
-						check_stack_depth(stack_depth);
 						std::string msg = llformat("pass %d", i);
 						LLGLState::checkStates(msg);
 						//LLGLState::checkTextureChannels(msg);
@@ -3751,13 +3809,13 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
 		LLVertexBuffer::unbind();
 			
 		gGLLastMatrix = NULL;
-		glLoadMatrixd(gGLModelView);
+		gGL.loadMatrix(gGLModelView);
 
 		if (occlude)
 		{
 			occlude = FALSE;
 			gGLLastMatrix = NULL;
-			glLoadMatrixd(gGLModelView);
+			gGL.loadMatrix(gGLModelView);
 			LLGLSLShader::bindNoShader();
 			doOcclusion(camera);
 		}
@@ -3851,7 +3909,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
 		}
 	}
 
-	LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0);
+	LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
 
 	LLVertexBuffer::unbind();
 
@@ -3877,7 +3935,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
 			LLFastTimer t(FTM_POOLRENDER);
 
 			gGLLastMatrix = NULL;
-			glLoadMatrixd(gGLModelView);
+			gGL.loadMatrix(gGLModelView);
 		
 			for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ )
 			{
@@ -3898,12 +3956,6 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
 
 				if (gDebugGL || gDebugPipeline)
 				{
-					GLint depth;
-					glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth);
-					if (depth > 3)
-					{
-						llerrs << "GL matrix stack corrupted!" << llendl;
-					}
 					LLGLState::checkStates();
 				}
 			}
@@ -3925,7 +3977,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
 	}
 
 	gGLLastMatrix = NULL;
-	glLoadMatrixd(gGLModelView);
+	gGL.loadMatrix(gGLModelView);
 
 	gGL.setColorMask(true, false);
 }
@@ -3938,7 +3990,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
 
 	LLGLEnable cull(GL_CULL_FACE);
 
-	LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0);
+	LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
 
 	calcNearbyLights(camera);
 	setupHWLights(NULL);
@@ -3958,7 +4010,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
 		{
 			occlude = FALSE;
 			gGLLastMatrix = NULL;
-			glLoadMatrixd(gGLModelView);
+			gGL.loadMatrix(gGLModelView);
 			LLGLSLShader::bindNoShader();
 			doOcclusion(camera);
 			gGL.setColorMask(true, false);
@@ -3970,7 +4022,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
 			LLFastTimer t(FTM_POOLRENDER);
 
 			gGLLastMatrix = NULL;
-			glLoadMatrixd(gGLModelView);
+			gGL.loadMatrix(gGLModelView);
 		
 			for( S32 i = 0; i < poolp->getNumPostDeferredPasses(); i++ )
 			{
@@ -3991,12 +4043,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
 
 				if (gDebugGL || gDebugPipeline)
 				{
-					GLint depth;
-					glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth);
-					if (depth > 3)
-					{
-						llerrs << "GL matrix stack corrupted!" << llendl;
-					}
 					LLGLState::checkStates();
 				}
 			}
@@ -4018,17 +4064,17 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
 	}
 
 	gGLLastMatrix = NULL;
-	glLoadMatrixd(gGLModelView);
+	gGL.loadMatrix(gGLModelView);
 
 	if (occlude)
 	{
 		occlude = FALSE;
 		gGLLastMatrix = NULL;
-		glLoadMatrixd(gGLModelView);
+		gGL.loadMatrix(gGLModelView);
 		LLGLSLShader::bindNoShader();
 		doOcclusion(camera);
 		gGLLastMatrix = NULL;
-		glLoadMatrixd(gGLModelView);
+		gGL.loadMatrix(gGLModelView);
 	}
 }
 
@@ -4052,8 +4098,10 @@ void LLPipeline::renderGeomShadow(LLCamera& camera)
 		pool_set_t::iterator iter2 = iter1;
 		if (hasRenderType(poolp->getType()) && poolp->getNumShadowPasses() > 0)
 		{
+			poolp->prerender() ;
+
 			gGLLastMatrix = NULL;
-			glLoadMatrixd(gGLModelView);
+			gGL.loadMatrix(gGLModelView);
 		
 			for( S32 i = 0; i < poolp->getNumShadowPasses(); i++ )
 			{
@@ -4092,7 +4140,7 @@ void LLPipeline::renderGeomShadow(LLCamera& camera)
 	}
 
 	gGLLastMatrix = NULL;
-	glLoadMatrixd(gGLModelView);
+	gGL.loadMatrix(gGLModelView);
 }
 
 
@@ -4139,6 +4187,11 @@ void LLPipeline::renderPhysicsDisplay()
 
 	gGL.setColorMask(true, false);
 
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		gDebugProgram.bind();
+	}
+
 	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
 			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
 	{
@@ -4161,15 +4214,20 @@ void LLPipeline::renderPhysicsDisplay()
 		LLSpatialBridge* bridge = *i;
 		if (!bridge->isDead() && hasRenderType(bridge->mDrawableType))
 		{
-			glPushMatrix();
-			glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
+			gGL.pushMatrix();
+			gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
 			bridge->renderPhysicsShapes();
-			glPopMatrix();
+			gGL.popMatrix();
 		}
 	}
 
-
 	gGL.flush();
+
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		gDebugProgram.unbind();
+	}
+
 	mPhysicsDisplay.flush();
 }
 
@@ -4183,7 +4241,7 @@ void LLPipeline::renderDebug()
 	gGL.color4f(1,1,1,1);
 
 	gGLLastMatrix = NULL;
-	glLoadMatrixd(gGLModelView);
+	gGL.loadMatrix(gGLModelView);
 	gGL.setColorMask(true, false);
 
 	bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD);
@@ -4243,13 +4301,18 @@ void LLPipeline::renderDebug()
 		LLSpatialBridge* bridge = *i;
 		if (!bridge->isDead() && hasRenderType(bridge->mDrawableType))
 		{
-			glPushMatrix();
-			glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
+			gGL.pushMatrix();
+			gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
 			bridge->renderDebug();
-			glPopMatrix();
+			gGL.popMatrix();
 		}
 	}
 
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		gUIProgram.bind();
+	}
+
 	if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
 	{
 		LLVertexBuffer::unbind();
@@ -4429,7 +4492,7 @@ void LLPipeline::renderDebug()
 		gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep);
 		
 		gGL.pushMatrix();
-		glLoadMatrixd(gGLModelView);
+		gGL.loadMatrix(gGLModelView);
 		gGLLastMatrix = NULL;
 
 		for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); iter != mGroupQ2.end(); ++iter)
@@ -4450,7 +4513,7 @@ void LLPipeline::renderDebug()
 			if (bridge)
 			{
 				gGL.pushMatrix();
-				glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
+				gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
 			}
 
 			F32 alpha = llclamp((F32) (size-count)/size, 0.f, 1.f);
@@ -4474,8 +4537,10 @@ void LLPipeline::renderDebug()
 	}
 
 	gGL.flush();
-
-	gPipeline.renderPhysicsDisplay();
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		gUIProgram.unbind();
+	}
 }
 
 void LLPipeline::rebuildPools()
@@ -5024,10 +5089,14 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
 void LLPipeline::setupHWLights(LLDrawPool* pool)
 {
 	assertInitialized();
-
+	
 	// Ambient
-	LLColor4 ambient = gSky.getTotalAmbientColor();
-	glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient.mV);
+	if (!LLGLSLShader::sNoFixedFunction)
+	{
+		gGL.syncMatrices();
+		LLColor4 ambient = gSky.getTotalAmbientColor();
+		gGL.setAmbientLightColor(ambient);
+	}
 
 	// Light 0 = Sun or Moon (All objects)
 	{
@@ -5137,8 +5206,9 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 				light_state->setQuadraticAttenuation(0.f);
 			}
 			
+
 			if (light->isLightSpotlight() // directional (spot-)light
-			    && (LLPipeline::sRenderDeferred || gSavedSettings.getBOOL("RenderSpotLightsInNondeferred"))) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on
+			    && (LLPipeline::sRenderDeferred || RenderSpotLightsInNondeferred)) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on
 			{
 				LLVector3 spotparams = light->getSpotLightParams();
 				LLQuaternion quat = light->getRenderRotation();
@@ -5205,7 +5275,11 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 	}
 
 	// Init GL state
-	glDisable(GL_LIGHTING);
+	if (!LLGLSLShader::sNoFixedFunction)
+	{
+		glDisable(GL_LIGHTING);
+	}
+
 	for (S32 i = 0; i < 8; ++i)
 	{
 		gGL.getLight(i)->disable();
@@ -5226,7 +5300,10 @@ void LLPipeline::enableLights(U32 mask)
 		stop_glerror();
 		if (!mLightMask)
 		{
-			glEnable(GL_LIGHTING);
+			if (!LLGLSLShader::sNoFixedFunction)
+			{
+				glEnable(GL_LIGHTING);
+			}
 		}
 		if (mask)
 		{
@@ -5249,13 +5326,16 @@ void LLPipeline::enableLights(U32 mask)
 		}
 		else
 		{
-			glDisable(GL_LIGHTING);
+			if (!LLGLSLShader::sNoFixedFunction)
+			{
+				glDisable(GL_LIGHTING);
+			}
 		}
-		stop_glerror();
 		mLightMask = mask;
-		LLColor4 ambient = gSky.getTotalAmbientColor();
-		glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient.mV);
 		stop_glerror();
+
+		LLColor4 ambient = gSky.getTotalAmbientColor();
+		gGL.setAmbientLightColor(ambient);
 	}
 }
 
@@ -5304,21 +5384,24 @@ void LLPipeline::enableLightsPreview()
 {
 	disableLights();
 
-	glEnable(GL_LIGHTING);
-	LLColor4 ambient = gSavedSettings.getColor4("PreviewAmbientColor");
-	glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient.mV);
+	if (!LLGLSLShader::sNoFixedFunction)
+	{
+		glEnable(GL_LIGHTING);
+	}
 
+	LLColor4 ambient = PreviewAmbientColor;
+	gGL.setAmbientLightColor(ambient);
 
-	LLColor4 diffuse0 = gSavedSettings.getColor4("PreviewDiffuse0");
-	LLColor4 specular0 = gSavedSettings.getColor4("PreviewSpecular0");
-	LLColor4 diffuse1 = gSavedSettings.getColor4("PreviewDiffuse1");
-	LLColor4 specular1 = gSavedSettings.getColor4("PreviewSpecular1");
-	LLColor4 diffuse2 = gSavedSettings.getColor4("PreviewDiffuse2");
-	LLColor4 specular2 = gSavedSettings.getColor4("PreviewSpecular2");
+	LLColor4 diffuse0 = PreviewDiffuse0;
+	LLColor4 specular0 = PreviewSpecular0;
+	LLColor4 diffuse1 = PreviewDiffuse1;
+	LLColor4 specular1 = PreviewSpecular1;
+	LLColor4 diffuse2 = PreviewDiffuse2;
+	LLColor4 specular2 = PreviewSpecular2;
 
-	LLVector3 dir0 = gSavedSettings.getVector3("PreviewDirection0");
-	LLVector3 dir1 = gSavedSettings.getVector3("PreviewDirection1");
-	LLVector3 dir2 = gSavedSettings.getVector3("PreviewDirection2");
+	LLVector3 dir0 = PreviewDirection0;
+	LLVector3 dir1 = PreviewDirection1;
+	LLVector3 dir2 = PreviewDirection2;
 
 	dir0.normVec();
 	dir1.normVec();
@@ -5365,7 +5448,7 @@ void LLPipeline::enableLightsAvatarEdit(const LLColor4& color)
 	setupAvatarLights(TRUE);
 	enableLights(mask);
 
-	glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV);
+	gGL.setAmbientLightColor(color);
 }
 
 void LLPipeline::enableLightsFullbright(const LLColor4& color)
@@ -5374,7 +5457,7 @@ void LLPipeline::enableLightsFullbright(const LLColor4& color)
 	U32 mask = 0x1000; // Non-0 mask, set ambient
 	enableLights(mask);
 
-	glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV);
+	gGL.setAmbientLightColor(color);
 }
 
 void LLPipeline::disableLights()
@@ -6030,11 +6113,8 @@ void LLPipeline::resetVertexBuffers()
 
 	gSky.resetVertexBuffers();
 
-	if (LLVertexBuffer::sGLCount > 0)
-	{
-		LLVertexBuffer::cleanupClass();
-	}
-
+	LLVertexBuffer::cleanupClass();
+	
 	//delete all name pool caches
 	LLGLNamePool::cleanupPools();
 
@@ -6043,35 +6123,32 @@ void LLPipeline::resetVertexBuffers()
 		llwarns << "VBO wipe failed." << llendl;
 	}
 
-	if (!LLVertexBuffer::sStreamIBOPool.mNameList.empty() ||
-		!LLVertexBuffer::sStreamVBOPool.mNameList.empty() ||
-		!LLVertexBuffer::sDynamicIBOPool.mNameList.empty() ||
-		!LLVertexBuffer::sDynamicVBOPool.mNameList.empty())
-	{
-		llwarns << "VBO name pool cleanup failed." << llendl;
-	}
+	llassert(LLVertexBuffer::sGLCount == 0);
 
 	LLVertexBuffer::unbind();	
 	
 	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
 	sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
 	LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
+	LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseVAO");
 	LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw");
 	LLVertexBuffer::sEnableVBOs = gSavedSettings.getBOOL("RenderVBOEnable");
 	LLVertexBuffer::sDisableVBOMapping = LLVertexBuffer::sEnableVBOs && gSavedSettings.getBOOL("RenderVBOMappingDisable") ;
 	sBakeSunlight = gSavedSettings.getBOOL("RenderBakeSunlight");
 	sNoAlpha = gSavedSettings.getBOOL("RenderNoAlpha");
 	LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind");
+
+	LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping);
 }
 
 void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture)
 {
 	LLMemType mt_ro(LLMemType::MTYPE_PIPELINE_RENDER_OBJECTS);
 	assertInitialized();
-	glLoadMatrixd(gGLModelView);
+	gGL.loadMatrix(gGLModelView);
 	gGLLastMatrix = NULL;
 	mSimplePool->pushBatches(type, mask);
-	glLoadMatrixd(gGLModelView);
+	gGL.loadMatrix(gGLModelView);
 	gGLLastMatrix = NULL;		
 }
 
@@ -6080,25 +6157,25 @@ void apply_cube_face_rotation(U32 face)
 	switch (face)
 	{
 		case 0: 
-			glRotatef(90.f, 0, 1, 0);
-			glRotatef(180.f, 1, 0, 0);
+			gGL.rotatef(90.f, 0, 1, 0);
+			gGL.rotatef(180.f, 1, 0, 0);
 		break;
 		case 2: 
-			glRotatef(-90.f, 1, 0, 0);
+			gGL.rotatef(-90.f, 1, 0, 0);
 		break;
 		case 4:
-			glRotatef(180.f, 0, 1, 0);
-			glRotatef(180.f, 0, 0, 1);
+			gGL.rotatef(180.f, 0, 1, 0);
+			gGL.rotatef(180.f, 0, 0, 1);
 		break;
 		case 1: 
-			glRotatef(-90.f, 0, 1, 0);
-			glRotatef(180.f, 1, 0, 0);
+			gGL.rotatef(-90.f, 0, 1, 0);
+			gGL.rotatef(180.f, 1, 0, 0);
 		break;
 		case 3:
-			glRotatef(90, 1, 0, 0);
+			gGL.rotatef(90, 1, 0, 0);
 		break;
 		case 5: 
-			glRotatef(180, 0, 0, 1);
+			gGL.rotatef(180, 0, 0, 1);
 		break;
 	}
 }
@@ -6141,8 +6218,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 {
 	LLMemType mt_ru(LLMemType::MTYPE_PIPELINE_RENDER_BLOOM);
 	if (!(gPipeline.canUseVertexShaders() &&
-		sRenderGlow) ||
-		(!sRenderDeferred && hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)))
+		sRenderGlow))
 	{
 		return;
 	}
@@ -6158,7 +6234,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 	}
 
-	U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor");
+	U32 res_mod = RenderResolutionDivisor;
 
 	LLVector2 tc1(0,0);
 	LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw()*2,
@@ -6177,12 +6253,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 	
 	enableLightsFullbright(LLColor4(1,1,1,1));
 
-	glMatrixMode(GL_PROJECTION);
-	glPushMatrix();
-	glLoadIdentity();
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
-	glLoadIdentity();
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.pushMatrix();
+	gGL.loadIdentity();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.pushMatrix();
+	gGL.loadIdentity();
 
 	LLGLDisable test(GL_ALPHA_TEST);
 
@@ -6197,16 +6273,18 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 		}
 		
 		gGlowExtractProgram.bind();
-		F32 minLum = llmax(gSavedSettings.getF32("RenderGlowMinLuminance"), 0.0f);
-		F32 maxAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha");		
-		F32 warmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount");	
-		LLVector3 lumWeights = gSavedSettings.getVector3("RenderGlowLumWeights");
-		LLVector3 warmthWeights = gSavedSettings.getVector3("RenderGlowWarmthWeights");
-		gGlowExtractProgram.uniform1f("minLuminance", minLum);
-		gGlowExtractProgram.uniform1f("maxExtractAlpha", maxAlpha);
-		gGlowExtractProgram.uniform3f("lumWeights", lumWeights.mV[0], lumWeights.mV[1], lumWeights.mV[2]);
-		gGlowExtractProgram.uniform3f("warmthWeights", warmthWeights.mV[0], warmthWeights.mV[1], warmthWeights.mV[2]);
-		gGlowExtractProgram.uniform1f("warmthAmount", warmthAmount);
+		F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f);
+		F32 maxAlpha = RenderGlowMaxExtractAlpha;		
+		F32 warmthAmount = RenderGlowWarmthAmount;	
+		LLVector3 lumWeights = RenderGlowLumWeights;
+		LLVector3 warmthWeights = RenderGlowWarmthWeights;
+
+
+		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum);
+		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha);
+		gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1], lumWeights.mV[2]);
+		gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1], warmthWeights.mV[2]);
+		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount);
 		LLGLEnable blend_on(GL_BLEND);
 		LLGLEnable test(GL_ALPHA_TEST);
 		
@@ -6237,22 +6315,22 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 	tc2.setVec(2,2);
 
 	// power of two between 1 and 1024
-	U32 glowResPow = gSavedSettings.getS32("RenderGlowResolutionPow");
+	U32 glowResPow = RenderGlowResolutionPow;
 	const U32 glow_res = llmax(1, 
 		llmin(1024, 1 << glowResPow));
 
-	S32 kernel = gSavedSettings.getS32("RenderGlowIterations")*2;
-	F32 delta = gSavedSettings.getF32("RenderGlowWidth") / glow_res;
+	S32 kernel = RenderGlowIterations*2;
+	F32 delta = RenderGlowWidth / glow_res;
 	// Use half the glow width if we have the res set to less than 9 so that it looks
 	// almost the same in either case.
 	if (glowResPow < 9)
 	{
 		delta *= 0.5f;
 	}
-	F32 strength = gSavedSettings.getF32("RenderGlowStrength");
+	F32 strength = RenderGlowStrength;
 
 	gGlowProgram.bind();
-	gGlowProgram.uniform1f("glowStrength", strength);
+	gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength);
 
 	for (S32 i = 0; i < kernel; i++)
 	{
@@ -6273,11 +6351,11 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 
 		if (i%2 == 0)
 		{
-			gGlowProgram.uniform2f("glowDelta", delta, 0);
+			gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0);
 		}
 		else
 		{
-			gGlowProgram.uniform2f("glowDelta", 0, delta);
+			gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta);
 		}
 
 		gGL.begin(LLRender::TRIANGLE_STRIP);
@@ -6318,160 +6396,231 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 
 	if (LLPipeline::sRenderDeferred)
 	{
-		bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater();
 
-		LLGLSLShader* shader = &gDeferredPostProgram;
-		if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2)
+		bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
+							!LLToolMgr::getInstance()->inBuildMode() &&
+							RenderDepthOfField;
+
+
+		bool multisample = RenderFSAASamples > 1;
+
+		if (multisample)
 		{
-			shader = &gDeferredGIFinalProgram;
-			dof_enabled = false;
-		}
-		else if (!dof_enabled || LLToolMgr::getInstance()->inBuildMode() || !gSavedSettings.getBOOL("RenderDepthOfField"))
-		{ //squish focal length when in build mode (or if DoF is disabled) so DoF doesn't make editing objects difficult
-			shader = &gDeferredPostNoDoFProgram;
-			dof_enabled = false;
+			//bake out texture2D with RGBL for FXAA shader
+			mFXAABuffer.bindTarget();
+			
+			S32 width = mScreen.getWidth();
+			S32 height = mScreen.getHeight();
+			glViewport(0, 0, width, height);
+
+			gGlowCombineFXAAProgram.bind();
+			gGlowCombineFXAAProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height);
+
+			gGL.getTexUnit(0)->bind(&mGlow[1]);
+			gGL.getTexUnit(1)->bind(&mScreen);
+
+			gGL.begin(LLRender::TRIANGLE_STRIP);
+			gGL.vertex2f(-1,-1);
+			gGL.vertex2f(-1,3);
+			gGL.vertex2f(3,-1);
+			gGL.end();
+
+			gGL.flush();
+
+			gGlowCombineFXAAProgram.unbind();
+			mFXAABuffer.flush();
+
+			if (dof_enabled)
+			{ //if depth of field is not enabled, this is the final pass (draw to window)
+				mScreen.bindTarget();
+			}
+			LLGLSLShader* shader = &gFXAAProgram;
+			shader->bind();
+
+			S32 channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage());
+			if (channel > -1)
+			{
+				mFXAABuffer.bindTexture(0, channel);
+				gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
+			}
+
+			
+			F32 scale_x = (F32) width/mFXAABuffer.getWidth();
+			F32 scale_y = (F32) height/mFXAABuffer.getHeight();
+			shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y);
+			shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f/width*scale_x, 1.f/height*scale_y);
+			shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f/width*scale_x, -0.5f/height*scale_y, 0.5f/width*scale_x, 0.5f/height*scale_y);
+			shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f/width*scale_x, -2.f/height*scale_y, 2.f/width*scale_x, 2.f/height*scale_y);
+
+			gGL.begin(LLRender::TRIANGLE_STRIP);
+			gGL.vertex2f(-1,-1);
+			gGL.vertex2f(-1,3);
+			gGL.vertex2f(3,-1);
+			gGL.end();
+
+			gGL.flush();
+			if (dof_enabled)
+			{
+				mScreen.flush();
+			}
+			shader->unbind();
 		}
-		
-		
-		LLGLDisable blend(GL_BLEND);
-		bindDeferredShader(*shader);
 
-		if (dof_enabled)
+		gViewerWindow->setup3DViewport();
+				
+		if (dof_enabled || !multisample)
 		{
-			//depth of field focal plane calculations
+			LLGLSLShader* shader = &gDeferredPostProgram;
+			if (!dof_enabled)
+			{ 
+				shader = &gDeferredPostNoDoFProgram;
+			}
+				
+			LLGLDisable blend(GL_BLEND);
+			bindDeferredShader(*shader);
 
-			static F32 current_distance = 16.f;
-			static F32 start_distance = 16.f;
-			static F32 transition_time = 1.f;
+			if (dof_enabled)
+			{
+				//depth of field focal plane calculations
 
-			LLVector3 focus_point;
+				static F32 current_distance = 16.f;
+				static F32 start_distance = 16.f;
+				static F32 transition_time = 1.f;
 
-			LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject();
-			if (obj && obj->mDrawable && obj->isSelected())
-			{ //focus on selected media object
-				S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace();
-				if (obj && obj->mDrawable)
-				{
-					LLFace* face = obj->mDrawable->getFace(face_idx);
-					if (face)
+				LLVector3 focus_point;
+
+				LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject();
+				if (obj && obj->mDrawable && obj->isSelected())
+				{ //focus on selected media object
+					S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace();
+					if (obj && obj->mDrawable)
 					{
-						focus_point = face->getPositionAgent();
+						LLFace* face = obj->mDrawable->getFace(face_idx);
+						if (face)
+						{
+							focus_point = face->getPositionAgent();
+						}
 					}
 				}
-			}
 		
-			if (focus_point.isExactlyZero())
-			{
-				if (LLViewerJoystick::getInstance()->getOverrideCamera())
-				{ //focus on point under cursor
-					focus_point = gDebugRaycastIntersection;
-				}
-				else if (gAgentCamera.cameraMouselook())
-				{ //focus on point under mouselook crosshairs
-					gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE,
-												  NULL,
-												  &focus_point);
-				}
-				else
+				if (focus_point.isExactlyZero())
 				{
-					LLViewerObject* obj = gAgentCamera.getFocusObject();
-					if (obj)
-					{ //focus on alt-zoom target
-						focus_point = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal());
+					if (LLViewerJoystick::getInstance()->getOverrideCamera())
+					{ //focus on point under cursor
+						focus_point = gDebugRaycastIntersection;
+					}
+					else if (gAgentCamera.cameraMouselook())
+					{ //focus on point under mouselook crosshairs
+						gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE,
+													  NULL,
+													  &focus_point);
 					}
 					else
-					{ //focus on your avatar
-						focus_point = gAgent.getPositionAgent();
+					{
+						LLViewerObject* obj = gAgentCamera.getFocusObject();
+						if (obj)
+						{ //focus on alt-zoom target
+							focus_point = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal());
+						}
+						else
+						{ //focus on your avatar
+							focus_point = gAgent.getPositionAgent();
+						}
 					}
 				}
-			}
 
-			LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
-			F32 target_distance = 16.f;
-			if (!focus_point.isExactlyZero())
-			{
-				target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point-eye);
-			}
+				LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
+				F32 target_distance = 16.f;
+				if (!focus_point.isExactlyZero())
+				{
+					target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point-eye);
+				}
 
-			if (transition_time >= 1.f &&
-				fabsf(current_distance-target_distance)/current_distance > 0.01f)
-			{ //large shift happened, interpolate smoothly to new target distance
-				transition_time = 0.f;
-				start_distance = current_distance;
-			}
-			else if (transition_time < 1.f)
-			{ //currently in a transition, continue interpolating
-				transition_time += 1.f/gSavedSettings.getF32("CameraFocusTransitionTime")*gFrameIntervalSeconds;
-				transition_time = llmin(transition_time, 1.f);
+				if (transition_time >= 1.f &&
+					fabsf(current_distance-target_distance)/current_distance > 0.01f)
+				{ //large shift happened, interpolate smoothly to new target distance
+					transition_time = 0.f;
+					start_distance = current_distance;
+				}
+				else if (transition_time < 1.f)
+				{ //currently in a transition, continue interpolating
+					transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds;
+					transition_time = llmin(transition_time, 1.f);
 
-				F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f;
-				current_distance = start_distance + (target_distance-start_distance)*t;
-			}
-			else
-			{ //small or no change, just snap to target distance
-				current_distance = target_distance;
-			}
+					F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f;
+					current_distance = start_distance + (target_distance-start_distance)*t;
+				}
+				else
+				{ //small or no change, just snap to target distance
+					current_distance = target_distance;
+				}
 
-			//convert to mm
-			F32 subject_distance = current_distance*1000.f;
-			F32 fnumber = gSavedSettings.getF32("CameraFNumber");
-			F32 default_focal_length = gSavedSettings.getF32("CameraFocalLength");
+				//convert to mm
+				F32 subject_distance = current_distance*1000.f;
+				F32 fnumber = CameraFNumber;
+				F32 default_focal_length = CameraFocalLength;
 
-			F32 fov = LLViewerCamera::getInstance()->getView();
+				F32 fov = LLViewerCamera::getInstance()->getView();
 		
-			const F32 default_fov = gSavedSettings.getF32("CameraFieldOfView") * F_PI/180.f;
-			//const F32 default_aspect_ratio = gSavedSettings.getF32("CameraAspectRatio");
+				const F32 default_fov = CameraFieldOfView * F_PI/180.f;
+				//const F32 default_aspect_ratio = gSavedSettings.getF32("CameraAspectRatio");
 		
-			//F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight();
+				//F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight();
 		
-			F32 dv = 2.f*default_focal_length * tanf(default_fov/2.f);
-			//F32 dh = 2.f*default_focal_length * tanf(default_fov*default_aspect_ratio/2.f);
+				F32 dv = 2.f*default_focal_length * tanf(default_fov/2.f);
+				//F32 dh = 2.f*default_focal_length * tanf(default_fov*default_aspect_ratio/2.f);
 
-			F32 focal_length = dv/(2*tanf(fov/2.f));
+				F32 focal_length = dv/(2*tanf(fov/2.f));
 		 
-			//F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
+				//F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
 	
-			// from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
-			// where	 N = fnumber
-			//			 s2 = dot distance
-			//			 s1 = subject distance
-			//			 f = focal length
-			//	
+				// from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
+				// where	 N = fnumber
+				//			 s2 = dot distance
+				//			 s1 = subject distance
+				//			 f = focal length
+				//	
 
-			F32 blur_constant = focal_length*focal_length/(fnumber*(subject_distance-focal_length));
-			blur_constant /= 1000.f; //convert to meters for shader
-			F32 magnification = focal_length/(subject_distance-focal_length);
+				F32 blur_constant = focal_length*focal_length/(fnumber*(subject_distance-focal_length));
+				blur_constant /= 1000.f; //convert to meters for shader
+				F32 magnification = focal_length/(subject_distance-focal_length);
 
-			shader->uniform1f("focal_distance", -subject_distance/1000.f);
-			shader->uniform1f("blur_constant", blur_constant);
-			shader->uniform1f("tan_pixel_angle", tanf(1.f/LLDrawable::sCurPixelAngle));
-			shader->uniform1f("magnification", magnification);
-		}
+				shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance/1000.f);
+				shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant);
+				shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f/LLDrawable::sCurPixelAngle));
+				shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification);
+			}
 
-		S32 channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
-		if (channel > -1)
-		{
-			mScreen.bindTexture(0, channel);
-		}
-		//channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE);
-		//if (channel > -1)
-		//{
-			//gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
-		//}
+			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+			if (channel > -1)
+			{
+				mScreen.bindTexture(0, channel);
+			}
 
-		gGL.begin(LLRender::TRIANGLE_STRIP);
-		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-		gGL.vertex2f(-1,-1);
+			if (multisample)
+			{ //bloom has already been added, bind black
+				channel = shader->enableTexture(LLShaderMgr::DEFERRED_BLOOM);
+				if (channel > -1)
+				{
+					gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sBlackImagep);
+				}
+			}
+
+	
+			gGL.begin(LLRender::TRIANGLE_STRIP);
+			gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+			gGL.vertex2f(-1,-1);
 		
-		gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-		gGL.vertex2f(-1,3);
+			gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+			gGL.vertex2f(-1,3);
 		
-		gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-		gGL.vertex2f(3,-1);
+			gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+			gGL.vertex2f(3,-1);
 		
-		gGL.end();
+			gGL.end();
 
-		unbindDeferredShader(*shader);
+			unbindDeferredShader(*shader);
+		}
 	}
 	else
 	{
@@ -6504,7 +6653,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 		v[1] = LLVector3(-1,3,0);
 		v[2] = LLVector3(3,-1,0);
 				
-		buff->setBuffer(0);
+		buff->flush();
 
 		LLGLDisable blend(GL_BLEND);
 
@@ -6523,7 +6672,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 		gGL.getTexUnit(0)->bind(&mGlow[1]);
 		gGL.getTexUnit(1)->bind(&mScreen);
 		
-		LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0);
+		LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
 		
 		buff->setBuffer(mask);
 		buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3);
@@ -6543,19 +6692,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 		
 	}
 
-	if (LLRenderTarget::sUseFBO)
-	{ //copy depth buffer from mScreen to framebuffer
-		LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), 
-			0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
-	}
-	
 	gGL.setSceneBlendType(LLRender::BT_ALPHA);
 
 	if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))
 	{
 		if (LLGLSLShader::sNoFixedFunction)
 		{
-			gUIProgram.bind();
+			gSplatTextureRectProgram.bind();
 		}
 
 		gGL.setColorMask(true, false);
@@ -6569,7 +6712,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 
 		gGL.getTexUnit(0)->bind(&mPhysicsDisplay);
 
-		gGL.begin(LLRender::TRIANGLE_STRIP);
+		gGL.begin(LLRender::TRIANGLES);
 		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
 		gGL.vertex2f(-1,-1);
 		
@@ -6584,15 +6727,22 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 
 		if (LLGLSLShader::sNoFixedFunction)
 		{
-			gUIProgram.unbind();
+			gSplatTextureRectProgram.unbind();
 		}
+	}
 
+	
+	if (LLRenderTarget::sUseFBO)
+	{ //copy depth buffer from mScreen to framebuffer
+		LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), 
+			0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
 	}
+	
 
-	glMatrixMode(GL_PROJECTION);
-	glPopMatrix();
-	glMatrixMode(GL_MODELVIEW);
-	glPopMatrix();
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.popMatrix();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.popMatrix();
 
 	LLVertexBuffer::unbind();
 
@@ -6603,7 +6753,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 
 static LLFastTimer::DeclareTimer FTM_BIND_DEFERRED("Bind Deferred");
 
-void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRenderTarget* gi_source, LLRenderTarget* last_gi_post, U32 noise_map)
+void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 noise_map)
 {
 	LLFastTimer t(FTM_BIND_DEFERRED);
 
@@ -6614,150 +6764,32 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen
 
 	shader.bind();
 	S32 channel = 0;
-	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage());
+	channel = shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage());
 	if (channel > -1)
 	{
 		mDeferredScreen.bindTexture(0,channel);
 		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
 	}
 
-	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage());
+	channel = shader.enableTexture(LLShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage());
 	if (channel > -1)
 	{
 		mDeferredScreen.bindTexture(1, channel);
 		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
 	}
 
-	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage());
+	channel = shader.enableTexture(LLShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage());
 	if (channel > -1)
 	{
 		mDeferredScreen.bindTexture(2, channel);
 		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
 	}
 
-	if (gi_source)
+	channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, mDeferredDepth.getUsage());
+	if (channel > -1)
 	{
-		BOOL has_gi = FALSE;
-		channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_DIFFUSE);
-		if (channel > -1)
-		{
-			has_gi = TRUE;
-			gi_source->bindTexture(0, channel);
-			gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
-		}
-		
-		channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_SPECULAR);
-		if (channel > -1)
-		{
-			has_gi = TRUE;
-			gi_source->bindTexture(1, channel);
-			gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
-		}
-		
-		channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_NORMAL);
-		if (channel > -1)
-		{
-			has_gi = TRUE;
-			gi_source->bindTexture(2, channel);
-			gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
-		}
-		
-		channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_MIN_POS);
-		if (channel > -1)
-		{
-			has_gi = TRUE;
-			gi_source->bindTexture(1, channel);
-			gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
-		}
-		
-		channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_MAX_POS);
-		if (channel > -1)
-		{
-			has_gi = TRUE;
-			gi_source->bindTexture(3, channel);
-			gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
-		}
-		
-		channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_DIFFUSE);
-		if (channel > -1)
-		{
-			has_gi = TRUE;
-			last_gi_post->bindTexture(0, channel);
-			gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
-		}
-		
-		channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_NORMAL);
-		if (channel > -1)
-		{
-			has_gi = TRUE;
-			last_gi_post->bindTexture(2, channel);
-			gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
-		}
-		
-		channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MAX_POS);
-		if (channel > -1)
-		{
-			has_gi = TRUE;
-			last_gi_post->bindTexture(1, channel);
-			gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
-		}
-		
-		channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MIN_POS);
-		if (channel > -1)
-		{
-			has_gi = TRUE;
-			last_gi_post->bindTexture(3, channel);
-			gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
-		}
-		
-		channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_DEPTH);
-		if (channel > -1)
-		{
-			has_gi = TRUE;
-			gGL.getTexUnit(channel)->bind(gi_source, TRUE);
-			gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
-			stop_glerror();
-			
-			glTexParameteri(LLTexUnit::getInternalType(mGIMap.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);		
-			glTexParameteri(LLTexUnit::getInternalType(mGIMap.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA);		
-
-			stop_glerror();
-		}
-
-		if (has_gi)
-		{
-			F32 range_x = llmin(mGIRange.mV[0], 1.f);
-			F32 range_y = llmin(mGIRange.mV[1], 1.f);
-
-			LLVector2 scale(range_x,range_y);
-
-			LLVector2 kern[25];
-
-			for (S32 i = 0; i < 5; ++i)
-			{
-				for (S32 j = 0; j < 5; ++j)
-				{
-					S32 idx = i*5+j;
-					kern[idx].mV[0] = (i-2)*0.5f;
-					kern[idx].mV[1] = (j-2)*0.5f;
-					kern[idx].scaleVec(scale);
-				}
-			}
-
-			shader.uniform2fv("gi_kern", 25, (F32*) kern);
-			shader.uniformMatrix4fv("gi_mat", 1, FALSE, mGIMatrix.m);
-			shader.uniformMatrix4fv("gi_mat_proj", 1, FALSE, mGIMatrixProj.m);
-			shader.uniformMatrix4fv("gi_inv_proj", 1, FALSE, mGIInvProj.m);
-			shader.uniformMatrix4fv("gi_norm_mat", 1, FALSE, mGINormalMatrix.m);
-		}
-	}
-	stop_glerror();
-
-	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, mDeferredDepth.getUsage());
-	if (channel > -1)
-	{
-		gGL.getTexUnit(channel)->bind(&mDeferredDepth, TRUE);
-		stop_glerror();
+		gGL.getTexUnit(channel)->bind(&mDeferredDepth, TRUE);
+		stop_glerror();
 		
 		//glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);		
 		//glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA);		
@@ -6767,21 +6799,21 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen
 		glh::matrix4f projection = glh_get_current_projection();
 		glh::matrix4f inv_proj = projection.inverse();
 		
-		shader.uniformMatrix4fv("inv_proj", 1, FALSE, inv_proj.m);
-		shader.uniform4f("viewport", (F32) gGLViewport[0],
+		shader.uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m);
+		shader.uniform4f(LLShaderMgr::VIEWPORT, (F32) gGLViewport[0],
 									(F32) gGLViewport[1],
 									(F32) gGLViewport[2],
 									(F32) gGLViewport[3]);
 	}
 
-	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NOISE);
+	channel = shader.enableTexture(LLShaderMgr::DEFERRED_NOISE);
 	if (channel > -1)
 	{
 		gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, noise_map);
 		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
 	}
 
-	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHTFUNC);
+	channel = shader.enableTexture(LLShaderMgr::DEFERRED_LIGHTFUNC);
 	if (channel > -1)
 	{
 		gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
@@ -6789,60 +6821,31 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen
 
 	stop_glerror();
 
-	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, mDeferredLight[light_index].getUsage());
+	channel = shader.enableTexture(LLShaderMgr::DEFERRED_LIGHT, mDeferredLight.getUsage());
 	if (channel > -1)
 	{
-		mDeferredLight[light_index].bindTexture(0, channel);
+		if (light_index > 0)
+		{
+			mScreen.bindTexture(0, channel);
+		}
+		else
+		{
+			mDeferredLight.bindTexture(0, channel);
+		}
 		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
 	}
 
-	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE);
-	if (channel > -1)
-	{
-		gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mLuminanceMap.getTexture(), true);
-		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
-	}
-
-	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_BLOOM);
+	channel = shader.enableTexture(LLShaderMgr::DEFERRED_BLOOM);
 	if (channel > -1)
 	{
 		mGlow[1].bindTexture(0, channel);
 	}
 
-	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
-	if (channel > -1)
-	{
-		gi_source->bindTexture(0, channel);
-		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
-	}
-
-	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_EDGE, LLTexUnit::TT_RECT_TEXTURE);
-	if (channel > -1)
-	{
-		mEdgeMap.bindTexture(0, channel);
-		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
-	}
-
-	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
-	if (channel > -1)
-	{
-		mDeferredLight[1].bindTexture(0, channel);
-		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
-	}
-
-	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
-	if (channel > -1)
-	{
-		mDeferredLight[2].bindTexture(0, channel);
-		gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
-	}
-
-
 	stop_glerror();
 
 	for (U32 i = 0; i < 4; i++)
 	{
-		channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE);
+		channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE);
 		stop_glerror();
 		if (channel > -1)
 		{
@@ -6860,7 +6863,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen
 
 	for (U32 i = 4; i < 6; i++)
 	{
-		channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i);
+		channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i);
 		stop_glerror();
 		if (channel > -1)
 		{
@@ -6889,12 +6892,11 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen
 		mat[i+80] = mSunShadowMatrix[5].m[i];
 	}
 
-	shader.uniformMatrix4fv("shadow_matrix[0]", 6, FALSE, mat);
-	shader.uniformMatrix4fv("shadow_matrix", 6, FALSE, mat);
+	shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_SHADOW_MATRIX, 6, FALSE, mat);
 
 	stop_glerror();
 
-	channel = shader.enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
+	channel = shader.enableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
 	if (channel > -1)
 	{
 		LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
@@ -6902,31 +6904,30 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen
 		{
 			cube_map->enable(channel);
 			cube_map->bind();
-			F64* m = gGLModelView;
+			F32* m = gGLModelView;
 
 			
 			F32 mat[] = { m[0], m[1], m[2],
 						  m[4], m[5], m[6],
 						  m[8], m[9], m[10] };
 		
-			shader.uniform3fv("env_mat[0]", 3, mat);
-			shader.uniform3fv("env_mat", 3, mat);
+			shader.uniform3fv(LLShaderMgr::DEFERRED_ENV_MAT, 3, mat);
 		}
 	}
 
-	shader.uniform4fv("shadow_clip", 1, mSunClipPlanes.mV);
-	shader.uniform1f("sun_wash", gSavedSettings.getF32("RenderDeferredSunWash"));
-	shader.uniform1f("shadow_noise", gSavedSettings.getF32("RenderShadowNoise"));
-	shader.uniform1f("blur_size", gSavedSettings.getF32("RenderShadowBlurSize"));
+	shader.uniform4fv(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1, mSunClipPlanes.mV);
+	shader.uniform1f(LLShaderMgr::DEFERRED_SUN_WASH, RenderDeferredSunWash);
+	shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_NOISE, RenderShadowNoise);
+	shader.uniform1f(LLShaderMgr::DEFERRED_BLUR_SIZE, RenderShadowBlurSize);
 
-	shader.uniform1f("ssao_radius", gSavedSettings.getF32("RenderSSAOScale"));
-	shader.uniform1f("ssao_max_radius", gSavedSettings.getU32("RenderSSAOMaxScale"));
+	shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_RADIUS, RenderSSAOScale);
+	shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_MAX_RADIUS, RenderSSAOMaxScale);
 
-	F32 ssao_factor = gSavedSettings.getF32("RenderSSAOFactor");
-	shader.uniform1f("ssao_factor", ssao_factor);
-	shader.uniform1f("ssao_factor_inv", 1.0/ssao_factor);
+	F32 ssao_factor = RenderSSAOFactor;
+	shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_FACTOR, ssao_factor);
+	shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_FACTOR_INV, 1.0/ssao_factor);
 
-	LLVector3 ssao_effect = gSavedSettings.getVector3("RenderSSAOEffect");
+	LLVector3 ssao_effect = RenderSSAOEffect;
 	F32 matrix_diag = (ssao_effect[0] + 2.0*ssao_effect[1])/3.0;
 	F32 matrix_nondiag = (ssao_effect[0] - ssao_effect[1])/3.0;
 	// This matrix scales (proj of color onto <1/rt(3),1/rt(3),1/rt(3)>) by
@@ -6934,35 +6935,23 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen
 	F32 ssao_effect_mat[] = {	matrix_diag, matrix_nondiag, matrix_nondiag,
 								matrix_nondiag, matrix_diag, matrix_nondiag,
 								matrix_nondiag, matrix_nondiag, matrix_diag};
-	shader.uniformMatrix3fv("ssao_effect_mat", 1, GL_FALSE, ssao_effect_mat);
-
-	F32 shadow_offset_error = 1.f + gSavedSettings.getF32("RenderShadowOffsetError") * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]);
-	F32 shadow_bias_error = 1.f + gSavedSettings.getF32("RenderShadowBiasError") * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]);
-
-	shader.uniform2f("screen_res", mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
-	shader.uniform1f("near_clip", LLViewerCamera::getInstance()->getNear()*2.f);
-	shader.uniform1f ("shadow_offset", gSavedSettings.getF32("RenderShadowOffset")*shadow_offset_error);
-	shader.uniform1f("shadow_bias", gSavedSettings.getF32("RenderShadowBias")*shadow_bias_error);
-	shader.uniform1f ("spot_shadow_offset", gSavedSettings.getF32("RenderSpotShadowOffset"));
-	shader.uniform1f("spot_shadow_bias", gSavedSettings.getF32("RenderSpotShadowBias"));	
-
-	shader.uniform1f("lum_scale", gSavedSettings.getF32("RenderLuminanceScale"));
-	shader.uniform1f("sun_lum_scale", gSavedSettings.getF32("RenderSunLuminanceScale"));
-	shader.uniform1f("sun_lum_offset", gSavedSettings.getF32("RenderSunLuminanceOffset"));
-	shader.uniform1f("lum_lod", gSavedSettings.getF32("RenderLuminanceDetail"));
-	shader.uniform1f("gi_range", gSavedSettings.getF32("RenderGIRange"));
-	shader.uniform1f("gi_brightness", gSavedSettings.getF32("RenderGIBrightness"));
-	shader.uniform1f("gi_luminance", gSavedSettings.getF32("RenderGILuminance"));
-	shader.uniform1f("gi_edge_weight", gSavedSettings.getF32("RenderGIBlurEdgeWeight"));
-	shader.uniform1f("gi_blur_brightness", gSavedSettings.getF32("RenderGIBlurBrightness"));
-	shader.uniform1f("gi_sample_width", mGILightRadius);
-	shader.uniform1f("gi_noise", gSavedSettings.getF32("RenderGINoise"));
-	shader.uniform1f("gi_attenuation", gSavedSettings.getF32("RenderGIAttenuation"));
-	shader.uniform1f("gi_ambiance", gSavedSettings.getF32("RenderGIAmbiance"));
-	shader.uniform2f("shadow_res", mShadow[0].getWidth(), mShadow[0].getHeight());
-	shader.uniform2f("proj_shadow_res", mShadow[4].getWidth(), mShadow[4].getHeight());
-	shader.uniform1f("depth_cutoff", gSavedSettings.getF32("RenderEdgeDepthCutoff"));
-	shader.uniform1f("norm_cutoff", gSavedSettings.getF32("RenderEdgeNormCutoff"));
+	shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_SSAO_EFFECT_MAT, 1, GL_FALSE, ssao_effect_mat);
+
+	F32 shadow_offset_error = 1.f + RenderShadowOffsetError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]);
+	F32 shadow_bias_error = 1.f + RenderShadowBiasError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]);
+
+	shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
+	shader.uniform1f(LLShaderMgr::DEFERRED_NEAR_CLIP, LLViewerCamera::getInstance()->getNear()*2.f);
+	shader.uniform1f (LLShaderMgr::DEFERRED_SHADOW_OFFSET, RenderShadowOffset*shadow_offset_error);
+	shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_BIAS, RenderShadowBias*shadow_bias_error);
+	shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_OFFSET, RenderSpotShadowOffset);
+	shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_BIAS, RenderSpotShadowBias);	
+
+	shader.uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, mTransformedSunDir.mV);
+	shader.uniform2f(LLShaderMgr::DEFERRED_SHADOW_RES, mShadow[0].getWidth(), mShadow[0].getHeight());
+	shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mShadow[4].getWidth(), mShadow[4].getHeight());
+	shader.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);
+	shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff);
 	
 
 	if (shader.getUniformLocation("norm_mat") >= 0)
@@ -7001,7 +6990,7 @@ void LLPipeline::renderDeferredLighting()
 							0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);	
 		}
 
-		LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0);
+		LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
 
 		if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
 		{
@@ -7023,38 +7012,40 @@ void LLPipeline::renderDeferredLighting()
 
 		glh::matrix4f mat = glh_copy_matrix(gGLModelView);
 
-		F32 vert[] = 
-		{
-			-1,1,
-			-1,-3,
-			3,1,
-		};
-		glVertexPointer(2, GL_FLOAT, 0, vert);
-		glColor3f(1,1,1);
+		LLStrider<LLVector3> vert; 
+		mDeferredVB->getVertexStrider(vert);
+		LLStrider<LLVector2> tc0;
+		LLStrider<LLVector2> tc1;
+		mDeferredVB->getTexCoord0Strider(tc0);
+		mDeferredVB->getTexCoord1Strider(tc1);
 
+		vert[0].set(-1,1,0);
+		vert[1].set(-1,-3,0);
+		vert[2].set(3,1,0);
+		
 		{
 			setupHWLights(NULL); //to set mSunDir;
 			LLVector4 dir(mSunDir, 0.f);
 			glh::vec4f tc(dir.mV);
 			mat.mult_matrix_vec(tc);
-			glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0);
+			mTransformedSunDir.set(tc.v);
 		}
 
-		glPushMatrix();
-		glLoadIdentity();
-		glMatrixMode(GL_PROJECTION);
-		glPushMatrix();
-		glLoadIdentity();
+		gGL.pushMatrix();
+		gGL.loadIdentity();
+		gGL.matrixMode(LLRender::MM_PROJECTION);
+		gGL.pushMatrix();
+		gGL.loadIdentity();
 
-		if (gSavedSettings.getBOOL("RenderDeferredSSAO") || gSavedSettings.getS32("RenderShadowDetail") > 0)
+		if (RenderDeferredSSAO || RenderShadowDetail > 0)
 		{
-			mDeferredLight[0].bindTarget();
+			mDeferredLight.bindTarget();
 			{ //paint shadow/SSAO light map (direct lighting lightmap)
 				LLFastTimer ftm(FTM_SUN_SHADOW);
 				bindDeferredShader(gDeferredSunProgram, 0);
-
+				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
 				glClearColor(1,1,1,1);
-				mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT);
+				mDeferredLight.clear(GL_COLOR_BUFFER_BIT);
 				glClearColor(0,0,0,0);
 
 				glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose();
@@ -7077,141 +7068,36 @@ void LLPipeline::renderDeferredLighting()
 				}
 
 				gDeferredSunProgram.uniform3fv("offset", slice, offset);
-				gDeferredSunProgram.uniform2f("screenRes", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight());
+				gDeferredSunProgram.uniform2f("screenRes", mDeferredLight.getWidth(), mDeferredLight.getHeight());
 				
 				{
 					LLGLDisable blend(GL_BLEND);
 					LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
 					stop_glerror();
-					glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
+					mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
 					stop_glerror();
 				}
 				
 				unbindDeferredShader(gDeferredSunProgram);
 			}
-			mDeferredLight[0].flush();
+			mDeferredLight.flush();
 		}
 		
-		{ //global illumination specific block (still experimental)
-			if (gSavedSettings.getBOOL("RenderDeferredBlurLight") &&
-			    gSavedSettings.getBOOL("RenderDeferredGI"))
-			{
-				LLFastTimer ftm(FTM_EDGE_DETECTION);
-				//generate edge map
-				LLGLDisable blend(GL_BLEND);
-				LLGLDisable test(GL_ALPHA_TEST);
-				LLGLDepthTest depth(GL_FALSE);
-				LLGLDisable stencil(GL_STENCIL_TEST);
-
-				{
-					gDeferredEdgeProgram.bind();
-					mEdgeMap.bindTarget();
-					bindDeferredShader(gDeferredEdgeProgram);
-					glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
-					unbindDeferredShader(gDeferredEdgeProgram);
-					mEdgeMap.flush();
-				}
-			}
-
-			if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2)
-			{
-				{ //get luminance map from previous frame's light map
-					LLGLEnable blend(GL_BLEND);
-					LLGLDisable test(GL_ALPHA_TEST);
-					LLGLDepthTest depth(GL_FALSE);
-					LLGLDisable stencil(GL_STENCIL_TEST);
-
-					//static F32 fade = 1.f;
-
-					{
-						gGL.setSceneBlendType(LLRender::BT_ALPHA);
-						gLuminanceGatherProgram.bind();
-						gLuminanceGatherProgram.uniform2f("screen_res", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight());
-						mLuminanceMap.bindTarget();
-						bindDeferredShader(gLuminanceGatherProgram);
-						glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
-						unbindDeferredShader(gLuminanceGatherProgram);
-						mLuminanceMap.flush();
-						gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLuminanceMap.getTexture(), true);
-						gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
-						glGenerateMipmap(GL_TEXTURE_2D);
-					}
-				}
-
-				{ //paint noisy GI map (bounce lighting lightmap)
-					LLFastTimer ftm(FTM_GI_TRACE);
-					LLGLDisable blend(GL_BLEND);
-					LLGLDepthTest depth(GL_FALSE);
-					LLGLDisable test(GL_ALPHA_TEST);
-
-					mGIMapPost[0].bindTarget();
-
-					bindDeferredShader(gDeferredGIProgram, 0, &mGIMap, 0, mTrueNoiseMap);
-					glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
-					unbindDeferredShader(gDeferredGIProgram);
-					mGIMapPost[0].flush();
-				}
-
-				U32 pass_count = 0;
-				if (gSavedSettings.getBOOL("RenderDeferredBlurLight"))
-				{
-					pass_count = llclamp(gSavedSettings.getU32("RenderGIBlurPasses"), (U32) 1, (U32) 128);
-				}
-
-				for (U32 i = 0; i < pass_count; ++i)
-				{ //gather/soften indirect lighting map
-					LLFastTimer ftm(FTM_GI_GATHER);
-					bindDeferredShader(gDeferredPostGIProgram, 0, &mGIMapPost[0], NULL, mTrueNoiseMap);
-					F32 blur_size = gSavedSettings.getF32("RenderGIBlurSize")/((F32) i * gSavedSettings.getF32("RenderGIBlurIncrement")+1.f);
-					gDeferredPostGIProgram.uniform2f("delta", 1.f, 0.f);
-					gDeferredPostGIProgram.uniform1f("kern_scale", blur_size);
-					gDeferredPostGIProgram.uniform1f("gi_blur_brightness", gSavedSettings.getF32("RenderGIBlurBrightness"));
-				
-					mGIMapPost[1].bindTarget();
-					{
-						LLGLDisable blend(GL_BLEND);
-						LLGLDepthTest depth(GL_FALSE);
-						stop_glerror();
-						glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
-						stop_glerror();
-					}
-					
-					mGIMapPost[1].flush();
-					unbindDeferredShader(gDeferredPostGIProgram);
-					bindDeferredShader(gDeferredPostGIProgram, 0, &mGIMapPost[1], NULL, mTrueNoiseMap);
-					mGIMapPost[0].bindTarget();
-
-					gDeferredPostGIProgram.uniform2f("delta", 0.f, 1.f);
-
-					{
-						LLGLDisable blend(GL_BLEND);
-						LLGLDepthTest depth(GL_FALSE);
-						stop_glerror();
-						glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-						stop_glerror();
-					}
-					mGIMapPost[0].flush();
-					unbindDeferredShader(gDeferredPostGIProgram);
-				}
-			}
-		}
-
-		if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
+		if (RenderDeferredSSAO)
 		{ //soften direct lighting lightmap
 			LLFastTimer ftm(FTM_SOFTEN_SHADOW);
 			//blur lightmap
-			mDeferredLight[1].bindTarget();
-
+			mScreen.bindTarget();
 			glClearColor(1,1,1,1);
-			mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT);
+			mScreen.clear(GL_COLOR_BUFFER_BIT);
 			glClearColor(0,0,0,0);
 			
 			bindDeferredShader(gDeferredBlurLightProgram);
-
-			LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian");
+			mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+			LLVector3 go = RenderShadowGaussian;
 			const U32 kern_length = 4;
-			F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize");
-			F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor");
+			F32 blur_size = RenderShadowBlurSize;
+			F32 dist_factor = RenderShadowBlurDistFactor;
 
 			// sample symmetrically with the middle sample falling exactly on 0.0
 			F32 x = 0.f;
@@ -7235,15 +7121,16 @@ void LLPipeline::renderDeferredLighting()
 				LLGLDisable blend(GL_BLEND);
 				LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
 				stop_glerror();
-				glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
+				mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
 				stop_glerror();
 			}
 			
-			mDeferredLight[1].flush();
+			mScreen.flush();
 			unbindDeferredShader(gDeferredBlurLightProgram);
 
 			bindDeferredShader(gDeferredBlurLightProgram, 1);
-			mDeferredLight[0].bindTarget();
+			mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+			mDeferredLight.bindTarget();
 
 			gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f);
 
@@ -7251,69 +7138,59 @@ void LLPipeline::renderDeferredLighting()
 				LLGLDisable blend(GL_BLEND);
 				LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
 				stop_glerror();
-				glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
+				mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
 				stop_glerror();
 			}
-			mDeferredLight[0].flush();
+			mDeferredLight.flush();
 			unbindDeferredShader(gDeferredBlurLightProgram);
 		}
 
 		stop_glerror();
-		glPopMatrix();
+		gGL.popMatrix();
 		stop_glerror();
-		glMatrixMode(GL_MODELVIEW);
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
 		stop_glerror();
-		glPopMatrix();
+		gGL.popMatrix();
 		stop_glerror();
 
 		//copy depth and stencil from deferred screen
 		//mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
 		//					0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
 
-		if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2)
-		{
-			mDeferredLight[1].bindTarget();
-			// clear color buffer here (GI) - zeroing alpha (glow) is important or it will accumulate against sky
-			glClearColor(0,0,0,0);
-			mScreen.clear(GL_COLOR_BUFFER_BIT);
-		}
-		else
-		{
-			mScreen.bindTarget();
-			// clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky
-			glClearColor(0,0,0,0);
-			mScreen.clear(GL_COLOR_BUFFER_BIT);
-		}
-
-		if (gSavedSettings.getBOOL("RenderDeferredAtmospheric"))
+		mScreen.bindTarget();
+		// clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky
+		glClearColor(0,0,0,0);
+		mScreen.clear(GL_COLOR_BUFFER_BIT);
+		
+		if (RenderDeferredAtmospheric)
 		{ //apply sunlight contribution 
 			LLFastTimer ftm(FTM_ATMOSPHERICS);
-			bindDeferredShader(gDeferredSoftenProgram, 0, &mGIMapPost[0]);	
+			bindDeferredShader(gDeferredSoftenProgram);	
 			{
 				LLGLDepthTest depth(GL_FALSE);
 				LLGLDisable blend(GL_BLEND);
 				LLGLDisable test(GL_ALPHA_TEST);
 
 				//full screen blit
-				glPushMatrix();
-				glLoadIdentity();
-				glMatrixMode(GL_PROJECTION);
-				glPushMatrix();
-				glLoadIdentity();
+				gGL.pushMatrix();
+				gGL.loadIdentity();
+				gGL.matrixMode(LLRender::MM_PROJECTION);
+				gGL.pushMatrix();
+				gGL.loadIdentity();
 
-				glVertexPointer(2, GL_FLOAT, 0, vert);
-				
-				glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
+				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
 				
-				glPopMatrix();
-				glMatrixMode(GL_MODELVIEW);
-				glPopMatrix();
+				mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+				gGL.popMatrix();
+				gGL.matrixMode(LLRender::MM_MODELVIEW);
+				gGL.popMatrix();
 			}
 
 			unbindDeferredShader(gDeferredSoftenProgram);
 		}
 
-		{ //render sky
+		{ //render non-deferred geometry (fullbright, alpha, etc)
 			LLGLDisable blend(GL_BLEND);
 			LLGLDisable stencil(GL_STENCIL_TEST);
 			gGL.setSceneBlendType(LLRender::BT_ALPHA);
@@ -7330,15 +7207,8 @@ void LLPipeline::renderDeferredLighting()
 			gPipeline.popRenderTypeMask();
 		}
 
-		BOOL render_local = gSavedSettings.getBOOL("RenderLocalLights");
+		BOOL render_local = RenderLocalLights;
 				
-		if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2)
-		{
-			mDeferredLight[1].flush();
-			mDeferredLight[2].bindTarget();
-			mDeferredLight[2].clear(GL_COLOR_BUFFER_BIT);
-		}
-
 		if (render_local)
 		{
 			gGL.setSceneBlendType(LLRender::BT_ADD);
@@ -7354,12 +7224,12 @@ void LLPipeline::renderDeferredLighting()
 			std::list<LLVector4> light_colors;
 
 			LLVertexBuffer::unbind();
+			LLVector4a* v = (LLVector4a*) vert.get();
 
-			F32 v[24];
-			glVertexPointer(3, GL_FLOAT, 0, v);
-			
 			{
 				bindDeferredShader(gDeferredLightProgram);
+				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
 				LLGLDepthTest depth(GL_TRUE, GL_FALSE);
 				for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
 				{
@@ -7414,15 +7284,16 @@ void LLPipeline::renderDeferredLighting()
 					//correspond to their axis facing, with bit position 3,2,1 matching
 					//axis facing x,y,z, bit set meaning positive facing, bit clear 
 					//meaning negative facing
-					v[0] = c[0]-s; v[1]  = c[1]-s; v[2]  = c[2]-s;  // 0 - 0000 
-					v[3] = c[0]-s; v[4]  = c[1]-s; v[5]  = c[2]+s;  // 1 - 0001
-					v[6] = c[0]-s; v[7]  = c[1]+s; v[8]  = c[2]-s;  // 2 - 0010
-					v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s;  // 3 - 0011
+					mDeferredVB->getVertexStrider(vert);
+					v[0].set(c[0]-s,c[1]-s,c[2]-s);  // 0 - 0000 
+					v[1].set(c[0]-s,c[1]-s,c[2]+s);  // 1 - 0001
+					v[2].set(c[0]-s,c[1]+s,c[2]-s);  // 2 - 0010
+					v[3].set(c[0]-s,c[1]+s,c[2]+s);  // 3 - 0011
 																									   
-					v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100
-					v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101
-					v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110
-					v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111
+					v[4].set(c[0]+s,c[1]-s,c[2]-s); // 4 - 0100
+					v[5].set(c[0]+s,c[1]-s,c[2]+s); // 5 - 0101
+					v[6].set(c[0]+s,c[1]+s,c[2]-s); // 6 - 0110
+					v[7].set(c[0]+s,c[1]+s,c[2]+s); // 7 - 0111
 
 					if (camera->getOrigin().mV[0] > c[0] + s + 0.2f ||
 						camera->getOrigin().mV[0] < c[0] - s - 0.2f ||
@@ -7441,10 +7312,16 @@ void LLPipeline::renderDeferredLighting()
 							}
 							
 							LLFastTimer ftm(FTM_LOCAL_LIGHTS);
-							glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
-							glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
+							//glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
+							gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
+							gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
+							gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+							gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
+							//gGL.diffuseColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
+							gGL.syncMatrices();
+							mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
 							glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
-								GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, center));
+								GL_UNSIGNED_SHORT, get_box_fan_indices_ptr(camera, center));
 							stop_glerror();
 						}
 					}
@@ -7469,7 +7346,9 @@ void LLPipeline::renderDeferredLighting()
 				LLGLDepthTest depth(GL_TRUE, GL_FALSE);
 				bindDeferredShader(gDeferredSpotLightProgram);
 
-				gDeferredSpotLightProgram.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION);
+				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+				gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
 
 				for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter)
 				{
@@ -7497,36 +7376,49 @@ void LLPipeline::renderDeferredLighting()
 					//correspond to their axis facing, with bit position 3,2,1 matching
 					//axis facing x,y,z, bit set meaning positive facing, bit clear 
 					//meaning negative facing
-					v[0] = c[0]-s; v[1]  = c[1]-s; v[2]  = c[2]-s;  // 0 - 0000 
-					v[3] = c[0]-s; v[4]  = c[1]-s; v[5]  = c[2]+s;  // 1 - 0001
-					v[6] = c[0]-s; v[7]  = c[1]+s; v[8]  = c[2]-s;  // 2 - 0010
-					v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s;  // 3 - 0011
+					mDeferredVB->getVertexStrider(vert);
+					v[0].set(c[0]-s,c[1]-s,c[2]-s);  // 0 - 0000 
+					v[1].set(c[0]-s,c[1]-s,c[2]+s);  // 1 - 0001
+					v[2].set(c[0]-s,c[1]+s,c[2]-s);  // 2 - 0010
+					v[3].set(c[0]-s,c[1]+s,c[2]+s);  // 3 - 0011
 																									   
-					v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100
-					v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101
-					v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110
-					v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111
-
-					glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
-					glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
+					v[4].set(c[0]+s,c[1]-s,c[2]-s); // 4 - 0100
+					v[5].set(c[0]+s,c[1]-s,c[2]+s); // 5 - 0101
+					v[6].set(c[0]+s,c[1]+s,c[2]-s); // 6 - 0110
+					v[7].set(c[0]+s,c[1]+s,c[2]+s); // 7 - 0111
+					
+					gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
+					gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
+					gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+					gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
+					gGL.syncMatrices();
+					mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
 					glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
-							GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, center));
+							GL_UNSIGNED_SHORT, get_box_fan_indices_ptr(camera, center));
 				}
-				gDeferredSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION);
+				gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
 				unbindDeferredShader(gDeferredSpotLightProgram);
 			}
 
+			//reset mDeferredVB to fullscreen triangle
+			mDeferredVB->getVertexStrider(vert);
+			vert[0].set(-1,1,0);
+			vert[1].set(-1,-3,0);
+			vert[2].set(3,1,0);
+
 			{
 				bindDeferredShader(gDeferredMultiLightProgram);
 			
+				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
 				LLGLDepthTest depth(GL_FALSE);
 
 				//full screen blit
-				glPushMatrix();
-				glLoadIdentity();
-				glMatrixMode(GL_PROJECTION);
-				glPushMatrix();
-				glLoadIdentity();
+				gGL.pushMatrix();
+				gGL.loadIdentity();
+				gGL.matrixMode(LLRender::MM_PROJECTION);
+				gGL.pushMatrix();
+				gGL.loadIdentity();
 
 				U32 count = 0;
 
@@ -7534,7 +7426,7 @@ void LLPipeline::renderDeferredLighting()
 				LLVector4 light[max_count];
 				LLVector4 col[max_count];
 
-				glVertexPointer(2, GL_FLOAT, 0, vert);
+//				glVertexPointer(2, GL_FLOAT, 0, vert);
 
 				F32 far_z = 0.f;
 
@@ -7551,13 +7443,13 @@ void LLPipeline::renderDeferredLighting()
 					count++;
 					if (count == max_count || fullscreen_lights.empty())
 					{
-						gDeferredMultiLightProgram.uniform1i("light_count", count);
-						gDeferredMultiLightProgram.uniform4fv("light", count, (GLfloat*) light);
-						gDeferredMultiLightProgram.uniform4fv("light_col", count, (GLfloat*) col);
-						gDeferredMultiLightProgram.uniform1f("far_z", far_z);
+						gDeferredMultiLightProgram.uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
+						gDeferredMultiLightProgram.uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
+						gDeferredMultiLightProgram.uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
+						gDeferredMultiLightProgram.uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
 						far_z = 0.f;
-						count = 0;
-						glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
+						count = 0; 
+						mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
 					}
 				}
 				
@@ -7565,7 +7457,9 @@ void LLPipeline::renderDeferredLighting()
 
 				bindDeferredShader(gDeferredMultiSpotLightProgram);
 
-				gDeferredMultiSpotLightProgram.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION);
+				gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+
+				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
 
 				for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter)
 				{
@@ -7588,62 +7482,23 @@ void LLPipeline::renderDeferredLighting()
 					LLColor3 col = volume->getLightColor();
 					col *= volume->getLightIntensity();
 
-					glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
-					glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
-					glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
+					gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
+					gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
+					gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+					gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
+					mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
 				}
 
-				gDeferredMultiSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION);
+				gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
 				unbindDeferredShader(gDeferredMultiSpotLightProgram);
 
-				glPopMatrix();
-				glMatrixMode(GL_MODELVIEW);
-				glPopMatrix();
+				gGL.popMatrix();
+				gGL.matrixMode(LLRender::MM_MODELVIEW);
+				gGL.popMatrix();
 			}
 		}
 
 		gGL.setColorMask(true, true);
-
-		if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2)
-		{
-			mDeferredLight[2].flush();
-
-			mScreen.bindTarget();
-			mScreen.clear(GL_COLOR_BUFFER_BIT);
-		
-			gGL.setSceneBlendType(LLRender::BT_ALPHA);
-
-			{ //mix various light maps (local, sun, gi)
-				LLFastTimer ftm(FTM_POST);
-				LLGLDisable blend(GL_BLEND);
-				LLGLDisable test(GL_ALPHA_TEST);
-				LLGLDepthTest depth(GL_FALSE);
-				LLGLDisable stencil(GL_STENCIL_TEST);
-			
-				bindDeferredShader(gDeferredPostProgram, 0, &mGIMapPost[0]);
-
-				gDeferredPostProgram.bind();
-
-				LLVertexBuffer::unbind();
-
-				glVertexPointer(2, GL_FLOAT, 0, vert);
-				glColor3f(1,1,1);
-
-				glPushMatrix();
-				glLoadIdentity();
-				glMatrixMode(GL_PROJECTION);
-				glPushMatrix();
-				glLoadIdentity();
-
-				glDrawArrays(GL_TRIANGLES, 0, 3);
-
-				glPopMatrix();
-				glMatrixMode(GL_MODELVIEW);
-				glPopMatrix();
-
-				unbindDeferredShader(gDeferredPostProgram);
-			}
-		}
 	}
 
 	{ //render non-deferred geometry (alpha, fullbright, glow)
@@ -7759,13 +7614,13 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
 	F32 proj_range = far_clip - near_clip;
 	glh::matrix4f light_proj = gl_perspective(fovy, aspect, near_clip, far_clip);
 	screen_to_light = trans * light_proj * screen_to_light;
-	shader.uniformMatrix4fv("proj_mat", 1, FALSE, screen_to_light.m);
-	shader.uniform1f("proj_near", near_clip);
-	shader.uniform3fv("proj_p", 1, p1.v);
-	shader.uniform3fv("proj_n", 1, n.v);
-	shader.uniform3fv("proj_origin", 1, screen_origin.v);
-	shader.uniform1f("proj_range", proj_range);
-	shader.uniform1f("proj_ambiance", params.mV[2]);
+	shader.uniformMatrix4fv(LLShaderMgr::PROJECTOR_MATRIX, 1, FALSE, screen_to_light.m);
+	shader.uniform1f(LLShaderMgr::PROJECTOR_NEAR, near_clip);
+	shader.uniform3fv(LLShaderMgr::PROJECTOR_P, 1, p1.v);
+	shader.uniform3fv(LLShaderMgr::PROJECTOR_N, 1, n.v);
+	shader.uniform3fv(LLShaderMgr::PROJECTOR_ORIGIN, 1, screen_origin.v);
+	shader.uniform1f(LLShaderMgr::PROJECTOR_RANGE, proj_range);
+	shader.uniform1f(LLShaderMgr::PROJECTOR_AMBIANCE, params.mV[2]);
 	S32 s_idx = -1;
 
 	for (U32 i = 0; i < 2; i++)
@@ -7776,15 +7631,15 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
 		}
 	}
 
-	shader.uniform1i("proj_shadow_idx", s_idx);
+	shader.uniform1i(LLShaderMgr::PROJECTOR_SHADOW_INDEX, s_idx);
 
 	if (s_idx >= 0)
 	{
-		shader.uniform1f("shadow_fade", 1.f-mSpotLightFade[s_idx]);
+		shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f-mSpotLightFade[s_idx]);
 	}
 	else
 	{
-		shader.uniform1f("shadow_fade", 1.f);
+		shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f);
 	}
 
 	{
@@ -7818,7 +7673,7 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
 		img = LLViewerFetchedTexture::sWhiteImagep;
 	}
 
-	S32 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION);
+	S32 channel = shader.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
 
 	if (channel > -1)
 	{
@@ -7828,9 +7683,9 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
 
 			F32 lod_range = logf(img->getWidth())/logf(2.f);
 
-			shader.uniform1f("proj_focus", focus);
-			shader.uniform1f("proj_lod", lod_range);
-			shader.uniform1f("proj_ambient_lod", llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f));
+			shader.uniform1f(LLShaderMgr::PROJECTOR_FOCUS, focus);
+			shader.uniform1f(LLShaderMgr::PROJECTOR_LOD, lod_range);
+			shader.uniform1f(LLShaderMgr::PROJECTOR_AMBIENT_LOD, llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f));
 		}
 	}
 		
@@ -7839,33 +7694,17 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
 void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
 {
 	stop_glerror();
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage());
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage());
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage());
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, mDeferredScreen.getUsage());
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, mDeferredLight[0].getUsage());
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_EDGE, mEdgeMap.getUsage());
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, mDeferredLight[1].getUsage());
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, mDeferredLight[2].getUsage());
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE);
-	shader.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MIP);
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_BLOOM);
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_NORMAL);
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_DIFFUSE);
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_SPECULAR);
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_DEPTH);
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MIN_POS);
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MAX_POS);
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_NORMAL);
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_DIFFUSE);
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MIN_POS);
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MAX_POS);
+	shader.disableTexture(LLShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage());
+	shader.disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage());
+	shader.disableTexture(LLShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage());
+	shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, mDeferredScreen.getUsage());
+	shader.disableTexture(LLShaderMgr::DEFERRED_LIGHT, mDeferredLight.getUsage());
+	shader.disableTexture(LLShaderMgr::DIFFUSE_MAP);
+	shader.disableTexture(LLShaderMgr::DEFERRED_BLOOM);
 
 	for (U32 i = 0; i < 4; i++)
 	{
-		if (shader.disableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE) > -1)
+		if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE) > -1)
 		{
 			glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
 		}
@@ -7873,16 +7712,16 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
 
 	for (U32 i = 4; i < 6; i++)
 	{
-		if (shader.disableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i) > -1)
+		if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i) > -1)
 		{
 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
 		}
 	}
 
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_NOISE);
-	shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHTFUNC);
+	shader.disableTexture(LLShaderMgr::DEFERRED_NOISE);
+	shader.disableTexture(LLShaderMgr::DEFERRED_LIGHTFUNC);
 
-	S32 channel = shader.disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
+	S32 channel = shader.disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
 	if (channel > -1)
 	{
 		LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
@@ -7908,11 +7747,11 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 	if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate)
 	{
 		BOOL skip_avatar_update = FALSE;
-		if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK)
+		if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
 		{
 			skip_avatar_update = TRUE;
 		}
-
+		
 		if (!skip_avatar_update)
 		{
 			gAgentAvatarp->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON);
@@ -7977,7 +7816,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 
 			stop_glerror();
 
-			glPushMatrix();
+			gGL.pushMatrix();
 
 			mat.set_scale(glh::vec3f(1,1,-1));
 			mat.set_translate(glh::vec3f(0,0,height*2.f));
@@ -7987,7 +7826,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 			mat = current * mat;
 
 			glh_set_current_modelview(mat);
-			glLoadMatrixf(mat.m);
+			gGL.loadMatrix(mat.m);
 
 			LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE);
 
@@ -8030,7 +7869,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 					LLPipeline::RENDER_TYPE_CLOUDS,
 					LLPipeline::END_RENDER_TYPES);	
 
-				S32 detail = gSavedSettings.getS32("RenderReflectionDetail");
+				S32 detail = RenderReflectionDetail;
 				if (detail > 0)
 				{ //mask out selected geometry based on reflection detail
 					if (detail < 4)
@@ -8054,7 +7893,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 
 				if (LLDrawPoolWater::sNeedsDistortionUpdate)
 				{
-					if (gSavedSettings.getS32("RenderReflectionDetail") > 0)
+					if (RenderReflectionDetail > 0)
 					{
 						gPipeline.grabReferences(ref_result);
 						LLGLUserClipPlane clip_plane(plane, mat, projection);
@@ -8065,7 +7904,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 				gPipeline.popRenderTypeMask();
 			}	
 			glCullFace(GL_BACK);
-			glPopMatrix();
+			gGL.popMatrix();
 			mWaterRef.flush();
 			glh_set_current_modelview(current);
 			LLPipeline::sUseOcclusion = occlusion;
@@ -8246,12 +8085,12 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
 	stateSort(shadow_cam, result);
 	
 	//generate shadow map
-	glMatrixMode(GL_PROJECTION);
-	glPushMatrix();
-	glLoadMatrixf(proj.m);
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
-	glLoadMatrixd(gGLModelView);
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.pushMatrix();
+	gGL.loadMatrix(proj.m);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.pushMatrix();
+	gGL.loadMatrix(gGLModelView);
 
 	stop_glerror();
 	gGLLastMatrix = NULL;
@@ -8262,12 +8101,8 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
 	}
 
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-			
-	glColor4f(1,1,1,1);
 	
 	stop_glerror();
-
-	gGL.setColorMask(false, false);
 	
 	//glCullFace(GL_FRONT);
 
@@ -8278,6 +8113,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
 		{ //occlusion program is general purpose depth-only no-textures
 			gOcclusionProgram.bind();
 		}
+
+		gGL.diffuseColor4f(1,1,1,1);
+		gGL.setColorMask(false, false);
+	
 		LLFastTimer ftm(FTM_SHADOW_SIMPLE);
 		gGL.getTexUnit(0)->disable();
 		for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i)
@@ -8307,14 +8146,16 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
 		gDeferredShadowAlphaMaskProgram.bind();
 		gDeferredShadowAlphaMaskProgram.setAlphaRange(0.6f, 1.f);
 		renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE);
-		glColor4f(1,1,1,1);
+		gDeferredTreeShadowProgram.bind();
+		gDeferredTreeShadowProgram.setAlphaRange(0.6f, 1.f);
 		renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE);
 	}
 
 	//glCullFace(GL_BACK);
 
+	gDeferredShadowProgram.bind();
 	gGLLastMatrix = NULL;
-	glLoadMatrixd(gGLModelView);
+	gGL.loadMatrix(gGLModelView);
 	doOcclusion(shadow_cam);
 
 	if (use_shader)
@@ -8324,10 +8165,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
 	
 	gGL.setColorMask(true, true);
 			
-	glMatrixMode(GL_PROJECTION);
-	glPopMatrix();
-	glMatrixMode(GL_MODELVIEW);
-	glPopMatrix();
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.popMatrix();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.popMatrix();
 	gGLLastMatrix = NULL;
 
 	LLPipeline::sUseOcclusion = occlude;
@@ -8509,184 +8350,6 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
 	return TRUE;
 }
 
-void LLPipeline::generateGI(LLCamera& camera, LLVector3& lightDir, std::vector<LLVector3>& vpc)
-{
-	if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) < 3)
-	{
-		return;
-	}
-
-	LLVector3 up;
-
-	//LLGLEnable depth_clamp(GL_DEPTH_CLAMP_NV);
-
-	if (lightDir.mV[2] > 0.5f)
-	{
-		up = LLVector3(1,0,0);
-	}
-	else
-	{
-		up = LLVector3(0, 0, 1);
-	}
-
-	
-	F32 gi_range = gSavedSettings.getF32("RenderGIRange");
-
-	U32 res = mGIMap.getWidth();
-
-	F32 atten = llmax(gSavedSettings.getF32("RenderGIAttenuation"), 0.001f);
-
-	//set radius to range at which distance attenuation of incoming photons is near 0
-
-	F32 lrad = sqrtf(1.f/(atten*0.01f));
-
-	F32 lrange = lrad+gi_range*0.5f;
-
-	LLVector3 pad(lrange,lrange,lrange);
-
-	glh::matrix4f view = look(LLVector3(128.f,128.f,128.f), lightDir, up);
-
-	LLVector3 cp = camera.getOrigin()+camera.getAtAxis()*(gi_range*0.5f);
-
-	glh::vec3f scp(cp.mV);
-	view.mult_matrix_vec(scp);
-	cp.setVec(scp.v);
-
-	F32 pix_width = lrange/(res*0.5f);
-
-	//move cp to the nearest pix_width
-	for (U32 i = 0; i < 3; i++)
-	{
-		cp.mV[i] = llround(cp.mV[i], pix_width);
-	}
-	
-	LLVector3 min = cp-pad;
-	LLVector3 max = cp+pad;
-	
-	//set mGIRange to range in tc space[0,1] that covers texture block of intersecting lights around a point
-	mGIRange.mV[0] = (max.mV[0]-min.mV[0])/res;
-	mGIRange.mV[1] = (max.mV[1]-min.mV[1])/res;
-	mGILightRadius = lrad/lrange*0.5f;
-
-	glh::matrix4f proj = gl_ortho(min.mV[0], max.mV[0],
-								min.mV[1], max.mV[1],
-								-max.mV[2], -min.mV[2]);
-
-	LLCamera sun_cam = camera;
-
-	glh::matrix4f eye_view = glh_get_current_modelview();
-	
-	//get eye space to camera space matrix
-	mGIMatrix = view*eye_view.inverse();
-	mGINormalMatrix = mGIMatrix.inverse().transpose();
-	mGIInvProj = proj.inverse();
-	mGIMatrixProj = proj*mGIMatrix;
-
-	//translate and scale to [0,1]
-	glh::matrix4f trans(.5f, 0.f, 0.f, .5f,
-						0.f, 0.5f, 0.f, 0.5f,
-						0.f, 0.f, 0.5f, 0.5f,
-						0.f, 0.f, 0.f, 1.f);
-
-	mGIMatrixProj = trans*mGIMatrixProj;
-
-	glh_set_current_modelview(view);
-	glh_set_current_projection(proj);
-
-	LLViewerCamera::updateFrustumPlanes(sun_cam, TRUE, FALSE, TRUE);
-
-	sun_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR);
-	static LLCullResult result;
-
-	pushRenderTypeMask();
-
-	andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE,
-								 LLPipeline::RENDER_TYPE_FULLBRIGHT,
-								 LLPipeline::RENDER_TYPE_BUMP,
-								 LLPipeline::RENDER_TYPE_VOLUME,
-								 LLPipeline::RENDER_TYPE_TREE, 
-								 LLPipeline::RENDER_TYPE_TERRAIN,
-								 LLPipeline::RENDER_TYPE_WATER,
-								 LLPipeline::RENDER_TYPE_VOIDWATER,
-								 LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW,
-								 LLPipeline::RENDER_TYPE_AVATAR,
-								 LLPipeline::RENDER_TYPE_PASS_SIMPLE,
-								 LLPipeline::RENDER_TYPE_PASS_BUMP,
-								 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
-								 LLPipeline::RENDER_TYPE_PASS_SHINY,
-								 END_RENDER_TYPES);
-
-
-	
-	S32 occlude = LLPipeline::sUseOcclusion;
-	//LLPipeline::sUseOcclusion = 0;
-	LLPipeline::sShadowRender = TRUE;
-	
-	//only render large objects into GI map
-	sMinRenderSize = gSavedSettings.getF32("RenderGIMinRenderSize");
-	
-	LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_GI_SOURCE;
-	mGIMap.bindTarget();
-	
-	F64 last_modelview[16];
-	F64 last_projection[16];
-	for (U32 i = 0; i < 16; i++)
-	{
-		last_modelview[i] = gGLLastModelView[i];
-		last_projection[i] = gGLLastProjection[i];
-		gGLLastModelView[i] = mGIModelview.m[i];
-		gGLLastProjection[i] = mGIProjection.m[i];
-	}
-
-	sun_cam.setOrigin(0.f, 0.f, 0.f);
-	updateCull(sun_cam, result);
-	stateSort(sun_cam, result);
-	
-	for (U32 i = 0; i < 16; i++)
-	{
-		gGLLastModelView[i] = last_modelview[i];
-		gGLLastProjection[i] = last_projection[i];
-	}
-
-	mGIProjection = proj;
-	mGIModelview = view;
-
-	LLGLEnable cull(GL_CULL_FACE);
-
-	//generate GI map
-	glMatrixMode(GL_PROJECTION);
-	glPushMatrix();
-	glLoadMatrixf(proj.m);
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
-	glLoadMatrixf(view.m);
-
-	stop_glerror();
-	gGLLastMatrix = NULL;
-
-	mGIMap.clear();
-
-	{
-		//LLGLEnable enable(GL_DEPTH_CLAMP_NV);
-		renderGeomDeferred(camera);
-	}
-
-	mGIMap.flush();
-	
-	glMatrixMode(GL_PROJECTION);
-	glPopMatrix();
-	glMatrixMode(GL_MODELVIEW);
-	glPopMatrix();
-	gGLLastMatrix = NULL;
-
-	LLPipeline::sUseOcclusion = occlude;
-	LLPipeline::sShadowRender = FALSE;
-	sMinRenderSize = 0.f;
-
-	popRenderTypeMask();
-
-}
-
 void LLPipeline::renderHighlight(const LLViewerObject* obj, F32 fade)
 {
 	if (obj && obj->getVolume())
@@ -8721,7 +8384,7 @@ void LLPipeline::generateHighlight(LLCamera& camera)
 	
 	if (!mHighlightSet.empty())
 	{
-		F32 transition = gFrameIntervalSeconds/gSavedSettings.getF32("RenderHighlightFadeTime");
+		F32 transition = gFrameIntervalSeconds/RenderHighlightFadeTime;
 
 		LLGLDisable test(GL_ALPHA_TEST);
 		LLGLDepthTest depth(GL_FALSE);
@@ -8767,11 +8430,23 @@ void LLPipeline::generateHighlight(LLCamera& camera)
 
 void LLPipeline::generateSunShadow(LLCamera& camera)
 {
-	if (!sRenderDeferred || gSavedSettings.getS32("RenderShadowDetail") <= 0)
+	if (!sRenderDeferred || RenderShadowDetail <= 0)
 	{
 		return;
 	}
 
+	BOOL skip_avatar_update = FALSE;
+	if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
+	{
+
+		skip_avatar_update = TRUE;
+	}
+
+	if (!skip_avatar_update)
+	{
+		gAgentAvatarp->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON);
+	}
+
 	F64 last_modelview[16];
 	F64 last_projection[16];
 	for (U32 i = 0; i < 16; i++)
@@ -8814,25 +8489,25 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 	glh::matrix4f proj[6];
 	
 	//clip contains parallel split distances for 3 splits
-	LLVector3 clip = gSavedSettings.getVector3("RenderShadowClipPlanes");
+	LLVector3 clip = RenderShadowClipPlanes;
 
 	//F32 slope_threshold = gSavedSettings.getF32("RenderShadowSlopeThreshold");
 
 	//far clip on last split is minimum of camera view distance and 128
 	mSunClipPlanes = LLVector4(clip, clip.mV[2] * clip.mV[2]/clip.mV[1]);
 
-	clip = gSavedSettings.getVector3("RenderShadowOrthoClipPlanes");
+	clip = RenderShadowOrthoClipPlanes;
 	mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]);
 
 	//currently used for amount to extrude frusta corners for constructing shadow frusta
-	LLVector3 n = gSavedSettings.getVector3("RenderShadowNearDist");
+	LLVector3 n = RenderShadowNearDist;
 	//F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] };
 
 	//put together a universal "near clip" plane for shadow frusta
 	LLPlane shadow_near_clip;
 	{
 		LLVector3 p = gAgent.getPositionAgent();
-		p += mSunDir * gSavedSettings.getF32("RenderFarClip")*2.f;
+		p += mSunDir * RenderFarClip*2.f;
 		shadow_near_clip.setVec(p, mSunDir);
 	}
 
@@ -8885,11 +8560,15 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 				mShadowFrustPoints[3].clear();
 			}
 			popRenderTypeMask();
+
+			if (!skip_avatar_update)
+			{
+				gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
+			}
+
 			return;
 		}
 
-		generateGI(camera, lightDir, fp);
-
 		//get good split distances for frustum
 		for (U32 i = 0; i < fp.size(); ++i)
 		{
@@ -8915,7 +8594,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 
 		F32 range = far_clip-near_clip;
 
-		LLVector3 split_exp = gSavedSettings.getVector3("RenderShadowSplitExponent");
+		LLVector3 split_exp = RenderShadowSplitExponent;
 
 		F32 da = 1.f-llmax( fabsf(lightDir*up), fabsf(lightDir*camera.getLeftAxis()) );
 		
@@ -9126,7 +8805,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 			mShadowError.mV[j] /= wpf.size();
 			mShadowError.mV[j] /= size.mV[0];
 
-			if (mShadowError.mV[j] > gSavedSettings.getF32("RenderShadowErrorCutoff"))
+			if (mShadowError.mV[j] > RenderShadowErrorCutoff)
 			{ //just use ortho projection
 				mShadowFOV.mV[j] = -1.f;
 				origin.clearVec();
@@ -9169,7 +8848,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 				fovx = acos(fovx);
 				fovz = acos(fovz);
 
-				F32 cutoff = llmin(gSavedSettings.getF32("RenderShadowFOVCutoff"), 1.4f);
+				F32 cutoff = llmin((F32) RenderShadowFOVCutoff, 1.4f);
 				
 				mShadowFOV.mV[j] = fovx;
 				
@@ -9313,7 +8992,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 
 	
 	//hack to disable projector shadows 
-	bool gen_shadow = gSavedSettings.getS32("RenderShadowDetail") > 1;
+	bool gen_shadow = RenderShadowDetail > 1;
 
 	if (gen_shadow)
 	{
@@ -9452,7 +9131,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 	}
 
 
-	if (!gSavedSettings.getBOOL("CameraOffset"))
+	if (!CameraOffset)
 	{
 		glh_set_current_modelview(saved_view);
 		glh_set_current_projection(saved_proj);
@@ -9461,10 +9140,10 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 	{
 		glh_set_current_modelview(view[1]);
 		glh_set_current_projection(proj[1]);
-		glLoadMatrixf(view[1].m);
-		glMatrixMode(GL_PROJECTION);
-		glLoadMatrixf(proj[1].m);
-		glMatrixMode(GL_MODELVIEW);
+		gGL.loadMatrix(view[1].m);
+		gGL.matrixMode(LLRender::MM_PROJECTION);
+		gGL.loadMatrix(proj[1].m);
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
 	}
 	gGL.setColorMask(true, false);
 
@@ -9475,6 +9154,11 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 	}
 
 	popRenderTypeMask();
+
+	if (!skip_avatar_update)
+	{
+		gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
+	}
 }
 
 void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture)
@@ -9596,24 +9280,24 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
 	tdim.mV[0] = fabsf(half_height.dot3(left).getF32());
 	tdim.mV[1] = fabsf(half_height.dot3(up).getF32());
 
-	glMatrixMode(GL_PROJECTION);
-	glPushMatrix();
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.pushMatrix();
 	
 	F32 distance = (pos-camera.getOrigin()).length();
 	F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG;
 	F32 aspect = tdim.mV[0]/tdim.mV[1];
 	glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f);
 	glh_set_current_projection(persp);
-	glLoadMatrixf(persp.m);
+	gGL.loadMatrix(persp.m);
 
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.pushMatrix();
 	glh::matrix4f mat;
 	camera.getOpenGLTransform(mat.m);
 
 	mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat;
 
-	glLoadMatrixf(mat.m);
+	gGL.loadMatrix(mat.m);
 	glh_set_current_modelview(mat);
 
 	glClearColor(0.0f,0.0f,0.0f,0.0f);
@@ -9681,14 +9365,19 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
 
 		gGL.flush();
 
-		glPushMatrix();
-		glLoadIdentity();
-		glMatrixMode(GL_PROJECTION);
-		glPushMatrix();
-		glLoadIdentity();
+		gGL.pushMatrix();
+		gGL.loadIdentity();
+		gGL.matrixMode(LLRender::MM_PROJECTION);
+		gGL.pushMatrix();
+		gGL.loadIdentity();
 
 		static const F32 clip_plane = 0.99999f;
 
+		if (LLGLSLShader::sNoFixedFunction)
+		{
+			gUIProgram.bind();
+		}
+
 		gGL.color4ub(64,64,64,255);
 		gGL.begin(LLRender::QUADS);
 		gGL.vertex3f(-1, -1, clip_plane);
@@ -9698,9 +9387,14 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
 		gGL.end();
 		gGL.flush();
 
-		glPopMatrix();
-		glMatrixMode(GL_MODELVIEW);
-		glPopMatrix();
+		if (LLGLSLShader::sNoFixedFunction)
+		{
+			gUIProgram.unbind();
+		}
+
+		gGL.popMatrix();
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
+		gGL.popMatrix();
 	}
 
 	avatar->mImpostor.flush();
@@ -9714,10 +9408,10 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
 	sShadowRender = FALSE;
 	popRenderTypeMask();
 
-	glMatrixMode(GL_PROJECTION);
-	glPopMatrix();
-	glMatrixMode(GL_MODELVIEW);
-	glPopMatrix();
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.popMatrix();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.popMatrix();
 
 	avatar->mNeedsImpostorUpdate = FALSE;
 	avatar->cacheImpostorValues();
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 27ee2745b502ded96937f976b86c7f161353ff34..584e6e4c231319f73420cd4fa8797cddb63c3a36 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -72,7 +72,7 @@ BOOL compute_min_max(LLMatrix4& box, LLVector2& min, LLVector2& max); // Shouldn
 bool LLRayAABB(const LLVector3 &center, const LLVector3 &size, const LLVector3& origin, const LLVector3& dir, LLVector3 &coord, F32 epsilon = 0);
 BOOL setup_hud_matrices(); // use whole screen to render hud
 BOOL setup_hud_matrices(const LLRect& screen_region); // specify portion of screen (in pixels) to render hud attachments from (for picking)
-glh::matrix4f glh_copy_matrix(GLdouble* src);
+glh::matrix4f glh_copy_matrix(F32* src);
 glh::matrix4f glh_get_current_modelview();
 void glh_set_current_modelview(const glh::matrix4f& mat);
 glh::matrix4f glh_get_current_projection();
@@ -248,7 +248,7 @@ class LLPipeline
 	void renderGeomDeferred(LLCamera& camera);
 	void renderGeomPostDeferred(LLCamera& camera);
 	void renderGeomShadow(LLCamera& camera);
-	void bindDeferredShader(LLGLSLShader& shader, U32 light_index = 0, LLRenderTarget* gi_source = NULL, LLRenderTarget* last_gi_post = NULL, U32 noise_map = 0xFFFFFFFF);
+	void bindDeferredShader(LLGLSLShader& shader, U32 light_index = 0, U32 noise_map = 0xFFFFFFFF);
 	void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep);
 
 	void unbindDeferredShader(LLGLSLShader& shader);
@@ -262,7 +262,6 @@ class LLPipeline
 
 
 	void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, LLCullResult& result, BOOL use_shader = TRUE, BOOL use_occlusion = TRUE);
-	void generateGI(LLCamera& camera, LLVector3& lightDir, std::vector<LLVector3>& vpc);
 	void renderHighlights();
 	void renderDebug();
 	void renderPhysicsDisplay();
@@ -361,6 +360,7 @@ class LLPipeline
 
 	static void updateRenderDeferred();
 	static void refreshRenderDeferred();
+	static void refreshCachedSettings();
 
 	static void throttleNewMemoryAllocation(BOOL disable);
 
@@ -531,15 +531,16 @@ class LLPipeline
 	LLRenderTarget			mScreen;
 	LLRenderTarget			mUIScreen;
 	LLRenderTarget			mDeferredScreen;
+	LLRenderTarget			mFXAABuffer;
 	LLRenderTarget			mEdgeMap;
 	LLRenderTarget			mDeferredDepth;
-	LLRenderTarget			mDeferredLight[3];
-	LLRenderTarget			mGIMap;
-	LLRenderTarget			mGIMapPost[2];
-	LLRenderTarget			mLuminanceMap;
+	LLRenderTarget			mDeferredLight;
 	LLRenderTarget			mHighlight;
 	LLRenderTarget			mPhysicsDisplay;
 
+	//utility buffer for rendering post effects, gets abused by renderDeferredLighting
+	LLPointer<LLVertexBuffer> mDeferredVB;
+
 	//sun shadow map
 	LLRenderTarget			mShadow[6];
 	std::vector<LLVector3>	mShadowFrustPoints[4];
@@ -585,6 +586,7 @@ class LLPipeline
 
 	LLColor4				mSunDiffuse;
 	LLVector3				mSunDir;
+	LLVector3				mTransformedSunDir;
 
 	BOOL					mInitialized;
 	BOOL					mVertexShadersEnabled;
@@ -770,6 +772,79 @@ class LLPipeline
 
 	//debug use
 	static U32              sCurRenderPoolType ;
+
+	//cached settings
+	static BOOL WindLightUseAtmosShaders;
+	static BOOL VertexShaderEnable;
+	static BOOL RenderAvatarVP;
+	static BOOL RenderDeferred;
+	static F32 RenderDeferredSunWash;
+	static U32 RenderFSAASamples;
+	static U32 RenderResolutionDivisor;
+	static BOOL RenderUIBuffer;
+	static S32 RenderShadowDetail;
+	static BOOL RenderDeferredSSAO;
+	static F32 RenderShadowResolutionScale;
+	static BOOL RenderLocalLights;
+	static BOOL RenderDelayCreation;
+	static BOOL RenderAnimateRes;
+	static BOOL FreezeTime;
+	static S32 DebugBeaconLineWidth;
+	static F32 RenderHighlightBrightness;
+	static LLColor4 RenderHighlightColor;
+	static F32 RenderHighlightThickness;
+	static BOOL RenderSpotLightsInNondeferred;
+	static LLColor4 PreviewAmbientColor;
+	static LLColor4 PreviewDiffuse0;
+	static LLColor4 PreviewSpecular0;
+	static LLColor4 PreviewDiffuse1;
+	static LLColor4 PreviewSpecular1;
+	static LLColor4 PreviewDiffuse2;
+	static LLColor4 PreviewSpecular2;
+	static LLVector3 PreviewDirection0;
+	static LLVector3 PreviewDirection1;
+	static LLVector3 PreviewDirection2;
+	static F32 RenderGlowMinLuminance;
+	static F32 RenderGlowMaxExtractAlpha;
+	static F32 RenderGlowWarmthAmount;
+	static LLVector3 RenderGlowLumWeights;
+	static LLVector3 RenderGlowWarmthWeights;
+	static S32 RenderGlowResolutionPow;
+	static S32 RenderGlowIterations;
+	static F32 RenderGlowWidth;
+	static F32 RenderGlowStrength;
+	static BOOL RenderDepthOfField;
+	static F32 CameraFocusTransitionTime;
+	static F32 CameraFNumber;
+	static F32 CameraFocalLength;
+	static F32 CameraFieldOfView;
+	static F32 RenderShadowNoise;
+	static F32 RenderShadowBlurSize;
+	static F32 RenderSSAOScale;
+	static U32 RenderSSAOMaxScale;
+	static F32 RenderSSAOFactor;
+	static LLVector3 RenderSSAOEffect;
+	static F32 RenderShadowOffsetError;
+	static F32 RenderShadowBiasError;
+	static F32 RenderShadowOffset;
+	static F32 RenderShadowBias;
+	static F32 RenderSpotShadowOffset;
+	static F32 RenderSpotShadowBias;
+	static F32 RenderEdgeDepthCutoff;
+	static F32 RenderEdgeNormCutoff;
+	static LLVector3 RenderShadowGaussian;
+	static F32 RenderShadowBlurDistFactor;
+	static BOOL RenderDeferredAtmospheric;
+	static S32 RenderReflectionDetail;
+	static F32 RenderHighlightFadeTime;
+	static LLVector3 RenderShadowClipPlanes;
+	static LLVector3 RenderShadowOrthoClipPlanes;
+	static LLVector3 RenderShadowNearDist;
+	static F32 RenderFarClip;
+	static LLVector3 RenderShadowSplitExponent;
+	static F32 RenderShadowErrorCutoff;
+	static F32 RenderShadowFOVCutoff;
+	static BOOL CameraOffset;
 };
 
 void render_bbox(const LLVector3 &min, const LLVector3 &max);
diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml
index 36af47582477e3ee27868b63b2252fe87e7d9f8a..c7e9ec781daa343bdbf3ff75220412b4df54548e 100644
--- a/indra/newview/skins/default/xui/en/floater_about.xml
+++ b/indra/newview/skins/default/xui/en/floater_about.xml
@@ -196,34 +196,36 @@ Dummy Name replaced at run time
        top="5"
        width="435"
        word_wrap="true">
-3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
-APR Copyright (C) 2000-2004 The Apache Software Foundation
-Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
-cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
-DBus/dbus-glib Copyright (C) 2002, 2003  CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
-expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
-FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
-GL Copyright (C) 1999-2004 Brian Paul.
-GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia.
-google-perftools Copyright (c) 2005, Google Inc.
-Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
-jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
-jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
-ogg/vorbis Copyright (C) 2001, Xiphophorus
-OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
-PCRE Copyright (c) 1997-2008 University of Cambridge
-SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
-SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
-xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
-zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler.
-google-perftools Copyright (c) 2005, Google Inc.
+        3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
+        APR Copyright (C) 2000-2004 The Apache Software Foundation
+        Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
+        cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
+        DBus/dbus-glib Copyright (C) 2002, 2003  CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
+        expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
+        FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
+        GL Copyright (C) 1999-2004 Brian Paul.
+        GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia.
+        google-perftools Copyright (c) 2005, Google Inc.
+        Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
+        jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
+        jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
+        ogg/vorbis Copyright (C) 2001, Xiphophorus
+        OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
+        PCRE Copyright (c) 1997-2008 University of Cambridge
+        SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
+        SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+        xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
+        zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler.
+        google-perftools Copyright (c) 2005, Google Inc.
 
-Second Life Viewer uses Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (and its Licensors). All Rights Reserved. See www.havok.com for details.
+        Second Life Viewer uses Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (and its Licensors). All Rights Reserved. See www.havok.com for details.
 
-All rights reserved.  See licenses.txt for details.
+        This software contains source code provided by NVIDIA Corporation.
 
-Voice chat Audio coding: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
-        </text_editor>
+        All rights reserved.  See licenses.txt for details.
+
+        Voice chat Audio coding: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
+      </text_editor>
       </panel>
     </tab_container>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 63e50b0b9f7ceba094b453f89d22adca97e917f5..cc0cff61138369ac7fe2d5f828d6d813cfdb695b 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -2550,19 +2550,6 @@
             <menu_item_check.on_enable
                  function="Advanced.EnableRenderDeferredOptions" />
           </menu_item_check>
-          <menu_item_check
-                   label="   Global Illumination (experimental)"
-                   name="Global Illumination">
-            <menu_item_check.on_check
-             function="CheckControl"
-             parameter="RenderDeferredGI" />
-            <menu_item_check.on_click
-             function="ToggleControl"
-             parameter="RenderDeferredGI" />
-            <menu_item_check.on_enable
-                 function="Advanced.EnableRenderDeferredOptions" />
-          </menu_item_check>
-
           <menu_item_separator />
 
           <menu_item_check
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index f7666bdc4ca9bd18191c1b6ce52c81808f06f9e5..c25c1f23f51cb91a62f447af22a21c7145240fe2 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -204,20 +204,6 @@
 		name="LocalLights"
 		 top_pad="1"
 		 width="256" />
-		  <check_box
-		 control_name="VertexShaderEnable"
-		 height="16"
-		 initial_value="true"
-		 label="Basic shaders"
-		 layout="topleft"
-		 left_delta="0"
-		 name="BasicShaders"
-		 tool_tip="Disabling this option may prevent some graphics card drivers from crashing"
-		 top_pad="1"
-		 width="315">
-			<check_box.commit_callback
-		     function="Pref.VertexShaderEnable" />
-		</check_box>
 		<check_box
 		 control_name="WindLightUseAtmosShaders"
 		 height="16"