diff options
Diffstat (limited to 'indra')
56 files changed, 1638 insertions, 289 deletions
| diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 2e7147a3b4..71d24bcf13 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -56,7 +56,7 @@ BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)  LLShaderFeatures::LLShaderFeatures()  : calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false),  hasTransport(false), hasSkinning(false), hasObjectSkinning(false), hasAtmospherics(false), isSpecular(false), -hasGamma(false), hasLighting(false), calculatesAtmospherics(false) +hasGamma(false), hasLighting(false), calculatesAtmospherics(false), disableTextureIndex(false)  {  } diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index d46ddbbe18..392688bba3 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -45,6 +45,7 @@ public:  	bool hasObjectSkinning;  	bool hasAtmospherics;  	bool hasGamma; +	bool disableTextureIndex;  	// char numLights; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 049dd4346b..0532510996 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -203,7 +203,9 @@ void LLTexUnit::disable(void)  		if (mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE &&  			mIndex < gGLManager.mNumTextureUnits)  		{ +			stop_glerror();  			glDisable(sGLTextureType[mCurrTexType]); +			stop_glerror();  		}  		mCurrTexType = TT_NONE; @@ -403,6 +405,7 @@ void LLTexUnit::unbind(eTextureType type)  		activate();  		mCurrTexture = 0;  		glBindTexture(sGLTextureType[type], 0); +		stop_glerror();  	}  } diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index b8f9c60ca9..6fb1e6e437 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -209,7 +209,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)  		if (features->hasWaterFog)  		{ -			if (!shader->attachObject("lighting/lightWaterF.glsl")) +			if (features->disableTextureIndex) +			{ +				if (!shader->attachObject("lighting/lightWaterNonIndexedF.glsl")) +				{ +					return FALSE; +				} +			} +			else if (!shader->attachObject("lighting/lightWaterF.glsl"))  			{  				return FALSE;  			} @@ -217,7 +224,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)  		else  		{ -			if (!shader->attachObject("lighting/lightF.glsl")) +			if (features->disableTextureIndex) +			{ +				if (!shader->attachObject("lighting/lightNonIndexedF.glsl")) +				{ +					return FALSE; +				} +			} +			else if (!shader->attachObject("lighting/lightF.glsl"))  			{  				return FALSE;  			} @@ -230,14 +244,28 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)  		if (features->isShiny && features->hasWaterFog)  		{ -			if (!shader->attachObject("lighting/lightFullbrightShinyWaterF.glsl")) +			if (features->disableTextureIndex) +			{ +				if (!shader->attachObject("lighting/lightFullbrightShinyWaterNonIndexedF.glsl")) +				{ +					return FALSE; +				} +			} +			else if (!shader->attachObject("lighting/lightFullbrightShinyWaterF.glsl"))  			{  				return FALSE;  			}  		}  		else if (features->hasWaterFog)  		{ -			if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl")) +			if (features->disableTextureIndex) +			{ +				if (!shader->attachObject("lighting/lightFullbrightWaterNonIndexedF.glsl")) +				{ +					return FALSE; +				} +			} +			else if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl"))  			{  				return FALSE;  			} @@ -245,7 +273,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)  		else if (features->isShiny)  		{ -			if (!shader->attachObject("lighting/lightFullbrightShinyF.glsl")) +			if (features->disableTextureIndex) +			{ +				if (!shader->attachObject("lighting/lightFullbrightShinyNonIndexedF.glsl")) +				{ +					return FALSE; +				} +			} +			else if (!shader->attachObject("lighting/lightFullbrightShinyF.glsl"))  			{  				return FALSE;  			} @@ -253,7 +288,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)  		else  		{ -			if (!shader->attachObject("lighting/lightFullbrightF.glsl")) +			if (features->disableTextureIndex) +			{ +				if (!shader->attachObject("lighting/lightFullbrightNonIndexedF.glsl")) +				{ +					return FALSE; +				} +			} +			else if (!shader->attachObject("lighting/lightFullbrightF.glsl"))  			{  				return FALSE;  			} @@ -266,7 +308,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)  		if (features->hasWaterFog)  		{ -			if (!shader->attachObject("lighting/lightShinyWaterF.glsl")) +			if (features->disableTextureIndex) +			{ +				if (!shader->attachObject("lighting/lightShinyWaterNonIndexedF.glsl")) +				{ +					return FALSE; +				} +			} +			else if (!shader->attachObject("lighting/lightShinyWaterF.glsl"))  			{  				return FALSE;  			} @@ -274,7 +323,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)  		else   		{ -			if (!shader->attachObject("lighting/lightShinyF.glsl")) +			if (features->disableTextureIndex) +			{ +				if (!shader->attachObject("lighting/lightShinyNonIndexedF.glsl")) +				{ +					return FALSE; +				} +			} +			else if (!shader->attachObject("lighting/lightShinyF.glsl"))  			{  				return FALSE;  			} diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 8c9171ccf4..f715a8e9ba 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1497,7 +1497,14 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const  	}  	if (data_mask & MAP_VERTEX)  	{ -		glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); +		if (data_mask & MAP_TEXTURE_INDEX) +		{ +			glVertexPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); +		} +		else +		{ +			glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); +		}  	}  	llglassertok(); diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index a9f22193f8..0c4b241537 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -130,6 +130,9 @@ public:  		TYPE_CLOTHWEIGHT,  		TYPE_MAX,  		TYPE_INDEX, +		 +		//no actual additional data, but indicates position.w is texture index +		TYPE_TEXTURE_INDEX,  	};  	enum {  		MAP_VERTEX = (1<<TYPE_VERTEX), @@ -144,6 +147,7 @@ public:  		MAP_WEIGHT = (1<<TYPE_WEIGHT),  		MAP_WEIGHT4 = (1<<TYPE_WEIGHT4),  		MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT), +		MAP_TEXTURE_INDEX = (1<<TYPE_TEXTURE_INDEX),  	};  protected: diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index 3b12a07a27..f6b7f42c22 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -9,9 +9,10 @@  #extension GL_ARB_texture_rectangle : enable -uniform sampler2D diffuseMap;  uniform sampler2DRect depthMap; +vec4 diffuseLookup(vec2 texcoord); +  uniform mat4 shadow_matrix[6];  uniform vec4 shadow_clip;  uniform vec2 screen_res; @@ -47,7 +48,7 @@ void main()  	vec4 pos = vec4(vary_position, 1.0); -	vec4 diff= texture2D(diffuseMap, gl_TexCoord[0].xy); +	vec4 diff= diffuseLookup(gl_TexCoord[0].xy);  	vec4 col = vec4(vary_ambient + vary_directional.rgb, gl_Color.a);  	vec4 color = diff * col; diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index 2691fc8ded..5890c30d8f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -23,6 +23,7 @@ varying vec3 vary_fragcoord;  varying vec3 vary_position;  varying vec3 vary_light;  varying vec3 vary_pointlight_col; +varying float vary_texture_index;  uniform float near_clip;  uniform float shadow_offset; @@ -61,11 +62,13 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa  void main()  {  	//transform vertex -	gl_Position = ftransform();  +	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 * gl_Vertex); +	vec4 pos = (gl_ModelViewMatrix * vert);  	vec3 norm = normalize(gl_NormalMatrix * gl_Normal);  	float dp_directional_light = max(0.0, dot(norm, gl_LightSource[0].position.xyz)); @@ -102,7 +105,7 @@ void main()  	gl_FogFragCoord = pos.z; -	pos = gl_ModelViewProjectionMatrix * gl_Vertex; +	pos = gl_ModelViewProjectionMatrix * vert;  	vary_fragcoord.xyz = 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 new file mode 100644 index 0000000000..536bacd23c --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl @@ -0,0 +1,21 @@ +/**  + * @file avatarEyesV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +varying vec3 vary_normal; + +void main() +{ +	//transform vertex +	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;  +	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; +	 +	vary_normal = normalize(gl_NormalMatrix * gl_Normal); + +	gl_FrontColor = gl_Color; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index 35cfb80c93..f71d9f0b49 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -20,3 +20,4 @@ void main()  	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 new file mode 100644 index 0000000000..1bbaeb44ff --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl @@ -0,0 +1,50 @@ +/**  + * @file diffuseIndexedF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +varying float vary_texture_index; +varying vec3 vary_normal; + +uniform sampler2D tex0; +uniform sampler2D tex1; +uniform sampler2D tex2; +uniform sampler2D tex3; +uniform sampler2D tex4; +uniform sampler2D tex5; +uniform sampler2D tex6; +uniform sampler2D tex7; + +vec4 diffuseLookup(vec2 texcoord) +{ +	switch (int(vary_texture_index+0.25)) +	{ +		case 0: return texture2D(tex0, texcoord); +		case 1: return texture2D(tex1, texcoord); +		case 2: return texture2D(tex2, texcoord); +		case 3: return texture2D(tex3, texcoord); +		case 4: return texture2D(tex4, texcoord); +		case 5: return texture2D(tex5, texcoord); +		case 6: return texture2D(tex6, texcoord); +		case 7: return texture2D(tex7, texcoord); +	} + +	return vec4(0,0,0,0); +} + +void main()  +{ +	vec3 col = gl_Color.rgb * diffuseLookup(gl_TexCoord[0].xy).rgb; + +	//col = vec3(vary_texture_index*0.25, 0, 0); +	 +	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 +	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/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl index 03d3322cb6..b8de629fc8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl @@ -8,13 +8,15 @@  #version 120  varying vec3 vary_normal; +varying float vary_texture_index;  void main()  {  	//transform vertex -	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;  +	gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz, 1.0);   	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; +	vary_texture_index = gl_Vertex.w;  	vary_normal = normalize(gl_NormalMatrix * gl_Normal);  	gl_FrontColor = gl_Color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index 3429877397..30231039b0 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -9,56 +9,48 @@  #extension GL_ARB_texture_rectangle : enable -uniform sampler2D diffuseMap; -uniform sampler2DRect depthMap; -uniform sampler2D noiseMap; - -uniform vec4 shadow_clip; -uniform vec2 screen_res; +varying float vary_texture_index; + +uniform sampler2D tex0; +uniform sampler2D tex1; +uniform sampler2D tex2; +uniform sampler2D tex3; +uniform sampler2D tex4; +uniform sampler2D tex5; +uniform sampler2D tex6; +uniform sampler2D tex7; + +vec4 textureLookup(vec2 texcoord) +{ +	switch (int(vary_texture_index+0.25)) +	{ +		case 0: return texture2D(tex0, texcoord); +		case 1: return texture2D(tex1, texcoord); +		case 2: return texture2D(tex2, texcoord); +		case 3: return texture2D(tex3, texcoord); +		case 4: return texture2D(tex4, texcoord); +		case 5: return texture2D(tex5, texcoord); +		case 6: return texture2D(tex6, texcoord); +		case 7: return texture2D(tex7, texcoord); +	} + +	return vec4(0,0,0,0); +}  vec3 fullbrightAtmosTransport(vec3 light);  vec3 fullbrightScaleSoftClip(vec3 light); -varying vec3 vary_ambient; -varying vec3 vary_directional; -varying vec4 vary_position; -varying vec3 vary_normal; -varying vec3 vary_fragcoord; - -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; -	 -	vec3 samp_pos = getPosition(frag).xyz;  -	  	float shadow = 1.0; -	vec4 pos = vary_position; -	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy)*gl_Color; +	vec4 color = textureLookup(gl_TexCoord[0].xy)*gl_Color;  	color.rgb = fullbrightAtmosTransport(color.rgb);  	color.rgb = fullbrightScaleSoftClip(color.rgb); -	//gl_FragColor = gl_Color;  	gl_FragColor = color; -	//gl_FragColor = vec4(1,0,1,1); -	  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl index 6c38d220e2..6890360c56 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl @@ -14,30 +14,23 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);  vec3 scaleDownLight(vec3 light);  vec3 scaleUpLight(vec3 light); -varying vec3 vary_ambient; -varying vec3 vary_directional; -varying vec3 vary_normal; -varying vec3 vary_fragcoord; -uniform float near_clip; -varying vec4 vary_position; +varying float vary_texture_index;  void main()  {  	//transform vertex -	gl_Position = ftransform();  +	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 * gl_Vertex); -	vary_position = pos; -		 +	vec4 pos = (gl_ModelViewMatrix * vert); +				  	calcAtmospherics(pos.xyz);  	gl_FrontColor = gl_Color;  	gl_FogFragCoord = pos.z; -	 -	pos = gl_ModelViewProjectionMatrix * gl_Vertex; -	vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); -	  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index 6dfc1b952c..bd4875f3ff 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -9,13 +9,14 @@  #extension GL_ARB_texture_rectangle : enable -uniform sampler2D diffuseMap;  uniform sampler2DRectShadow shadowMap0;  uniform sampler2DRectShadow shadowMap1;  uniform sampler2DRectShadow shadowMap2;  uniform sampler2DRectShadow shadowMap3;  uniform sampler2DRect depthMap; +vec4 diffuseLookup(vec2 texcoord); +  uniform mat4 shadow_matrix[6];  uniform vec4 shadow_clip;  uniform vec2 screen_res; @@ -105,7 +106,7 @@ void main()  		}  	} -	vec4 diff= texture2D(diffuseMap, gl_TexCoord[0].xy); +	vec4 diff = diffuseLookup(gl_TexCoord[0].xy);  	vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, gl_Color.a);  	vec4 color = diff * col; diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl index f6160815eb..c6c0b0f32a 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl @@ -22,6 +22,7 @@ varying vec3 vary_directional;  varying vec3 vary_fragcoord;  varying vec3 vary_position;  varying vec3 vary_pointlight_col; +varying float vary_texture_index;  uniform float near_clip;  uniform float shadow_offset; @@ -60,11 +61,13 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa  void main()  {  	//transform vertex -	gl_Position = ftransform();  +	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 * gl_Vertex); +	vec4 pos = (gl_ModelViewMatrix * vert);  	vec3 norm = normalize(gl_NormalMatrix * gl_Normal);  	float dp_directional_light = max(0.0, dot(norm, gl_LightSource[0].position.xyz)); @@ -99,7 +102,7 @@ void main()  	gl_FogFragCoord = pos.z; -	pos = gl_ModelViewProjectionMatrix * gl_Vertex; +	pos = gl_ModelViewProjectionMatrix * vert;  	vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);  } diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl index 342bc2ab66..d5775f4506 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl @@ -7,14 +7,40 @@  #version 120 -uniform sampler2D diffuseMap; +uniform sampler2D tex0; +uniform sampler2D tex1; +uniform sampler2D tex2; +uniform sampler2D tex3; +uniform sampler2D tex4; +uniform sampler2D tex5; +uniform sampler2D tex6; +uniform sampler2D tex7; + +varying float vary_texture_index; + +vec4 diffuseLookup(vec2 texcoord) +{ +	switch (int(vary_texture_index+0.25)) +	{ +		case 0: return texture2D(tex0, texcoord); +		case 1: return texture2D(tex1, texcoord); +		case 2: return texture2D(tex2, texcoord); +		case 3: return texture2D(tex3, texcoord); +		case 4: return texture2D(tex4, texcoord); +		case 5: return texture2D(tex5, texcoord); +		case 6: return texture2D(tex6, texcoord); +		case 7: return texture2D(tex7, texcoord); +	} + +	return vec4(0,0,0,0); +}  vec3 atmosLighting(vec3 light);  vec3 scaleSoftClip(vec3 light);  void default_lighting()   { -	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color; +	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;  	color.rgb = atmosLighting(color.rgb); diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl index dad18b5883..e64b089dca 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl @@ -7,14 +7,40 @@  #version 120 -uniform sampler2D diffuseMap; -  vec3 fullbrightAtmosTransport(vec3 light);  vec3 fullbrightScaleSoftClip(vec3 light); +uniform sampler2D tex0; +uniform sampler2D tex1; +uniform sampler2D tex2; +uniform sampler2D tex3; +uniform sampler2D tex4; +uniform sampler2D tex5; +uniform sampler2D tex6; +uniform sampler2D tex7; + +varying float vary_texture_index; + +vec4 diffuseLookup(vec2 texcoord) +{ +	switch (int(vary_texture_index+0.25)) +	{ +		case 0: return texture2D(tex0, texcoord); +		case 1: return texture2D(tex1, texcoord); +		case 2: return texture2D(tex2, texcoord); +		case 3: return texture2D(tex3, texcoord); +		case 4: return texture2D(tex4, texcoord); +		case 5: return texture2D(tex5, texcoord); +		case 6: return texture2D(tex6, texcoord); +		case 7: return texture2D(tex7, texcoord); +	} + +	return vec4(0,0,0,0); +} +  void fullbright_lighting()  { -	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color; +	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;  	color.rgb = fullbrightAtmosTransport(color.rgb); diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightNonIndexedF.glsl new file mode 100644 index 0000000000..811a919d52 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightNonIndexedF.glsl @@ -0,0 +1,25 @@ +/**  + * @file lightFullbrightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +vec3 fullbrightAtmosTransport(vec3 light); +vec3 fullbrightScaleSoftClip(vec3 light); + +uniform sampler2D diffuseMap; + +void fullbright_lighting() +{ +	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color; +	 +	color.rgb = fullbrightAtmosTransport(color.rgb); +	 +	color.rgb = fullbrightScaleSoftClip(color.rgb); + +	gl_FragColor = color; +} + diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl index 73ff81e03a..f4ac789a74 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl @@ -7,15 +7,41 @@  #version 120 -uniform sampler2D diffuseMap;  uniform samplerCube environmentMap; +uniform sampler2D tex0; +uniform sampler2D tex1; +uniform sampler2D tex2; +uniform sampler2D tex3; +uniform sampler2D tex4; +uniform sampler2D tex5; +uniform sampler2D tex6; + +varying float vary_texture_index; + +vec4 diffuseLookup(vec2 texcoord) +{ +	switch (int(vary_texture_index+0.25)) +	{ +		case 0: return texture2D(tex0, texcoord); +		case 1: return texture2D(tex1, texcoord); +		case 2: return texture2D(tex2, texcoord); +		case 3: return texture2D(tex3, texcoord); +		case 4: return texture2D(tex4, texcoord); +		case 5: return texture2D(tex5, texcoord); +		case 6: return texture2D(tex6, texcoord); +	} + +	return vec4(0,0,0,0); +} + +  vec3 fullbrightShinyAtmosTransport(vec3 light);  vec3 fullbrightScaleSoftClip(vec3 light);  void fullbright_shiny_lighting()  { -	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy); +	vec4 color = diffuseLookup(gl_TexCoord[0].xy);  	color.rgb *= gl_Color.rgb;  	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	 diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyNonIndexedF.glsl new file mode 100644 index 0000000000..51a7ddb89a --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyNonIndexedF.glsl @@ -0,0 +1,32 @@ +/**  + * @file lightFullbrightShinyF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +uniform samplerCube environmentMap; +uniform sampler2D diffuseMap; + +vec3 fullbrightShinyAtmosTransport(vec3 light); +vec3 fullbrightScaleSoftClip(vec3 light); + +void fullbright_shiny_lighting() +{ +	vec4 color = texture2D(diffuseMap, 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 index 9b4b584369..277170e8af 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl @@ -7,8 +7,33 @@  #version 120 -uniform sampler2D diffuseMap; +  uniform samplerCube environmentMap; +uniform sampler2D tex0; +uniform sampler2D tex1; +uniform sampler2D tex2; +uniform sampler2D tex3; +uniform sampler2D tex4; +uniform sampler2D tex5; +uniform sampler2D tex6; + +varying float vary_texture_index; + +vec4 diffuseLookup(vec2 texcoord) +{ +	switch (int(vary_texture_index+0.25)) +	{ +		case 0: return texture2D(tex0, texcoord); +		case 1: return texture2D(tex1, texcoord); +		case 2: return texture2D(tex2, texcoord); +		case 3: return texture2D(tex3, texcoord); +		case 4: return texture2D(tex4, texcoord); +		case 5: return texture2D(tex5, texcoord); +		case 6: return texture2D(tex6, texcoord); +	} + +	return vec4(0,0,0,0); +}  vec3 fullbrightShinyAtmosTransport(vec3 light);  vec3 fullbrightScaleSoftClip(vec3 light); @@ -16,7 +41,7 @@ vec4 applyWaterFog(vec4 color);  void fullbright_shiny_lighting_water()  { -	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy); +	vec4 color = diffuseLookup(gl_TexCoord[0].xy);  	color.rgb *= gl_Color.rgb;  	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	 diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterNonIndexedF.glsl new file mode 100644 index 0000000000..a9a95940e6 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterNonIndexedF.glsl @@ -0,0 +1,32 @@ +/**  + * @file lightFullbrightShinyWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +  +#version 120 + + +uniform samplerCube environmentMap; +uniform sampler2D diffuseMap; + +vec3 fullbrightShinyAtmosTransport(vec3 light); +vec3 fullbrightScaleSoftClip(vec3 light); +vec4 applyWaterFog(vec4 color); + +void fullbright_shiny_lighting_water() +{ +	vec4 color = texture2D(diffuseMap,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 index 3d46c8d874..37e33059a6 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl @@ -7,14 +7,40 @@  #version 120 -uniform sampler2D diffuseMap; +uniform sampler2D tex0; +uniform sampler2D tex1; +uniform sampler2D tex2; +uniform sampler2D tex3; +uniform sampler2D tex4; +uniform sampler2D tex5; +uniform sampler2D tex6; +uniform sampler2D tex7; + +varying float vary_texture_index; + +vec4 diffuseLookup(vec2 texcoord) +{ +	switch (int(vary_texture_index+0.25)) +	{ +		case 0: return texture2D(tex0, texcoord); +		case 1: return texture2D(tex1, texcoord); +		case 2: return texture2D(tex2, texcoord); +		case 3: return texture2D(tex3, texcoord); +		case 4: return texture2D(tex4, texcoord); +		case 5: return texture2D(tex5, texcoord); +		case 6: return texture2D(tex6, texcoord); +		case 7: return texture2D(tex7, texcoord); +	} + +	return vec4(0,0,0,0); +}  vec3 fullbrightAtmosTransport(vec3 light);  vec4 applyWaterFog(vec4 color);  void fullbright_lighting_water()  { -	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color; +	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;  	color.rgb = fullbrightAtmosTransport(color.rgb); diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterNonIndexedF.glsl new file mode 100644 index 0000000000..3d46c8d874 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterNonIndexedF.glsl @@ -0,0 +1,23 @@ +/**  + * @file lightFullbrightWaterF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +uniform sampler2D diffuseMap; + +vec3 fullbrightAtmosTransport(vec3 light); +vec4 applyWaterFog(vec4 color); + +void fullbright_lighting_water() +{ +	vec4 color = texture2D(diffuseMap, 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/lightNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightNonIndexedF.glsl new file mode 100644 index 0000000000..787eeb7af6 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightNonIndexedF.glsl @@ -0,0 +1,25 @@ +/**  + * @file lightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +uniform sampler2D diffuseMap; + +vec3 atmosLighting(vec3 light); +vec3 scaleSoftClip(vec3 light); + +void default_lighting()  +{ +	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color; +	 +	color.rgb = atmosLighting(color.rgb); + +	color.rgb = scaleSoftClip(color.rgb); + +	gl_FragColor = color; +} + diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl index ebe21320b4..9f438f513f 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl @@ -7,8 +7,33 @@  #version 120 -uniform sampler2D diffuseMap; +  uniform samplerCube environmentMap; +uniform sampler2D tex0; +uniform sampler2D tex1; +uniform sampler2D tex2; +uniform sampler2D tex3; +uniform sampler2D tex4; +uniform sampler2D tex5; +uniform sampler2D tex6; + +varying float vary_texture_index; + +vec4 diffuseLookup(vec2 texcoord) +{ +	switch (int(vary_texture_index+0.25)) +	{ +		case 0: return texture2D(tex0, texcoord); +		case 1: return texture2D(tex1, texcoord); +		case 2: return texture2D(tex2, texcoord); +		case 3: return texture2D(tex3, texcoord); +		case 4: return texture2D(tex4, texcoord); +		case 5: return texture2D(tex5, texcoord); +		case 6: return texture2D(tex6, texcoord); +	} + +	return vec4(0,0,0,0); +}  vec3 scaleSoftClip(vec3 light);  vec3 atmosLighting(vec3 light); @@ -16,7 +41,7 @@ vec4 applyWaterFog(vec4 color);  void shiny_lighting()  { -	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy); +	vec4 color = diffuseLookup(gl_TexCoord[0].xy);  	color.rgb *= gl_Color.rgb;  	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	 diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightShinyNonIndexedF.glsl new file mode 100644 index 0000000000..212eacd6ea --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightShinyNonIndexedF.glsl @@ -0,0 +1,32 @@ +/**  + * @file lightShinyF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + + +uniform samplerCube environmentMap; +uniform sampler2D diffuseMap; + +vec3 scaleSoftClip(vec3 light); +vec3 atmosLighting(vec3 light); +vec4 applyWaterFog(vec4 color); + +void shiny_lighting() +{ +	vec4 color = texture2D(diffuseMap,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 index 7f48e2cf1d..5e11f6585c 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl @@ -8,15 +8,39 @@  #version 120 -uniform sampler2D diffuseMap;  uniform samplerCube environmentMap; +uniform sampler2D tex0; +uniform sampler2D tex1; +uniform sampler2D tex2; +uniform sampler2D tex3; +uniform sampler2D tex4; +uniform sampler2D tex5; +uniform sampler2D tex6; + +varying float vary_texture_index; + +vec4 diffuseLookup(vec2 texcoord) +{ +	switch (int(vary_texture_index+0.25)) +	{ +		case 0: return texture2D(tex0, texcoord); +		case 1: return texture2D(tex1, texcoord); +		case 2: return texture2D(tex2, texcoord); +		case 3: return texture2D(tex3, texcoord); +		case 4: return texture2D(tex4, texcoord); +		case 5: return texture2D(tex5, texcoord); +		case 6: return texture2D(tex6, texcoord); +	} + +	return vec4(0,0,0,0); +}  vec3 atmosLighting(vec3 light);  vec4 applyWaterFog(vec4 color);  void shiny_lighting_water()  { -	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy); +	vec4 color = diffuseLookup(gl_TexCoord[0].xy);  	color.rgb *= gl_Color.rgb;  	vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb;	 diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterNonIndexedF.glsl new file mode 100644 index 0000000000..cb8a24da60 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterNonIndexedF.glsl @@ -0,0 +1,29 @@ +/**  + * @file lightShinyWaterF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + + +uniform sampler2D diffuseMap; +uniform samplerCube environmentMap; + +vec3 atmosLighting(vec3 light); +vec4 applyWaterFog(vec4 color); + +void shiny_lighting_water() +{ +	vec4 color = texture2D(diffuseMap,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/lightWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl index 97eba92d7b..022544a917 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl @@ -7,14 +7,40 @@  #version 120 -uniform sampler2D diffuseMap; +uniform sampler2D tex0; +uniform sampler2D tex1; +uniform sampler2D tex2; +uniform sampler2D tex3; +uniform sampler2D tex4; +uniform sampler2D tex5; +uniform sampler2D tex6; +uniform sampler2D tex7; + +varying float vary_texture_index; + +vec4 diffuseLookup(vec2 texcoord) +{ +	switch (int(vary_texture_index+0.25)) +	{ +		case 0: return texture2D(tex0, texcoord); +		case 1: return texture2D(tex1, texcoord); +		case 2: return texture2D(tex2, texcoord); +		case 3: return texture2D(tex3, texcoord); +		case 4: return texture2D(tex4, texcoord); +		case 5: return texture2D(tex5, texcoord); +		case 6: return texture2D(tex6, texcoord); +		case 7: return texture2D(tex7, texcoord); +	} + +	return vec4(0,0,0,0); +}  vec3 atmosLighting(vec3 light);  vec4 applyWaterFog(vec4 color);  void default_lighting_water()  { -	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color; +	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;  	color.rgb = atmosLighting(color.rgb); diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightWaterNonIndexedF.glsl new file mode 100644 index 0000000000..dc16f2d5cd --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightWaterNonIndexedF.glsl @@ -0,0 +1,23 @@ +/**  + * @file lightWaterF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +uniform sampler2D diffuseMap; + +vec3 atmosLighting(vec3 light); +vec4 applyWaterFog(vec4 color); + +void default_lighting_water() +{ +	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color; + +	color.rgb = atmosLighting(color.rgb); + +	gl_FragColor = applyWaterFog(color); +} + diff --git a/indra/newview/app_settings/shaders/class2/objects/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class2/objects/fullbrightShinyV.glsl new file mode 100644 index 0000000000..e2145e1956 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/objects/fullbrightShinyV.glsl @@ -0,0 +1,35 @@ +/** + * @file fullbrightShinyV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +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; +	 +	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); + +	calcAtmospherics(pos.xyz); + +	gl_FrontColor = gl_Color; + +	gl_FogFragCoord = pos.z; +} diff --git a/indra/newview/app_settings/shaders/class2/objects/fullbrightV.glsl b/indra/newview/app_settings/shaders/class2/objects/fullbrightV.glsl new file mode 100644 index 0000000000..c4a3611a29 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/objects/fullbrightV.glsl @@ -0,0 +1,29 @@ +/** + * @file fullbrightV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +void calcAtmospherics(vec3 inPositionEye); + +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; +	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; +	 +	vec4 pos = (gl_ModelViewMatrix * vert); + +	calcAtmospherics(pos.xyz); + +	gl_FrontColor = gl_Color; + +	gl_FogFragCoord = pos.z; +} diff --git a/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl b/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl index 4cebb06df0..436c193c5d 100644 --- a/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl +++ b/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl @@ -11,14 +11,18 @@ vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);  void calcAtmospherics(vec3 inPositionEye); +varying float vary_texture_index; +  uniform vec4 origin;  void main()  {  	//transform vertex -	gl_Position = ftransform(); +	vec4 vert = vec4(gl_Vertex.xyz,1.0); +	vary_texture_index = gl_Vertex.w; +	gl_Position = gl_ModelViewProjectionMatrix*vert; -	vec4 pos = (gl_ModelViewMatrix * gl_Vertex); +	vec4 pos = (gl_ModelViewMatrix * vert);  	vec3 norm = normalize(gl_NormalMatrix * gl_Normal);  	vec3 ref = reflect(pos.xyz, -norm); diff --git a/indra/newview/app_settings/shaders/class2/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class2/objects/simpleV.glsl new file mode 100644 index 0000000000..50d2beee57 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/objects/simpleV.glsl @@ -0,0 +1,33 @@ +/**  + * @file simpleV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ +  +#version 120 + +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); +void calcAtmospherics(vec3 inPositionEye); + +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; +	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; +	 +	vec4 pos = (gl_ModelViewMatrix * vert); +	 +	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; +} diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 25e4bc847c..b8b12018d2 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -191,6 +191,14 @@ void LLDrawPool::renderPostDeferred(S32 pass)  //virtual  void LLDrawPool::endRenderPass( S32 pass )  { +	for (U32 i = 1; i < 8; i++) +	{ //dummy cleanup of any currently bound textures +		if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE) +		{ +			gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType()); +			gGL.getTexUnit(i)->disable(); +		} +	}  }  //virtual  @@ -430,14 +438,14 @@ void LLRenderPass::renderTexture(U32 type, U32 mask)  	pushBatches(type, mask, TRUE);  } -void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture) +void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)  {  	for (LLCullResult::drawinfo_list_t::iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)	  	{  		LLDrawInfo* pparams = *i;  		if (pparams)   		{ -			pushBatch(*pparams, mask, texture); +			pushBatch(*pparams, mask, texture, batch_textures);  		}  	}  } @@ -456,26 +464,42 @@ void LLRenderPass::applyModelMatrix(LLDrawInfo& params)  	}  } -void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) +void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)  {  	applyModelMatrix(params); +	bool tex_setup = false; +  	if (texture)  	{ -		if (params.mTexture.notNull()) +		if (batch_textures && params.mTextureList.size() > 1)  		{ -			params.mTexture->addTextureStats(params.mVSize); -			gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ; -			if (params.mTextureMatrix) +			for (U32 i = 0; i < params.mTextureList.size(); ++i)  			{ -				glMatrixMode(GL_TEXTURE); -				glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); -				gPipeline.mTextureMatrixOps++; +				if (params.mTextureList[i].notNull()) +				{ +					gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE); +				}  			}  		}  		else -		{ -			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +		{ //not batching textures or batch has only 1 texture -- might need a texture matrix +			if (params.mTexture.notNull()) +			{ +				params.mTexture->addTextureStats(params.mVSize); +				gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ; +				if (params.mTextureMatrix) +				{ +					tex_setup = true; +					glMatrixMode(GL_TEXTURE); +					glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); +					gPipeline.mTextureMatrixOps++; +				} +			} +			else +			{ +				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +			}  		}  	} @@ -490,7 +514,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)  		gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);  	} -	if (params.mTextureMatrix && texture && params.mTexture.notNull()) +	if (tex_setup)  	{  		glLoadIdentity();  		glMatrixMode(GL_MODELVIEW); diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index d3fd9ead0d..c7acbb42c6 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -146,8 +146,8 @@ public:  	void resetDrawOrders() { }  	static void applyModelMatrix(LLDrawInfo& params); -	virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE); -	virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture); +	virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE); +	virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);  	virtual void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);  	virtual void renderGroups(U32 type, U32 mask, BOOL texture = TRUE);  	virtual void renderTexture(U32 type, U32 mask); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 8b5a2ce781..71eee0188c 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -124,7 +124,7 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)  	if (pass == 0)  	{  		simple_shader = &gDeferredAlphaProgram; -		fullbright_shader = &gDeferredFullbrightProgram; +		fullbright_shader = &gObjectFullbrightProgram;  	}  	else  	{ @@ -228,13 +228,13 @@ void LLDrawPoolAlpha::render(S32 pass)  			if (!LLPipeline::sRenderDeferred)  			{  				simple_shader->bind(); -				pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask()); +				pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);  			}  			if (fullbright_shader)  			{  				fullbright_shader->bind();  			} -			pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask()); +			pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);  			LLGLSLShader::bindNoShader();  		}  		else @@ -273,7 +273,14 @@ void LLDrawPoolAlpha::render(S32 pass)  		}  	} -	renderAlpha(getVertexDataMask()); +	if (mVertexShaderLevel > 0) +	{ +		renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX); +	} +	else +	{ +		renderAlpha(getVertexDataMask()); +	}  	gGL.setColorMask(true, false); @@ -341,10 +348,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  	BOOL light_enabled = TRUE;  	S32 diffuse_channel = 0; -	BOOL use_shaders = (LLPipeline::sUnderWaterRender && gPipeline.canUseVertexShaders()) -		|| gPipeline.canUseWindLightShadersOnObjects(); -	 -	 +	BOOL use_shaders = gPipeline.canUseVertexShaders(); +		  	for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)  	{  		LLSpatialGroup* group = *i; @@ -368,92 +373,107 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  				LLRenderPass::applyModelMatrix(params); +				 +				if (params.mFullbright)  				{ -					if (params.mFullbright) -					{ -						// Turn off lighting if it hasn't already been so. -						if (light_enabled || !initialized_lighting) -						{ -							initialized_lighting = TRUE; -							if (use_shaders)  -							{ -								target_shader = fullbright_shader; -							} -							else -							{ -								gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); -							} -							light_enabled = FALSE; -						} -					} -					// Turn on lighting if it isn't already. -					else if (!light_enabled || !initialized_lighting) +					// Turn off lighting if it hasn't already been so. +					if (light_enabled || !initialized_lighting)  					{  						initialized_lighting = TRUE;  						if (use_shaders)   						{ -							target_shader = simple_shader; +							target_shader = fullbright_shader;  						}  						else  						{ -							gPipeline.enableLightsDynamic(); +							gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));  						} -						light_enabled = TRUE; +						light_enabled = FALSE;  					} - -					// If we need shaders, and we're not ALREADY using the proper shader, then bind it -					// (this way we won't rebind shaders unnecessarily). -					if(use_shaders && (current_shader != target_shader)) +				} +				// Turn on lighting if it isn't already. +				else if (!light_enabled || !initialized_lighting) +				{ +					initialized_lighting = TRUE; +					if (use_shaders)   					{ -						llassert(target_shader != NULL); -						if (deferred_render && current_shader != NULL) -						{ -							gPipeline.unbindDeferredShader(*current_shader); -							diffuse_channel = 0; -						} -						current_shader = target_shader; -						if (deferred_render) -						{ -							gPipeline.bindDeferredShader(*current_shader); -							diffuse_channel = current_shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); -						} -						else -						{ -							current_shader->bind(); -						} +						target_shader = simple_shader;  					} -					else if (!use_shaders && current_shader != NULL) +					else  					{ -						if (deferred_render) -						{ -							gPipeline.unbindDeferredShader(*current_shader); -							diffuse_channel = 0; -						} -						LLGLSLShader::bindNoShader(); -						current_shader = NULL; +						gPipeline.enableLightsDynamic();  					} +					light_enabled = TRUE; +				} -					if (params.mGroup) +				// If we need shaders, and we're not ALREADY using the proper shader, then bind it +				// (this way we won't rebind shaders unnecessarily). +				if(use_shaders && (current_shader != target_shader)) +				{ +					llassert(target_shader != NULL); +					if (deferred_render && current_shader != NULL) +					{ +						gPipeline.unbindDeferredShader(*current_shader); +						diffuse_channel = 0; +					} +					current_shader = target_shader; +					if (deferred_render) +					{ +						gPipeline.bindDeferredShader(*current_shader); +						diffuse_channel = current_shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); +					} +					else  					{ -						params.mGroup->rebuildMesh(); +						current_shader->bind();  					} +				} +				else if (!use_shaders && current_shader != NULL) +				{ +					if (deferred_render) +					{ +						gPipeline.unbindDeferredShader(*current_shader); +						diffuse_channel = 0; +					} +					LLGLSLShader::bindNoShader(); +					current_shader = NULL; +				} -					 -					if (params.mTexture.notNull()) +				if (params.mGroup) +				{ +					params.mGroup->rebuildMesh(); +				} + +				bool tex_setup = false; + +				if (use_shaders && params.mTextureList.size() > 1) +				{ +					for (U32 i = 0; i < params.mTextureList.size(); ++i)  					{ -						gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get()); -						if(params.mTexture.notNull()) +						if (params.mTextureList[i].notNull())  						{ -							params.mTexture->addTextureStats(params.mVSize); +							gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE);  						} +					} +				} +				else +				{ //not batching textures or batch has only 1 texture -- might need a texture matrix +					if (params.mTexture.notNull()) +					{ +						params.mTexture->addTextureStats(params.mVSize); +						gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;  						if (params.mTextureMatrix)  						{ +							tex_setup = true;  							gGL.getTexUnit(0)->activate();  							glMatrixMode(GL_TEXTURE);  							glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);  							gPipeline.mTextureMatrixOps++;  						}  					} +					else +					{ +						gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +					}  				}  				params.mVertexBuffer->setBuffer(mask); @@ -480,7 +500,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  					gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);  				} -				if (params.mTextureMatrix && params.mTexture.notNull()) +				if (tex_setup)  				{  					gGL.getTexUnit(0)->activate();  					glLoadIdentity(); @@ -494,9 +514,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  	{  		gPipeline.unbindDeferredShader(*current_shader);  		LLVertexBuffer::unbind();	 -		LLGLState::checkStates(); -		LLGLState::checkTextureChannels(); -		LLGLState::checkClientArrays();  	}  	if (!light_enabled) diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 645c7ebcae..7c017f5694 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -613,11 +613,11 @@ void LLDrawPoolAvatar::beginRigid()  	{  		if (LLPipeline::sUnderWaterRender)  		{ -			sVertexProgram = &gObjectSimpleWaterProgram; +			sVertexProgram = &gObjectSimpleNonIndexedWaterProgram;  		}  		else  		{ -			sVertexProgram = &gObjectSimpleProgram; +			sVertexProgram = &gObjectSimpleNonIndexedProgram;  		}  		if (sVertexProgram != NULL) @@ -669,7 +669,7 @@ void LLDrawPoolAvatar::endDeferredImpostor()  void LLDrawPoolAvatar::beginDeferredRigid()  { -	sVertexProgram = &gDeferredDiffuseProgram; +	sVertexProgram = &gDeferredNonIndexedDiffuseProgram;  	sVertexProgram->bind();  } @@ -700,11 +700,11 @@ void LLDrawPoolAvatar::beginSkinned()  	{  		if (LLPipeline::sUnderWaterRender)  		{ -			sVertexProgram = &gObjectSimpleWaterProgram; +			sVertexProgram = &gObjectSimpleNonIndexedWaterProgram;  		}  		else  		{ -			sVertexProgram = &gObjectSimpleProgram; +			sVertexProgram = &gObjectSimpleNonIndexedProgram;  		}  	} @@ -789,11 +789,11 @@ void LLDrawPoolAvatar::beginRiggedSimple()  	{  		if (LLPipeline::sUnderWaterRender)  		{ -			sVertexProgram = &gObjectSimpleWaterProgram; +			sVertexProgram = &gObjectSimpleNonIndexedWaterProgram;  		}  		else  		{ -			sVertexProgram = &gObjectSimpleProgram; +			sVertexProgram = &gObjectSimpleNonIndexedProgram;  		}  	} @@ -864,11 +864,11 @@ void LLDrawPoolAvatar::beginRiggedFullbright()  	{  		if (LLPipeline::sUnderWaterRender)  		{ -			sVertexProgram = &gObjectFullbrightWaterProgram; +			sVertexProgram = &gObjectFullbrightNonIndexedWaterProgram;  		}  		else  		{ -			sVertexProgram = &gObjectFullbrightProgram; +			sVertexProgram = &gObjectFullbrightNonIndexedProgram;  		}  	} @@ -908,11 +908,11 @@ void LLDrawPoolAvatar::beginRiggedShinySimple()  	{  		if (LLPipeline::sUnderWaterRender)  		{ -			sVertexProgram = &gObjectShinyWaterProgram; +			sVertexProgram = &gObjectShinyNonIndexedWaterProgram;  		}  		else  		{ -			sVertexProgram = &gObjectShinyProgram; +			sVertexProgram = &gObjectShinyNonIndexedProgram;  		}  	} @@ -953,11 +953,11 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()  	{  		if (LLPipeline::sUnderWaterRender)  		{ -			sVertexProgram = &gObjectFullbrightShinyWaterProgram; +			sVertexProgram = &gObjectFullbrightShinyNonIndexedWaterProgram;  		}  		else  		{ -			sVertexProgram = &gObjectFullbrightShinyProgram; +			sVertexProgram = &gObjectFullbrightShinyNonIndexedProgram;  		}  	} diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 5f89d11391..4ac4b89ab4 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -309,6 +309,9 @@ void LLDrawPoolBump::endRenderPass(S32 pass)  			llassert(0);  			break;  	} + +	//to cleanup texture channels +	LLRenderPass::endRenderPass(pass);  }  //static @@ -347,6 +350,11 @@ void LLDrawPoolBump::beginShiny(bool invisible)  	}  	bindCubeMap(shader, mVertexShaderLevel, diffuse_channel, cube_channel, invisible); + +	if (mVertexShaderLevel > 1) +	{ //indexed texture rendering, channel 0 is always diffuse +		diffuse_channel = 0; +	}  }  //static @@ -414,16 +422,16 @@ void LLDrawPoolBump::renderShiny(bool invisible)  		LLGLEnable blend_enable(GL_BLEND);  		if (!invisible && mVertexShaderLevel > 1)  		{ -			LLRenderPass::renderTexture(LLRenderPass::PASS_SHINY, sVertexMask); +			LLRenderPass::pushBatches(LLRenderPass::PASS_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);  		}  		else if (!invisible)  		{  			renderGroups(LLRenderPass::PASS_SHINY, sVertexMask);  		} -		else // invisible -		{ -			renderGroups(LLRenderPass::PASS_INVISI_SHINY, sVertexMask); -		} +		//else // invisible (deprecated) +		//{ +			//renderGroups(LLRenderPass::PASS_INVISI_SHINY, sVertexMask); +		//}  	}  } @@ -536,7 +544,15 @@ void LLDrawPoolBump::renderFullbrightShiny()  	if( gSky.mVOSkyp->getCubeMap() )  	{  		LLGLEnable blend_enable(GL_BLEND); -		LLRenderPass::renderTexture(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask); + +		if (mVertexShaderLevel > 1) +		{ +			LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +		} +		else +		{ +			LLRenderPass::renderTexture(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask); +		}  	}  } @@ -836,6 +852,9 @@ void LLDrawPoolBump::endPostDeferredPass(S32 pass)  		endBump(LLRenderPass::PASS_POST_BUMP);  		break;  	} + +	//to disable texture channels +	LLRenderPass::endRenderPass(pass);  }  void LLDrawPoolBump::renderPostDeferred(S32 pass) @@ -1292,43 +1311,60 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)  	}  } -void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) +void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)  {  	applyModelMatrix(params); -	if (params.mTextureMatrix) +	bool tex_setup = false; + +	if (batch_textures && params.mTextureList.size() > 1)  	{ -		if (mShiny) +		for (U32 i = 0; i < params.mTextureList.size(); ++i)  		{ -			gGL.getTexUnit(0)->activate(); -			glMatrixMode(GL_TEXTURE); +			if (params.mTextureList[i].notNull()) +			{ +				gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE); +			}  		} -		else +	} +	else +	{ //not batching textures or batch has only 1 texture -- might need a texture matrix +		if (params.mTextureMatrix)  		{ -			gGL.getTexUnit(1)->activate(); -			glMatrixMode(GL_TEXTURE); +			if (mShiny) +			{ +				gGL.getTexUnit(0)->activate(); +				glMatrixMode(GL_TEXTURE); +			} +			else +			{ +				gGL.getTexUnit(1)->activate(); +				glMatrixMode(GL_TEXTURE); +				glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); +				gPipeline.mTextureMatrixOps++; +				gGL.getTexUnit(0)->activate(); +			} +  			glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);  			gPipeline.mTextureMatrixOps++; -			gGL.getTexUnit(0)->activate(); -		} -		glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); -		gPipeline.mTextureMatrixOps++; -	} - -	if (mShiny && mVertexShaderLevel > 1 && texture) -	{ -		if (params.mTexture.notNull()) -		{ -			gGL.getTexUnit(diffuse_channel)->bind(params.mTexture) ; -			params.mTexture->addTextureStats(params.mVSize);		 +			tex_setup = true;  		} -		else + +		if (mShiny && mVertexShaderLevel > 1 && texture)  		{ -			gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); +			if (params.mTexture.notNull()) +			{ +				gGL.getTexUnit(diffuse_channel)->bind(params.mTexture) ; +				params.mTexture->addTextureStats(params.mVSize);		 +			} +			else +			{ +				gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); +			}  		}  	} -	 +  	if (params.mGroup)  	{  		params.mGroup->rebuildMesh(); @@ -1336,7 +1372,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)  	params.mVertexBuffer->setBuffer(mask);  	params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);  	gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); -	if (params.mTextureMatrix) +	if (tex_setup)  	{  		if (mShiny)  		{ diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index f4702bf61d..476b1d41b7 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -55,7 +55,7 @@ public:  	virtual void endRenderPass( S32 pass );  	virtual S32	 getNumPasses();  	/*virtual*/ void prerender(); -	/*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture); +	/*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);  	void renderBump(U32 type, U32 mask);  	void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture); diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 2e83167851..9b73b2f9b6 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -44,6 +44,43 @@ static LLGLSLShader* fullbright_shader = NULL;  static LLFastTimer::DeclareTimer FTM_RENDER_SIMPLE_DEFERRED("Deferred Simple");  static LLFastTimer::DeclareTimer FTM_RENDER_GRASS_DEFERRED("Deferred Grass"); +void LLDrawPoolGlow::beginPostDeferredPass(S32 pass) +{ +	gDeferredFullbrightProgram.bind(); +} + +void LLDrawPoolGlow::renderPostDeferred(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_GLOW); +	LLGLEnable blend(GL_BLEND); +	LLGLDisable test(GL_ALPHA_TEST); +	gGL.flush(); +	/// Get rid of z-fighting with non-glow pass. +	LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); +	glPolygonOffset(-1.0f, -1.0f); +	gGL.setSceneBlendType(LLRender::BT_ADD); +	 +	LLGLDepthTest depth(GL_TRUE, GL_FALSE); +	gGL.setColorMask(false, true); +	pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +	 +	gGL.setColorMask(true, false); +	gGL.setSceneBlendType(LLRender::BT_ALPHA);	 +} + +void LLDrawPoolGlow::endPostDeferredPass(S32 pass) +{ +	gDeferredFullbrightProgram.unbind(); +	for (U32 i = 0; i < 8; i++) +	{ +		if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE) +		{ +			gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType()); +			gGL.getTexUnit(i)->disable(); +		} +	} +} +  void LLDrawPoolGlow::render(S32 pass)  {  	LLFastTimer t(FTM_RENDER_GLOW); @@ -68,7 +105,15 @@ void LLDrawPoolGlow::render(S32 pass)  	LLGLDepthTest depth(GL_TRUE, GL_FALSE);  	gGL.setColorMask(false, true); -	renderTexture(LLRenderPass::PASS_GLOW, getVertexDataMask()); + +	if (shader_level > 1) +	{ +		pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +	} +	else +	{ +		renderTexture(LLRenderPass::PASS_GLOW, getVertexDataMask()); +	}  	gGL.setColorMask(true, false);  	gGL.setSceneBlendType(LLRender::BT_ALPHA); @@ -79,10 +124,10 @@ void LLDrawPoolGlow::render(S32 pass)  	}  } -void LLDrawPoolGlow::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) +void LLDrawPoolGlow::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)  {  	glColor4ubv(params.mGlowColor.mV); -	LLRenderPass::pushBatch(params, mask, texture); +	LLRenderPass::pushBatch(params, mask, texture, batch_textures);  } @@ -128,8 +173,8 @@ void LLDrawPoolSimple::endRenderPass(S32 pass)  	LLFastTimer t(FTM_RENDER_SIMPLE);  	LLRenderPass::endRenderPass(pass); -	if (mVertexShaderLevel > 0){ - +	if (mVertexShaderLevel > 0) +	{  		simple_shader->unbind();  	}  } @@ -142,13 +187,24 @@ void LLDrawPoolSimple::render(S32 pass)  	{ //render simple  		LLFastTimer t(FTM_RENDER_SIMPLE);  		gPipeline.enableLightsDynamic(); -		renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask()); -		if (LLPipeline::sRenderDeferred) -		{ //if deferred rendering is enabled, bump faces aren't registered as simple -			//render bump faces here as simple so bump faces will appear under water -			renderTexture(LLRenderPass::PASS_BUMP, getVertexDataMask()); +		if (mVertexShaderLevel > 0) +		{ +			U32 mask = getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX; + +			pushBatches(LLRenderPass::PASS_SIMPLE, mask, TRUE, TRUE); + +			if (LLPipeline::sRenderDeferred) +			{ //if deferred rendering is enabled, bump faces aren't registered as simple +				//render bump faces here as simple so bump faces will appear under water +				pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE); +			} +		} +		else +		{ +			renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask());  		} +		  	}  } @@ -168,6 +224,15 @@ void LLDrawPoolSimple::endDeferredPass(S32 pass)  	LLRenderPass::endRenderPass(pass);  	gDeferredDiffuseProgram.unbind(); + +	for (U32 i = 0; i < 8; i++) +	{ +		if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE) +		{ +			gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType()); +			gGL.getTexUnit(i)->disable(); +		} +	}  }  void LLDrawPoolSimple::renderDeferred(S32 pass) @@ -177,7 +242,7 @@ void LLDrawPoolSimple::renderDeferred(S32 pass)  	{ //render simple  		LLFastTimer t(FTM_RENDER_SIMPLE_DEFERRED); -		renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask()); +		pushBatches(LLRenderPass::PASS_SIMPLE, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);  	}  } @@ -200,11 +265,11 @@ void LLDrawPoolGrass::beginRenderPass(S32 pass)  	if (LLPipeline::sUnderWaterRender)  	{ -		simple_shader = &gObjectSimpleWaterProgram; +		simple_shader = &gObjectSimpleNonIndexedWaterProgram;  	}  	else  	{ -		simple_shader = &gObjectSimpleProgram; +		simple_shader = &gObjectSimpleNonIndexedProgram;  	}  	if (mVertexShaderLevel > 0) @@ -285,6 +350,33 @@ void LLDrawPoolFullbright::prerender()  	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);  } +void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass) +{ +	gDeferredFullbrightProgram.bind(); +} + +void LLDrawPoolFullbright::renderPostDeferred(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_FULLBRIGHT); +	 +	gGL.setSceneBlendType(LLRender::BT_ALPHA); +	U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; +	pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE); +} + +void LLDrawPoolFullbright::endPostDeferredPass(S32 pass) +{ +	gDeferredFullbrightProgram.unbind(); +	for (U32 i = 0; i < 8; i++) +	{ +		if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE) +		{ +			gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType()); +			gGL.getTexUnit(i)->disable(); +		} +	} +} +  void LLDrawPoolFullbright::beginRenderPass(S32 pass)  {  	LLFastTimer t(FTM_RENDER_FULLBRIGHT); @@ -313,25 +405,21 @@ void LLDrawPoolFullbright::endRenderPass(S32 pass)  void LLDrawPoolFullbright::render(S32 pass)  { //render fullbright  	LLFastTimer t(FTM_RENDER_FULLBRIGHT); +	gGL.setSceneBlendType(LLRender::BT_ALPHA); +  	if (mVertexShaderLevel > 0)  	{  		fullbright_shader->bind();  		fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f); +		U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; +		pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE);  	}  	else  	{  		gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); +		U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR; +		renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask);  	} -	 -	//gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.25f); -	 -	//LLGLEnable test(GL_ALPHA_TEST); -	//LLGLEnable blend(GL_BLEND); -	gGL.setSceneBlendType(LLRender::BT_ALPHA); -	U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR; -	renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask); - -	//gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);  }  S32 LLDrawPoolFullbright::getNumPasses() diff --git a/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h index 5f3bbebbda..3811b3d398 100644 --- a/indra/newview/lldrawpoolsimple.h +++ b/indra/newview/lldrawpoolsimple.h @@ -98,9 +98,9 @@ public:  	LLDrawPoolFullbright();  	/*virtual*/ S32 getNumPostDeferredPasses() { return 1; } -	/*virtual*/ void beginPostDeferredPass(S32 pass) { beginRenderPass(pass); } -	/*virtual*/ void endPostDeferredPass(S32 pass) { endRenderPass(pass); } -	/*virtual*/ void renderPostDeferred(S32 pass) { render(pass); } +	/*virtual*/ void beginPostDeferredPass(S32 pass); +	/*virtual*/ void endPostDeferredPass(S32 pass); +	/*virtual*/ void renderPostDeferred(S32 pass);  	/*virtual*/ void beginRenderPass(S32 pass);  	/*virtual*/ void endRenderPass(S32 pass); @@ -126,12 +126,12 @@ public:  	virtual void prerender() { }  	/*virtual*/ S32 getNumPostDeferredPasses() { return 1; } -	/*virtual*/ void beginPostDeferredPass(S32 pass) { beginRenderPass(pass); } -	/*virtual*/ void endPostDeferredPass(S32 pass) { endRenderPass(pass); } -	/*virtual*/ void renderPostDeferred(S32 pass) { render(pass); } +	/*virtual*/ void beginPostDeferredPass(S32 pass);  +	/*virtual*/ void endPostDeferredPass(S32 pass); +	/*virtual*/ void renderPostDeferred(S32 pass);  	void render(S32 pass = 0); -	void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture = TRUE); +	void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);  }; diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 195ee60a2e..81c796b146 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -66,11 +66,11 @@ void LLDrawPoolTree::beginRenderPass(S32 pass)  	if (LLPipeline::sUnderWaterRender)  	{ -		shader = &gObjectSimpleWaterProgram; +		shader = &gObjectSimpleNonIndexedWaterProgram;  	}  	else  	{ -		shader = &gObjectSimpleProgram; +		shader = &gObjectSimpleNonIndexedProgram;  	}  	if (gPipeline.canUseWindLightShadersOnObjects()) diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 9f9e50ad0a..e30522d380 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -165,6 +165,7 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)  	mIndexInTex = 0;  	mTexture		= NULL;  	mTEOffset		= -1; +	mTextureIndex = 255;  	setDrawable(drawablep);  	mVObjp = objp; @@ -386,6 +387,26 @@ void LLFace::setGeomIndex(U16 idx)  	}  } +void LLFace::setTextureIndex(U8 index) +{ +	if (index != mTextureIndex) +	{ +		mTextureIndex = index; + +		if (mTextureIndex != 255) +		{ +			mDrawablep->setState(LLDrawable::REBUILD_POSITION); +		} +		else +		{ +			if (mDrawInfo && !mDrawInfo->mTextureList.empty()) +			{ +				llerrs << "Face with no texture index references indexed texture draw info." << llendl; +			} +		} +	} +} +  void LLFace::setIndicesIndex(S32 idx)   {   	if (mIndicesIndex != idx) @@ -1573,6 +1594,20 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			mat_vert.affineTransform(*src++, *dst++);  		}  		while(dst < end); + +		F32 index = (F32) (mTextureIndex < 255 ? mTextureIndex : 0); +		F32 *index_dst = (F32*) vertices; +		F32 *index_end = (F32*) end; + +		index_dst += 3; +		index_end += 3; +		do +		{ +			*index_dst = index; +			index_dst += 4; +		} +		while (index_dst < index_end); +		  	}  	if (rebuild_normal) diff --git a/indra/newview/llface.h b/indra/newview/llface.h index b2170c4cf3..b5eaeecd60 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -94,6 +94,8 @@ public:  	U16				getGeomCount()		const	{ return mGeomCount; }		// vertex count for this face  	U16				getGeomIndex()		const	{ return mGeomIndex; }		// index into draw pool  	U16				getGeomStart()		const	{ return mGeomIndex; }		// index into draw pool +	void			setTextureIndex(U8 index); +	U8				getTextureIndex() const		{ return mTextureIndex; }  	void			setTexture(LLViewerTexture* tex) ;  	void            switchTexture(LLViewerTexture* new_texture);  	void            dirtyTexture(); @@ -262,6 +264,7 @@ private:  	U16			mGeomCount;			// vertex count for this face  	U16			mGeomIndex;			// index into draw pool +	U8			mTextureIndex;		// index of texture channel to use for pseudo-atlasing  	U32			mIndicesCount;  	U32			mIndicesIndex;		// index into draw pool for indices (yeah, I know!)  	S32         mIndexInTex ; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 8143d6a41f..7f91f9a952 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3439,6 +3439,8 @@ void renderTextureAnim(LLDrawInfo* params)  void renderBatchSize(LLDrawInfo* params)  { +	LLGLEnable offset(GL_POLYGON_OFFSET_FILL); +	glPolygonOffset(-1.f, 1.f);  	glColor3ubv((GLubyte*) &(params->mDebugColor));  	pushVerts(params, LLVertexBuffer::MAP_VERTEX);  } @@ -3876,6 +3878,28 @@ public:  				renderAgentTarget(avatar);  			} +			if (gDebugGL) +			{ +				for (U32 i = 0; i < drawable->getNumFaces(); ++i) +				{ +					LLFace* facep = drawable->getFace(i); +					U8 index = facep->getTextureIndex(); +					if (facep->mDrawInfo) +					{ +						if (index < 255) +						{ +							if (facep->mDrawInfo->mTextureList.size() <= index) +							{ +								llerrs << "Face texture index out of bounds." << llendl; +							} +							else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture()) +							{ +								llerrs << "Face texture index incorrect." << llendl; +							} +						} +					} +				} +			}  		}  		for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 0d9cad914a..ae5d4fa463 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -91,6 +91,8 @@ public:  	LLPointer<LLVertexBuffer> mVertexBuffer;  	LLPointer<LLViewerTexture>     mTexture; +	std::vector<LLPointer<LLViewerTexture> > mTextureList; +  	LLColor4U mGlowColor;  	S32 mDebugColor;  	const LLMatrix4* mTextureMatrix; @@ -684,7 +686,7 @@ class LLVolumeGeometryManager: public LLGeometryManager  	virtual void rebuildGeom(LLSpatialGroup* group);  	virtual void rebuildMesh(LLSpatialGroup* group);  	virtual void getGeometry(LLSpatialGroup* group); -	void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE); +	void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE);  	void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);  }; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index b818da205e..e60b3f4543 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -66,12 +66,20 @@ LLGLSLShader		gObjectSimpleProgram;  LLGLSLShader		gObjectSimpleWaterProgram;  LLGLSLShader		gObjectFullbrightProgram;  LLGLSLShader		gObjectFullbrightWaterProgram; -  LLGLSLShader		gObjectFullbrightShinyProgram;  LLGLSLShader		gObjectFullbrightShinyWaterProgram;  LLGLSLShader		gObjectShinyProgram;  LLGLSLShader		gObjectShinyWaterProgram; +LLGLSLShader		gObjectSimpleNonIndexedProgram; +LLGLSLShader		gObjectSimpleNonIndexedWaterProgram; +LLGLSLShader		gObjectFullbrightNonIndexedProgram; +LLGLSLShader		gObjectFullbrightNonIndexedWaterProgram; +LLGLSLShader		gObjectFullbrightShinyNonIndexedProgram; +LLGLSLShader		gObjectFullbrightShinyNonIndexedWaterProgram; +LLGLSLShader		gObjectShinyNonIndexedProgram; +LLGLSLShader		gObjectShinyNonIndexedWaterProgram; +  //object hardware skinning shaders  LLGLSLShader		gSkinnedObjectSimpleProgram;  LLGLSLShader		gSkinnedObjectFullbrightProgram; @@ -113,6 +121,7 @@ LLGLSLShader			gDeferredImpostorProgram;  LLGLSLShader			gDeferredEdgeProgram;  LLGLSLShader			gDeferredWaterProgram;  LLGLSLShader			gDeferredDiffuseProgram; +LLGLSLShader			gDeferredNonIndexedDiffuseProgram;  LLGLSLShader			gDeferredSkinnedDiffuseProgram;  LLGLSLShader			gDeferredSkinnedBumpProgram;  LLGLSLShader			gDeferredSkinnedAlphaProgram; @@ -132,6 +141,7 @@ LLGLSLShader			gDeferredShadowProgram;  LLGLSLShader			gDeferredAvatarShadowProgram;  LLGLSLShader			gDeferredAttachmentShadowProgram;  LLGLSLShader			gDeferredAlphaProgram; +LLGLSLShader			gDeferredAvatarEyesProgram;  LLGLSLShader			gDeferredFullbrightProgram;  LLGLSLShader			gDeferredGIProgram;  LLGLSLShader			gDeferredGIFinalProgram; @@ -162,6 +172,10 @@ LLViewerShaderMgr::LLViewerShaderMgr() :  	mShaderList.push_back(&gObjectFullbrightProgram);  	mShaderList.push_back(&gObjectFullbrightShinyProgram);  	mShaderList.push_back(&gObjectFullbrightShinyWaterProgram); +	mShaderList.push_back(&gObjectSimpleNonIndexedProgram); +	mShaderList.push_back(&gObjectFullbrightNonIndexedProgram); +	mShaderList.push_back(&gObjectFullbrightShinyNonIndexedProgram); +	mShaderList.push_back(&gObjectFullbrightShinyNonIndexedWaterProgram);  	mShaderList.push_back(&gSkinnedObjectSimpleProgram);  	mShaderList.push_back(&gSkinnedObjectFullbrightProgram);  	mShaderList.push_back(&gSkinnedObjectFullbrightShinyProgram); @@ -185,6 +199,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() :  	mShaderList.push_back(&gDeferredAlphaProgram);  	mShaderList.push_back(&gDeferredSkinnedAlphaProgram);  	mShaderList.push_back(&gDeferredFullbrightProgram); +	mShaderList.push_back(&gDeferredAvatarEyesProgram);  	mShaderList.push_back(&gDeferredPostGIProgram);  	mShaderList.push_back(&gDeferredEdgeProgram);  	mShaderList.push_back(&gDeferredPostProgram); @@ -354,6 +369,7 @@ void LLViewerShaderMgr::setShaders()  	//setup preprocessor definitions  	LLShaderMgr::instance()->mDefinitions["samples"] = llformat("%d", gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples"))); +	LLShaderMgr::instance()->mDefinitions["NUM_TEX_UNITS"] = llformat("%d", gGLManager.mNumTextureImageUnits);  	reentrance = true; @@ -585,6 +601,16 @@ void LLViewerShaderMgr::unloadShaders()  	gObjectFullbrightShinyWaterProgram.unload();  	gObjectShinyWaterProgram.unload(); +	gObjectSimpleNonIndexedProgram.unload(); +	gObjectSimpleNonIndexedWaterProgram.unload(); +	gObjectFullbrightNonIndexedProgram.unload(); +	gObjectFullbrightNonIndexedWaterProgram.unload(); + +	gObjectShinyNonIndexedProgram.unload(); +	gObjectFullbrightShinyNonIndexedProgram.unload(); +	gObjectFullbrightShinyNonIndexedWaterProgram.unload(); +	gObjectShinyNonIndexedWaterProgram.unload(); +  	gSkinnedObjectSimpleProgram.unload();  	gSkinnedObjectFullbrightProgram.unload();  	gSkinnedObjectFullbrightShinyProgram.unload(); @@ -615,6 +641,7 @@ void LLViewerShaderMgr::unloadShaders()  	gPostNightVisionProgram.unload();  	gDeferredDiffuseProgram.unload(); +	gDeferredNonIndexedDiffuseProgram.unload();  	gDeferredSkinnedDiffuseProgram.unload();  	gDeferredSkinnedBumpProgram.unload();  	gDeferredSkinnedAlphaProgram.unload(); @@ -706,6 +733,14 @@ BOOL LLViewerShaderMgr::loadBasicShaders()  	shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) );  	shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) );  	shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); +	shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl",					mVertexShaderLevel[SHADER_LIGHTING] ) ); +	shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) ); +	shaders.push_back( make_pair( "lighting/lightWaterNonIndexedF.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) ); +	shaders.push_back( make_pair( "lighting/lightFullbrightWaterNonIndexedF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) ); +	shaders.push_back( make_pair( "lighting/lightShinyNonIndexedF.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) ); +	shaders.push_back( make_pair( "lighting/lightFullbrightShinyNonIndexedF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) ); +	shaders.push_back( make_pair( "lighting/lightShinyWaterNonIndexedF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) ); +	shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );  	for (U32 i = 0; i < shaders.size(); i++)  	{ @@ -941,12 +976,53 @@ BOOL LLViewerShaderMgr::loadShadersEffects()  } +void setup_indexed_texture(LLGLSLShader& shader) +{ +	shader.bind(); +	shader.uniform1i("tex0", 0); +	shader.uniform1i("tex1", 1); +	shader.uniform1i("tex2", 2); +	shader.uniform1i("tex3", 3); +	shader.uniform1i("tex4", 4); +	shader.uniform1i("tex5", 5); +	shader.uniform1i("tex6", 6); +	shader.uniform1i("tex7", 7); + +	S32 cur_tex = 8; //adjust any texture channels that might have been overwritten +	for (U32 i = 0; i < shader.mTexture.size(); i++) +	{ +		if (shader.mTexture[i] > -1 && shader.mTexture[i] < 7) +		{ +			shader.uniform1i(i, cur_tex); +			shader.mTexture[i] = cur_tex++; +		} +	} +	shader.unbind(); +} + +void setup_indexed_texture_with_cubemap(LLGLSLShader& shader) +{ +	shader.bind(); +	shader.uniform1i("tex0", 0); +	shader.uniform1i("tex1", 1); +	shader.uniform1i("tex2", 2); +	shader.uniform1i("tex3", 3); +	shader.uniform1i("tex4", 4); +	shader.uniform1i("tex5", 5); +	shader.uniform1i("tex6", 6); +	shader.uniform1i("environmentMap", 7); +	shader.mTexture[LLViewerShaderMgr::ENVIRONMENT_MAP] = 7; +	shader.mTexture[LLViewerShaderMgr::DIFFUSE_MAP] = 0; +	shader.unbind(); +} +  BOOL LLViewerShaderMgr::loadShadersDeferred()  {  	if (mVertexShaderLevel[SHADER_DEFERRED] == 0)  	{  		gDeferredTreeProgram.unload();  		gDeferredDiffuseProgram.unload(); +		gDeferredNonIndexedDiffuseProgram.unload();  		gDeferredSkinnedDiffuseProgram.unload();  		gDeferredSkinnedBumpProgram.unload();  		gDeferredSkinnedAlphaProgram.unload(); @@ -967,6 +1043,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAvatarAlphaProgram.unload();  		gDeferredAlphaProgram.unload();  		gDeferredFullbrightProgram.unload(); +		gDeferredAvatarEyesProgram.unload();  		gDeferredPostGIProgram.unload();		  		gDeferredEdgeProgram.unload();		  		gDeferredPostProgram.unload();		 @@ -992,13 +1069,29 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		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/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredDiffuseProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredDiffuseProgram.createShader(NULL, NULL); + +		if (success) +		{ //force tex0-7 to appropriate texture channels +			setup_indexed_texture(gDeferredDiffuseProgram); +		}  	}  	if (success)  	{ +		gDeferredNonIndexedDiffuseProgram.mName = "Non Indexed Deferred Diffuse Shader"; +		gDeferredNonIndexedDiffuseProgram.mShaderFiles.clear(); +		gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredNonIndexedDiffuseProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		success = gDeferredNonIndexedDiffuseProgram.createShader(NULL, NULL); +	} +		 + +	if (success) +	{  		gDeferredSkinnedDiffuseProgram.mName = "Deferred Skinned Diffuse Shader";  		gDeferredSkinnedDiffuseProgram.mFeatures.hasObjectSkinning = true;  		gDeferredSkinnedDiffuseProgram.mShaderFiles.clear(); @@ -1217,6 +1310,24 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredAlphaProgram.createShader(NULL, NULL); +		if (success) +		{ +			setup_indexed_texture(gDeferredAlphaProgram); +		} +	} + +	if (success) +	{ +		gDeferredAvatarEyesProgram.mName = "Deferred Avatar Eyes Shader"; +		gDeferredAvatarEyesProgram.mFeatures.calculatesAtmospherics = true; +		gDeferredAvatarEyesProgram.mFeatures.hasGamma = true; +		gDeferredAvatarEyesProgram.mFeatures.hasTransport = true; +		gDeferredAvatarEyesProgram.mFeatures.isFullbright = true; +		gDeferredAvatarEyesProgram.mShaderFiles.clear(); +		gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredAvatarEyesProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		success = gDeferredAvatarEyesProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1231,6 +1342,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredFullbrightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredFullbrightProgram.createShader(NULL, NULL); + +		if (success) +		{ +			setup_indexed_texture(gDeferredFullbrightProgram); +		}  	}  	if (success) @@ -1490,6 +1606,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  BOOL LLViewerShaderMgr::loadShadersObject()  {  	BOOL success = TRUE; +	bool batch_textures = mVertexShaderLevel[SHADER_OBJECT] > 1;  	if (mVertexShaderLevel[SHADER_OBJECT] == 0)  	{ @@ -1501,6 +1618,14 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleWaterProgram.unload();  		gObjectFullbrightProgram.unload();  		gObjectFullbrightWaterProgram.unload(); +		gObjectShinyNonIndexedProgram.unload(); +		gObjectFullbrightShinyNonIndexedProgram.unload(); +		gObjectFullbrightShinyNonIndexedWaterProgram.unload(); +		gObjectShinyNonIndexedWaterProgram.unload(); +		gObjectSimpleNonIndexedProgram.unload(); +		gObjectSimpleNonIndexedWaterProgram.unload(); +		gObjectFullbrightNonIndexedProgram.unload(); +		gObjectFullbrightNonIndexedWaterProgram.unload();  		gSkinnedObjectSimpleProgram.unload();  		gSkinnedObjectFullbrightProgram.unload();  		gSkinnedObjectFullbrightShinyProgram.unload(); @@ -1515,6 +1640,137 @@ BOOL LLViewerShaderMgr::loadShadersObject()  	if (success)  	{ +		gObjectSimpleNonIndexedProgram.mName = "Non indexed Shader"; +		gObjectSimpleNonIndexedProgram.mFeatures.calculatesLighting = true; +		gObjectSimpleNonIndexedProgram.mFeatures.calculatesAtmospherics = true; +		gObjectSimpleNonIndexedProgram.mFeatures.hasGamma = true; +		gObjectSimpleNonIndexedProgram.mFeatures.hasAtmospherics = true; +		gObjectSimpleNonIndexedProgram.mFeatures.hasLighting = true; +		gObjectSimpleNonIndexedProgram.mFeatures.disableTextureIndex = true; +		gObjectSimpleNonIndexedProgram.mShaderFiles.clear(); +		gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); +		gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gObjectSimpleNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		success = gObjectSimpleNonIndexedProgram.createShader(NULL, NULL); +	} +	 +	if (success) +	{ +		gObjectSimpleNonIndexedWaterProgram.mName = "Non indexed Water Shader"; +		gObjectSimpleNonIndexedWaterProgram.mFeatures.calculatesLighting = true; +		gObjectSimpleNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; +		gObjectSimpleNonIndexedWaterProgram.mFeatures.hasWaterFog = true; +		gObjectSimpleNonIndexedWaterProgram.mFeatures.hasAtmospherics = true; +		gObjectSimpleNonIndexedWaterProgram.mFeatures.hasLighting = true; +		gObjectSimpleNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; +		gObjectSimpleNonIndexedWaterProgram.mShaderFiles.clear(); +		gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); +		gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gObjectSimpleNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectSimpleNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; +		success = gObjectSimpleNonIndexedWaterProgram.createShader(NULL, NULL); +	} + +	if (success) +	{ +		gObjectFullbrightNonIndexedProgram.mName = "Non Indexed Fullbright Shader"; +		gObjectFullbrightNonIndexedProgram.mFeatures.calculatesAtmospherics = true; +		gObjectFullbrightNonIndexedProgram.mFeatures.hasGamma = true; +		gObjectFullbrightNonIndexedProgram.mFeatures.hasTransport = true; +		gObjectFullbrightNonIndexedProgram.mFeatures.isFullbright = true; +		gObjectFullbrightNonIndexedProgram.mFeatures.disableTextureIndex = true; +		gObjectFullbrightNonIndexedProgram.mShaderFiles.clear(); +		gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); +		gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gObjectFullbrightNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		success = gObjectFullbrightNonIndexedProgram.createShader(NULL, NULL); +	} + +	if (success) +	{ +		gObjectFullbrightNonIndexedWaterProgram.mName = "Non Indexed Fullbright Water Shader"; +		gObjectFullbrightNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; +		gObjectFullbrightNonIndexedWaterProgram.mFeatures.isFullbright = true; +		gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasWaterFog = true;		 +		gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasTransport = true; +		gObjectFullbrightNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; +		gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.clear(); +		gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); +		gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gObjectFullbrightNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectFullbrightNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; +		success = gObjectFullbrightNonIndexedWaterProgram.createShader(NULL, NULL); +	} + +	if (success) +	{ +		gObjectShinyNonIndexedProgram.mName = "Non Indexed Shiny Shader"; +		gObjectShinyNonIndexedProgram.mFeatures.calculatesAtmospherics = true; +		gObjectShinyNonIndexedProgram.mFeatures.calculatesLighting = true; +		gObjectShinyNonIndexedProgram.mFeatures.hasGamma = true; +		gObjectShinyNonIndexedProgram.mFeatures.hasAtmospherics = true; +		gObjectShinyNonIndexedProgram.mFeatures.isShiny = true; +		gObjectShinyNonIndexedProgram.mFeatures.disableTextureIndex = true; +		gObjectShinyNonIndexedProgram.mShaderFiles.clear(); +		gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); +		gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));		 +		gObjectShinyNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		success = gObjectShinyNonIndexedProgram.createShader(NULL, &mShinyUniforms); +	} + +	if (success) +	{ +		gObjectShinyNonIndexedWaterProgram.mName = "Non Indexed Shiny Water Shader"; +		gObjectShinyNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; +		gObjectShinyNonIndexedWaterProgram.mFeatures.calculatesLighting = true; +		gObjectShinyNonIndexedWaterProgram.mFeatures.isShiny = true; +		gObjectShinyNonIndexedWaterProgram.mFeatures.hasWaterFog = true; +		gObjectShinyNonIndexedWaterProgram.mFeatures.hasAtmospherics = true; +		gObjectShinyNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; +		gObjectShinyNonIndexedWaterProgram.mShaderFiles.clear(); +		gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); +		gObjectShinyNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; +		success = gObjectShinyNonIndexedWaterProgram.createShader(NULL, &mShinyUniforms); +	} +	 +	if (success) +	{ +		gObjectFullbrightShinyNonIndexedProgram.mName = "Non Indexed Fullbright Shiny Shader"; +		gObjectFullbrightShinyNonIndexedProgram.mFeatures.calculatesAtmospherics = true; +		gObjectFullbrightShinyNonIndexedProgram.mFeatures.isFullbright = true; +		gObjectFullbrightShinyNonIndexedProgram.mFeatures.isShiny = true; +		gObjectFullbrightShinyNonIndexedProgram.mFeatures.hasGamma = true; +		gObjectFullbrightShinyNonIndexedProgram.mFeatures.hasTransport = true; +		gObjectFullbrightShinyNonIndexedProgram.mFeatures.disableTextureIndex = true; +		gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.clear(); +		gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); +		gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gObjectFullbrightShinyNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		success = gObjectFullbrightShinyNonIndexedProgram.createShader(NULL, &mShinyUniforms); +	} + +	if (success) +	{ +		gObjectFullbrightShinyNonIndexedWaterProgram.mName = "Non Indexed Fullbright Shiny Water Shader"; +		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; +		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.isFullbright = true; +		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.isShiny = true; +		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasGamma = true; +		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasTransport = true; +		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasWaterFog = true; +		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; +		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.clear(); +		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); +		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; +		success = gObjectFullbrightShinyNonIndexedWaterProgram.createShader(NULL, &mShinyUniforms); +	} + +	if (success) +	{  		gObjectSimpleProgram.mName = "Simple Shader";  		gObjectSimpleProgram.mFeatures.calculatesLighting = true;  		gObjectSimpleProgram.mFeatures.calculatesAtmospherics = true; @@ -1526,6 +1782,11 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectSimpleProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];  		success = gObjectSimpleProgram.createShader(NULL, NULL); + +		if (success && batch_textures) +		{ +			setup_indexed_texture(gObjectSimpleProgram); +		}  	}  	if (success) @@ -1542,6 +1803,11 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];  		gObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectSimpleWaterProgram.createShader(NULL, NULL); + +		if (success && batch_textures) +		{ +			setup_indexed_texture(gObjectSimpleWaterProgram); +		}  	}  	if (success) @@ -1556,6 +1822,10 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectFullbrightProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];  		success = gObjectFullbrightProgram.createShader(NULL, NULL); +		if (success && batch_textures) +		{ +			setup_indexed_texture(gObjectFullbrightProgram); +		}  	}  	if (success) @@ -1571,6 +1841,10 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];  		gObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectFullbrightWaterProgram.createShader(NULL, NULL); +		if (success && batch_textures) +		{ +			setup_indexed_texture(gObjectFullbrightWaterProgram); +		}  	}  	if (success) @@ -1586,6 +1860,10 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));		  		gObjectShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];  		success = gObjectShinyProgram.createShader(NULL, &mShinyUniforms); +		if (success && batch_textures) +		{ +			setup_indexed_texture_with_cubemap(gObjectShinyProgram); +		}  	}  	if (success) @@ -1602,6 +1880,10 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];  		gObjectShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectShinyWaterProgram.createShader(NULL, &mShinyUniforms); +		if (success && batch_textures) +		{ +			setup_indexed_texture_with_cubemap(gObjectShinyWaterProgram); +		}  	}  	if (success) @@ -1617,6 +1899,10 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];  		success = gObjectFullbrightShinyProgram.createShader(NULL, &mShinyUniforms); +		if (success && batch_textures) +		{ +			setup_indexed_texture_with_cubemap(gObjectFullbrightShinyProgram); +		}  	}  	if (success) @@ -1634,6 +1920,10 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];  		gObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		success = gObjectFullbrightShinyWaterProgram.createShader(NULL, &mShinyUniforms); +		if (success && batch_textures) +		{ +			setup_indexed_texture_with_cubemap(gObjectFullbrightShinyWaterProgram); +		}  	}  	if (mVertexShaderLevel[SHADER_AVATAR] > 0) @@ -1647,6 +1937,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectSimpleProgram.mFeatures.hasAtmospherics = true;  			gSkinnedObjectSimpleProgram.mFeatures.hasLighting = true;  			gSkinnedObjectSimpleProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectSimpleProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectSimpleProgram.mShaderFiles.clear();  			gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1662,6 +1953,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightProgram.mFeatures.hasTransport = true;  			gSkinnedObjectFullbrightProgram.mFeatures.isFullbright = true;  			gSkinnedObjectFullbrightProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectFullbrightProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectFullbrightProgram.mShaderFiles.clear();  			gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1678,6 +1970,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightShinyProgram.mFeatures.isShiny = true;  			gSkinnedObjectFullbrightShinyProgram.mFeatures.isFullbright = true;  			gSkinnedObjectFullbrightShinyProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectFullbrightShinyProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.clear();  			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1694,6 +1987,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectShinySimpleProgram.mFeatures.hasAtmospherics = true;  			gSkinnedObjectShinySimpleProgram.mFeatures.hasObjectSkinning = true;  			gSkinnedObjectShinySimpleProgram.mFeatures.isShiny = true; +			gSkinnedObjectShinySimpleProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectShinySimpleProgram.mShaderFiles.clear();  			gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1709,9 +2003,11 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectSimpleWaterProgram.mFeatures.hasGamma = true;  			gSkinnedObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true;  			gSkinnedObjectSimpleWaterProgram.mFeatures.hasLighting = true; +			gSkinnedObjectSimpleWaterProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectSimpleWaterProgram.mFeatures.hasWaterFog = true;  			gSkinnedObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  			gSkinnedObjectSimpleWaterProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectSimpleWaterProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectSimpleWaterProgram.mShaderFiles.clear();  			gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1728,6 +2024,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightWaterProgram.mFeatures.isFullbright = true;  			gSkinnedObjectFullbrightWaterProgram.mFeatures.hasObjectSkinning = true;  			gSkinnedObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true; +			gSkinnedObjectFullbrightWaterProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  			gSkinnedObjectFullbrightWaterProgram.mShaderFiles.clear();  			gSkinnedObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1746,6 +2043,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true;  			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasObjectSkinning = true;  			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true; +			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  			gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.clear();  			gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1764,6 +2062,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasObjectSkinning = true;  			gSkinnedObjectShinySimpleWaterProgram.mFeatures.isShiny = true;  			gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasWaterFog = true; +			gSkinnedObjectShinySimpleWaterProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectShinySimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  			gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.clear();  			gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index f5371f0619..6ecba65470 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -298,16 +298,25 @@ extern LLVector4			gShinyOrigin;  //object shaders  extern LLGLSLShader			gObjectSimpleProgram;  extern LLGLSLShader			gObjectSimpleWaterProgram; +extern LLGLSLShader			gObjectSimpleNonIndexedProgram; +extern LLGLSLShader			gObjectSimpleNonIndexedWaterProgram;  extern LLGLSLShader			gObjectFullbrightProgram;  extern LLGLSLShader			gObjectFullbrightWaterProgram; +extern LLGLSLShader			gObjectFullbrightNonIndexedProgram; +extern LLGLSLShader			gObjectFullbrightNonIndexedWaterProgram;  extern LLGLSLShader			gObjectSimpleLODProgram;  extern LLGLSLShader			gObjectFullbrightLODProgram;  extern LLGLSLShader			gObjectFullbrightShinyProgram;  extern LLGLSLShader			gObjectFullbrightShinyWaterProgram; +extern LLGLSLShader			gObjectFullbrightShinyNonIndexedProgram; +extern LLGLSLShader			gObjectFullbrightShinyNonIndexedWaterProgram; +  extern LLGLSLShader			gObjectShinyProgram;  extern LLGLSLShader			gObjectShinyWaterProgram; +extern LLGLSLShader			gObjectShinyNonIndexedProgram; +extern LLGLSLShader			gObjectShinyNonIndexedWaterProgram;  extern LLGLSLShader			gSkinnedObjectSimpleProgram;  extern LLGLSLShader			gSkinnedObjectFullbrightProgram; @@ -349,6 +358,7 @@ extern LLGLSLShader			gDeferredImpostorProgram;  extern LLGLSLShader			gDeferredEdgeProgram;  extern LLGLSLShader			gDeferredWaterProgram;  extern LLGLSLShader			gDeferredDiffuseProgram; +extern LLGLSLShader			gDeferredNonIndexedDiffuseProgram;  extern LLGLSLShader			gDeferredSkinnedDiffuseProgram;  extern LLGLSLShader			gDeferredSkinnedBumpProgram;  extern LLGLSLShader			gDeferredSkinnedAlphaProgram; @@ -373,6 +383,7 @@ extern LLGLSLShader			gDeferredAvatarShadowProgram;  extern LLGLSLShader			gDeferredAttachmentShadowProgram;  extern LLGLSLShader			gDeferredAlphaProgram;  extern LLGLSLShader			gDeferredFullbrightProgram; +extern LLGLSLShader			gDeferredAvatarEyesProgram;  extern LLGLSLShader			gDeferredAvatarAlphaProgram;  extern LLGLSLShader			gDeferredWLSkyProgram;  extern LLGLSLShader			gDeferredWLCloudProgram; diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 6f354b78b1..a4b0910c92 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -324,10 +324,18 @@ void LLVOPartGroup::getGeometry(S32 idx,  	LLVector3 normal = -LLViewerCamera::getInstance()->getXAxis(); -		 + +	//HACK -- the verticesp->mV[3] = 0.f here are to set the texture index to 0 (particles don't use texture batching, maybe they should) +	// 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;  	*colorsp++ = part.mColor; @@ -360,7 +368,7 @@ U32 LLVOPartGroup::getPartitionType() const  }  LLParticlePartition::LLParticlePartition() -: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK, TRUE, GL_STREAM_DRAW_ARB) +: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB)  {  	mRenderPass = LLRenderPass::PASS_ALPHA;  	mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES; @@ -418,6 +426,7 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co  			mFaceList.push_back(facep);  			vertex_count += facep->getGeomCount();  			index_count += facep->getIndicesCount(); +			llassert(facep->getIndicesCount() < 65536);  		}  		obj->mDepth /= count; diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 6396bc042d..800af26b69 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -1483,6 +1483,8 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons  		facep->setVertexBuffer(buff);  	} +	llassert(facep->getVertexBuffer()->getNumIndices() == 6); +  	index_offset = facep->getGeometry(verticesp,normalsp,texCoordsp, indicesp);  	if (-1 == index_offset) diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index dbcd4f50ca..510525259f 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -375,6 +375,8 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep,  	S32 num_vertices, num_indices;  	U32 index; +	llassert(mLastStride > 0); +  	render_stride = mLastStride;  	patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();  	S32 vert_size = patch_size / render_stride; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index cc443d32fb..713724cf46 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -73,6 +73,7 @@  #include "llagent.h"  #include "llviewermediafocus.h"  #include "lldatapacker.h" +#include "llviewershadermgr.h"  #include "llvoavatar.h"  #include "llvocache.h" @@ -1247,17 +1248,7 @@ BOOL LLVOVolume::calcLOD()  	{  		//setDebugText(llformat("%.2f:%.2f, %d", debug_distance, radius, cur_detail)); -		F32 bin_radius = getBinRadius(); -		F32 node_size = 0.f;  - -		LLSpatialGroup* group = mDrawable->getSpatialGroup(); -		if (group) -		{ -			LLSpatialGroup::OctreeNode* node = group->mOctreeNode; -			node_size = node->getSize()[0]; -		} - -		setDebugText(llformat("%.2f:%.2f", bin_radius, node_size)); +		setDebugText(llformat("%d", mDrawable->getFace(0)->getTextureIndex()));  	}  	if (cur_detail != mLOD) @@ -3734,6 +3725,21 @@ LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep)  	mSlopRatio = 0.25f;  } +bool can_batch_texture(LLFace* facep) +{ +	if (facep->getTextureEntry()->getBumpmap()) +	{ //bump maps aren't worked into texture batching yet +		return false; +	} + +	if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE) +	{ //texture animation breaks batches +		return false; +	} +	 +	return true; +} +  void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type)  {  	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -3784,12 +3790,36 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  	LLViewerTexture* tex = facep->getTexture(); +	U8 index = facep->getTextureIndex(); + +	bool batchable = false; + +	if (index < 255 && idx >= 0) +	{ +		if (index < draw_vec[idx]->mTextureList.size()) +		{ +			if (draw_vec[idx]->mTextureList[index].isNull()) +			{ +				batchable = true; +				draw_vec[idx]->mTextureList[index] = tex; +			} +			else if (draw_vec[idx]->mTextureList[index] == tex) +			{ //this face's texture index can be used with this batch +				batchable = true; +			} +		} +		else +		{ //texture list can be expanded to fit this texture index +			batchable = true; +		} +	} +	  	U8 glow = (U8) (facep->getTextureEntry()->getGlow() * 255);  	if (idx >= 0 &&   		draw_vec[idx]->mVertexBuffer == facep->getVertexBuffer() &&  		draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && -		(LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex) && +		(LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex || batchable) &&  #if LL_DARWIN  		draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange &&  		draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && @@ -3803,6 +3833,12 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		draw_vec[idx]->mCount += facep->getIndicesCount();  		draw_vec[idx]->mEnd += facep->getGeomCount();  		draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize()); + +		if (index >= draw_vec[idx]->mTextureList.size()) +		{ +			draw_vec[idx]->mTextureList.resize(index+1); +			draw_vec[idx]->mTextureList[index] = tex; +		}  		draw_vec[idx]->validate();  		update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]);  		update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[1]); @@ -3833,6 +3869,11 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  			draw_info->mDrawMode = LLRender::TRIANGLE_STRIP;  		} +		if (index < 255) +		{ //initialize texture list for texture batching +			draw_info->mTextureList.resize(index+1); +			draw_info->mTextureList[index] = tex; +		}  		draw_info->validate();  	}  } @@ -4255,15 +4296,24 @@ 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 (LLPipeline::sRenderDeferred) +	bool batch_textures = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1; + +	if (batch_textures)  	{  		bump_mask |= LLVertexBuffer::MAP_BINORMAL; +		genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, FALSE, TRUE); +		genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, FALSE, TRUE); +		genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, FALSE, TRUE); +		genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, TRUE, TRUE); +	} +	else +	{ +		genDrawInfo(group, simple_mask, simple_faces); +		genDrawInfo(group, fullbright_mask, fullbright_faces); +		genDrawInfo(group, bump_mask, bump_faces, FALSE, TRUE); +		genDrawInfo(group, alpha_mask, alpha_faces, TRUE);  	} -	genDrawInfo(group, simple_mask, simple_faces); -	genDrawInfo(group, bump_mask, bump_faces); -	genDrawInfo(group, fullbright_mask, fullbright_faces); -	genDrawInfo(group, alpha_mask, alpha_faces, TRUE);  	if (!LLPipeline::sDelayVBUpdate)  	{ @@ -4376,7 +4426,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  	llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO));  } -void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort) +void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures)  {  	//calculate maximum number of vertices to store in a single buffer  	U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); @@ -4435,19 +4485,101 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  		std::vector<LLFace*>::iterator i = face_iter;  		++i; -		while (i != faces.end() &&  -			(LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) +		std::vector<LLViewerTexture*> texture_list; + +		if (batch_textures)  		{ -			facep = *i; -			 -			if (geom_count + facep->getGeomCount() > max_vertices) -			{ //cut batches on geom count too big -				break; +			U8 cur_tex = 0; +			facep->setTextureIndex(cur_tex); +			texture_list.push_back(tex); + +			//if (can_batch_texture(facep)) +			{ +				while (i != faces.end()) +				{ +					facep = *i; +					if (facep->getTexture() != tex) +					{ +						if (distance_sort) +						{ //textures might be out of order, see if texture exists in current batch +							bool found = false; +							for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx) +							{ +								if (facep->getTexture() == texture_list[tex_idx]) +								{ +									cur_tex = tex_idx; +									found = true; +									break; +								} +							} + +							if (!found) +							{ +								cur_tex = texture_list.size(); +							} +						} +						else +						{ +							cur_tex++; + +							if (cur_tex >= 7 && facep->getTextureEntry()->getShiny()) +							{ //entry 7 is reserved for the environment map for shiny faces +								break; +							} +						} + +						if (!can_batch_texture(facep)) +						{ //face is bump mapped or has an animated texture matrix -- can't  +							//batch more than 1 texture at a time +							break; +						} + +						if (cur_tex >= 8) +						{ //cut batches on every 8 textures +							break; +						} + +						tex = facep->getTexture(); + +						texture_list.push_back(tex); +					} + +					if (geom_count + facep->getGeomCount() > max_vertices) +					{ //cut batches on geom count too big +						break; +					} + +					++i; +					index_count += facep->getIndicesCount(); +					geom_count += facep->getGeomCount(); + +					facep->setTextureIndex(cur_tex); +				}  			} -			++i; -			index_count += facep->getIndicesCount(); -			geom_count += facep->getGeomCount(); +			tex = texture_list[0]; +		} +		else +		{ +			while (i != faces.end() &&  +				(LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) +			{ +				facep = *i; +			 + +				//face has no texture index +				facep->mDrawInfo = NULL; +				facep->setTextureIndex(255); + +				if (geom_count + facep->getGeomCount() > max_vertices) +				{ //cut batches on geom count too big +					break; +				} + +				++i; +				index_count += facep->getIndicesCount(); +				geom_count += facep->getGeomCount(); +			}  		}  		//create/delete/resize vertex buffer if needed @@ -4497,6 +4629,11 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  			facep->setGeomIndex(index_offset);  			facep->setVertexBuffer(buffer);	 +			if (batch_textures && facep->getTextureIndex() == 255) +			{ +				llerrs << "Invalid texture index." << llendl; +			} +			  			{  				//for debugging, set last time face was updated vs moved  				facep->updateRebuildFlags(); @@ -4695,7 +4832,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun  			{  				vertex_count += facep->getGeomCount();  				index_count += facep->getIndicesCount(); - +				llassert(facep->getIndicesCount() < 65536);  				//remember face (for sorting)  				mFaceList.push_back(facep);  			} diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index fadae7c71e..1489c033e2 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -3606,7 +3606,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)  					if (gDebugGL)  					{  						check_stack_depth(stack_depth); -						std::string msg = llformat("%s pass %d", gPoolNames[cur_type].c_str(), i); +						std::string msg = llformat("pass %d", i);  						LLGLState::checkStates(msg);  						LLGLState::checkTextureChannels(msg);  						LLGLState::checkClientArrays(msg); @@ -6568,8 +6568,6 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen  		noise_map = mNoiseMap;  	} -	LLGLState::checkTextureChannels(); -  	shader.bind();  	S32 channel = 0;  	channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage()); @@ -7852,8 +7850,6 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)  	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  	gGL.getTexUnit(0)->activate();  	shader.unbind(); - -	LLGLState::checkTextureChannels();  }  inline float sgn(float a) | 
