diff options
22 files changed, 1181 insertions, 56 deletions
| diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 01541026b1..b1ef6e0576 100755 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -2239,7 +2239,32 @@ void LLVertexBuffer::setBuffer(U32 data_mask)  			if ((data_mask & required_mask) != required_mask)  			{ -				llwarns << "Shader consumption mismatches data provision." << llendl; +				 +				U32 unsatisfied_mask = (required_mask & ~data_mask); +				U32 i = 0; + +				while (i < 15) +				{ +					switch ((unsatisfied_mask & (1 << i))) +					{ +						case MAP_VERTEX: llinfos << "Missing vert pos" << llendl; break; +						case MAP_NORMAL: llinfos << "Missing normals" << llendl; break; +						case MAP_TEXCOORD0: llinfos << "Missing TC 0" << llendl; break; +						case MAP_TEXCOORD1: llinfos << "Missing TC 1" << llendl; break; +						case MAP_TEXCOORD2: llinfos << "Missing TC 2" << llendl; break; +						case MAP_TEXCOORD3: llinfos << "Missing TC 3" << llendl; break; +						case MAP_COLOR: llinfos << "Missing vert color" << llendl; break; +						case MAP_EMISSIVE: llinfos << "Missing emissive" << llendl; break; +						case MAP_TANGENT: llinfos << "Missing tangent" << llendl; break; +						case MAP_WEIGHT: llinfos << "Missing weight" << llendl; break; +						case MAP_WEIGHT4: llinfos << "Missing weightx4" << llendl; break; +						case MAP_CLOTHWEIGHT: llinfos << "Missing clothweight" << llendl; break; +						case MAP_TEXTURE_INDEX: llinfos << "Missing tex index" << llendl; break; +						default: llinfos << "Missing who effin knows" << llendl; +					}					 +				} + +				llerrs << "Shader consumption mismatches data provision." << llendl;  			}  		}  	} diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ebb01fb330..2d3b32159a 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9621,6 +9621,17 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>RenderWaterMaterials</key> +    <map> +      <key>Comment</key> +      <string>Water planar reflections include materials rendering.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>RenderWaterMipNormal</key>      <map>        <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl index 59d109b886..8525e13333 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl @@ -50,7 +50,7 @@ void main()  	{  		discard;  	} - +	  	frag_data[0] = vec4(col.rgb, 0.0);  	frag_data[1] = vec4(0,0,0,0);  	vec3 nvn = normalize(vary_normal); diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index 90518128fb..33c07a6e08 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -69,11 +69,11 @@ void main()  	vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);  #endif +	color.rgb *= vertex_color.rgb;  	color.rgb = srgb_to_linear(color.rgb);  	color.rgb = fullbrightAtmosTransport(color.rgb);  	color.rgb = fullbrightScaleSoftClip(color.rgb); -	color.rgb *= vertex_color.rgb;  	color.rgb = linear_to_srgb(color.rgb); diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index 027c6eeadb..9ce4d89df7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -51,7 +51,6 @@ vec3 linear_to_srgb(vec3 cl)  	return 1.055 * pow(cl, vec3(0.41666)) - 0.055;  } -  #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)  #ifdef DEFINE_GL_FRAGCOLOR @@ -136,6 +135,52 @@ uniform vec3 light_direction[8];  uniform vec3 light_attenuation[8];   uniform vec3 light_diffuse[8]; +#ifdef WATER_FOG +uniform vec4 waterPlane; +uniform vec4 waterFogColor; +uniform float waterFogDensity; +uniform float waterFogKS; + +vec4 applyWaterFogDeferred(vec3 pos, vec4 color) +{ +	//normalize view vector +	vec3 view = normalize(pos); +	float es = -(dot(view, waterPlane.xyz)); + +	//find intersection point with water plane and eye vector +	 +	//get eye depth +	float e0 = max(-waterPlane.w, 0.0); +	 +	vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0); +	 +	//get object depth +	float depth = length(pos - int_v); +		 +	//get "thickness" of water +	float l = max(depth, 0.1); + +	float kd = waterFogDensity; +	float ks = waterFogKS; +	vec4 kc = waterFogColor; +	 +	float F = 0.98; +	 +	float t1 = -kd * pow(F, ks * e0); +	float t2 = kd + ks * es; +	float t3 = pow(F, t2*l) - 1.0; +	 +	float L = min(t1/t2*t3, 1.0); +	 +	float D = pow(0.98, l*kd); +	 +	color.rgb = color.rgb * D + kc.rgb * L; +	color.a = kc.a + color.a; +	 +	return color; +} +#endif +  vec3 calcDirectionalLight(vec3 n, vec3 l)  {  	float a = max(dot(n,l),0.0); @@ -221,10 +266,6 @@ vec4 getPosition_d(vec2 pos_screen, float depth)  	return pos;  } -vec3 getPositionEye() -{ -	return vary_PositionEye; -}  vec3 getSunlitColor()  {  	return vary_SunlitColor; @@ -672,7 +713,6 @@ void main()  	//convert to linear space before adding local lights  	col = srgb_to_linear(col); -			  	vec3 npos = normalize(-pos.xyz);   #define LIGHT_LOOP(i) col.rgb = col.rgb + calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare); @@ -685,13 +725,17 @@ void main()  		LIGHT_LOOP(6)  		LIGHT_LOOP(7) +	glare = min(glare, 1.0); +	float al = max(diffcol.a,glare)*vertex_color.a; -	//convert to gamma space for display on screen -	col.rgb = linear_to_srgb(col.rgb); +#ifdef WATER_FOG +	vec4 temp = applyWaterFogDeferred(pos, vec4(col.rgb, al)); +	col.rgb = temp.rgb; +	al = temp.a; +#endif  	frag_color.rgb = col.rgb; -	glare = min(glare, 1.0); -	frag_color.a = max(diffcol.a,glare)*vertex_color.a; +	frag_color.a   = al;  #else  	frag_data[0] = final_color; @@ -699,3 +743,4 @@ void main()  	frag_data[2] = final_normal; // XY = Normal.  Z = Env. intensity.  #endif  } + diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl index b25032866b..393d1e69da 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl @@ -142,3 +142,4 @@ vary_normal  = n;  #endif  #endif  } + diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index dc2519bd0a..953f0189f0 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -133,6 +133,7 @@ vec3 getPositionEye()  {  	return vary_PositionEye;  } +  vec3 getSunlitColor()  {  	return vary_SunlitColor; @@ -175,6 +176,53 @@ void setAtmosAttenuation(vec3 v)  	vary_AtmosAttenuation = v;  } + +#ifdef WATER_FOG +uniform vec4 waterPlane; +uniform vec4 waterFogColor; +uniform float waterFogDensity; +uniform float waterFogKS; + +vec4 applyWaterFogDeferred(vec3 pos, vec4 color) +{ +	//normalize view vector +	vec3 view = normalize(pos); +	float es = -(dot(view, waterPlane.xyz)); + +	//find intersection point with water plane and eye vector +	 +	//get eye depth +	float e0 = max(-waterPlane.w, 0.0); +	 +	vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0); +	 +	//get object depth +	float depth = length(pos - int_v); +		 +	//get "thickness" of water +	float l = max(depth, 0.1); + +	float kd = waterFogDensity; +	float ks = waterFogKS; +	vec4 kc = waterFogColor; +	 +	float F = 0.98; +	 +	float t1 = -kd * pow(F, ks * e0); +	float t2 = kd + ks * es; +	float t3 = pow(F, t2*l) - 1.0; +	 +	float L = min(t1/t2*t3, 1.0); +	 +	float D = pow(0.98, l*kd); +	 +	color.rgb = color.rgb * D + kc.rgb * L; +	color.a = kc.a + color.a; +	 +	return color; +} +#endif +  void calcAtmospherics(vec3 inPositionEye, float ambFactor) {  	vec3 P = inPositionEye; @@ -388,7 +436,14 @@ void main()  		if (norm.w < 0.5)  		{  			col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a); -			col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a); + +			#ifdef WATER_FOG +				vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom)); +				col = fogged.rgb; +				bloom = fogged.a; +			#endif + +			col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);			  		}  		col = srgb_to_linear(col); @@ -397,7 +452,7 @@ void main()  		//col.g = envIntensity;  	} -	frag_color.rgb = col; - +	frag_color.rgb = col.rgb;  	frag_color.a = bloom;  } + diff --git a/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl new file mode 100644 index 0000000000..938947bbce --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl @@ -0,0 +1,140 @@ +/** + * @file underWaterF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ +  +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData +#endif + +uniform sampler2D diffuseMap; +uniform sampler2D bumpMap;    +uniform sampler2D screenTex; +uniform sampler2D refTex; +uniform sampler2D screenDepth; + +uniform vec4 fogCol; +uniform vec3 lightDir; +uniform vec3 specular; +uniform float lightExp; +uniform vec2 fbScale; +uniform float refScale; +uniform float znear; +uniform float zfar; +uniform float kd; +uniform vec4 waterPlane; +uniform vec3 eyeVec; +uniform vec4 waterFogColor; +uniform float waterFogDensity; +uniform float waterFogKS; +uniform vec2 screenRes; + +//bigWave is (refCoord.w, view.w); +VARYING vec4 refCoord; +VARYING vec4 littleWave; +VARYING vec4 view; + +vec3 srgb_to_linear(vec3 cs) +{ +	 +/*        {  cs / 12.92,                 cs <= 0.04045 +    cl = { +        {  ((cs + 0.055)/1.055)^2.4,   cs >  0.04045*/ + +	return pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); +} + +vec3 linear_to_srgb(vec3 cl) +{ +	    /*{  0.0,                          0         <= cl +            {  12.92 * c,                    0         <  cl < 0.0031308 +    cs = {  1.055 * cl^0.41666 - 0.055,   0.0031308 <= cl < 1 +            {  1.0,                                       cl >= 1*/ + +	return 1.055 * pow(cl, vec3(0.41666)) - 0.055; +} + +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec4 applyWaterFog(vec4 color, vec3 viewVec) +{ +	//normalize view vector +	vec3 view = normalize(viewVec); +	float es = -view.z; + +	//find intersection point with water plane and eye vector +	 +	//get eye depth +	float e0 = max(-waterPlane.w, 0.0); +	 +	//get object depth +	float depth = length(viewVec); +		 +	//get "thickness" of water +	float l = max(depth, 0.1); + +	float kd = waterFogDensity; +	float ks = waterFogKS; +	vec4 kc = waterFogColor; +	 +	float F = 0.98; +	 +	float t1 = -kd * pow(F, ks * e0); +	float t2 = kd + ks * es; +	float t3 = pow(F, t2*l) - 1.0; +	 +	float L = min(t1/t2*t3, 1.0); +	 +	float D = pow(0.98, l*kd); +	//return vec4(1.0, 0.0, 1.0, 1.0); +	return color * D + kc * L; +	//depth /= 10.0; +	//return vec4(depth,depth,depth,0.0); +} + +void main()  +{ +	vec4 color; +	     +	//get detail normals +	vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0; +	vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0; +	vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;     +	vec3 wavef = normalize(wave1+wave2+wave3); +	 +	//figure out distortion vector (ripply)    +	vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; +	distort = distort+wavef.xy*refScale; +		 +	vec4 fb = texture2D(screenTex, distort); + +	frag_data[0] = vec4(linear_to_srgb(fb.rgb), 1.0); // diffuse +	frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec +	frag_data[2] = vec4(encode_normal(wavef), 0.0, 0.0); // normalxyz, displace +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index daa2fb390a..17288873c8 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -67,6 +67,26 @@ VARYING vec4 littleWave;  VARYING vec4 view;  VARYING vec4 vary_position; +vec3 srgb_to_linear(vec3 cs) +{ +	 +/*        {  cs / 12.92,                 cs <= 0.04045 +    cl = { +        {  ((cs + 0.055)/1.055)^2.4,   cs >  0.04045*/ + +	return pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); +} + +vec3 linear_to_srgb(vec3 cl) +{ +	    /*{  0.0,                          0         <= cl +            {  12.92 * c,                    0         <  cl < 0.0031308 +    cs = {  1.055 * cl^0.41666 - 0.055,   0.0031308 <= cl < 1 +            {  1.0,                                       cl >= 1*/ + +	return 1.055 * pow(cl, vec3(0.41666)) - 0.055; +} +  vec2 encode_normal(vec3 n)  {  	float f = sqrt(8 * n.z + 8); @@ -116,6 +136,10 @@ void main()  	vec2 refvec3 = distort+refdistort3/dmod_scale;  	vec4 refcol3 = texture2D(refTex, refvec3); +	refcol1.rgb = srgb_to_linear(refcol1.rgb); +	refcol2.rgb = srgb_to_linear(refcol2.rgb); +	refcol3.rgb = srgb_to_linear(refcol3.rgb); +  	vec4 refcol = refcol1 + refcol2 + refcol3;  	float df1 = df.x + df.y + df.z;  	refcol *= df1 * 0.333; @@ -131,6 +155,9 @@ void main()  	vec2 refvec4 = distort+refdistort4/dmod;  	float dweight = min(dist2*blurMultiplier, 1.0);  	vec4 baseCol = texture2D(refTex, refvec4); + +	baseCol.rgb = srgb_to_linear(baseCol.rgb); +  	refcol = mix(baseCol*df2, refcol, dweight);  	//get specular component @@ -165,7 +192,7 @@ void main()  	//wavef = normalize(wavef);  	vec3 screenspacewavef = (norm_mat*vec4(wavef, 1.0)).xyz; -	frag_data[0] = vec4(color.rgb, 0.5); // diffuse +	frag_data[0] = vec4(linear_to_srgb(color.rgb), 0.5); // diffuse  	frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec  	frag_data[2] = vec4(encode_normal(screenspacewavef), 0.0, 0.0); // normalxyz, displace  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 06447261b4..9b72c5b57d 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -266,6 +266,52 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {  	setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));  } +#ifdef WATER_FOG +uniform vec4 waterPlane; +uniform vec4 waterFogColor; +uniform float waterFogDensity; +uniform float waterFogKS; + +vec4 applyWaterFogDeferred(vec3 pos, vec4 color) +{ +	//normalize view vector +	vec3 view = normalize(pos); +	float es = -(dot(view, waterPlane.xyz)); + +	//find intersection point with water plane and eye vector +	 +	//get eye depth +	float e0 = max(-waterPlane.w, 0.0); +	 +	vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0); +	 +	//get object depth +	float depth = length(pos - int_v); +		 +	//get "thickness" of water +	float l = max(depth, 0.1); + +	float kd = waterFogDensity; +	float ks = waterFogKS; +	vec4 kc = waterFogColor; +	 +	float F = 0.98; +	 +	float t1 = -kd * pow(F, ks * e0); +	float t2 = kd + ks * es; +	float t3 = pow(F, t2*l) - 1.0; +	 +	float L = min(t1/t2*t3, 1.0); +	 +	float D = pow(0.98, l*kd); +	 +	color.rgb = color.rgb * D + kc.rgb * L; +	color.a = kc.a + color.a; +	 +	return color; +} +#endif +  vec3 atmosLighting(vec3 light)  {  	light *= getAtmosAttenuation().r; @@ -409,6 +455,13 @@ void main()  		if (norm.w < 0.5)  		{  			col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a); + +			#ifdef WATER_FOG +				vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom)); +				col = fogged.rgb; +				bloom = fogged.a; +			#endif +  			col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);  		} @@ -421,3 +474,4 @@ void main()  	frag_color.rgb = col;  	frag_color.a = bloom;  } + diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index c832e1401d..e53c783161 100755 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -113,6 +113,15 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)  		gObjectFullbrightAlphaMaskProgram.setMinimumAlpha(0.33f);  	} +	if (LLPipeline::sUnderWaterRender) +	{ +		emissive_shader = &gObjectEmissiveWaterProgram; +	} +	else +	{ +		emissive_shader = &gObjectEmissiveProgram; +	} +  	deferred_render = TRUE;  	if (mVertexShaderLevel > 0)  	{ @@ -352,7 +361,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  				LLMaterial* mat = NULL; -				if (deferred_render && !LLPipeline::sUnderWaterRender) +				if (deferred_render)  				{  					mat = params.mMaterial;  				} @@ -396,6 +405,11 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  					llassert(mask < LLMaterial::SHADER_COUNT);  					target_shader = &(gDeferredMaterialProgram[mask]); +					if (LLPipeline::sUnderWaterRender) +					{ +						target_shader = &(gDeferredMaterialWaterProgram[mask]); +					} +  					if (current_shader != target_shader)  					{  						gPipeline.bindDeferredShader(*target_shader); @@ -545,3 +559,4 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  		gPipeline.enableLightsDynamic();  	}  } + diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 075299386e..87e9071c4d 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -299,6 +299,11 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass)  	sVertexProgram = &gDeferredMaterialProgram[pass]; +	if (LLPipeline::sUnderWaterRender) +	{ +		sVertexProgram = &(gDeferredMaterialWaterProgram[pass]); +	} +  	gPipeline.bindDeferredShader(*sVertexProgram);  	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);  	normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP); @@ -676,12 +681,16 @@ void LLDrawPoolAvatar::beginDeferredImpostor()  		LLVOAvatar::sNumVisibleAvatars = 0;  	} +#if DEFERRED_IMPOSTORS  	sVertexProgram = &gDeferredImpostorProgram;  	specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);  	normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL);  	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - +#else +	sVertexProgram = &gImpostorProgram; +	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); +#endif  	sVertexProgram->bind();  	sVertexProgram->setMinimumAlpha(0.01f);  } @@ -1093,6 +1102,12 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass)  		return;  	}  	sVertexProgram = &gDeferredMaterialProgram[pass+LLMaterial::SHADER_COUNT]; + +	if (LLPipeline::sUnderWaterRender) +	{ +		sVertexProgram = &(gDeferredMaterialWaterProgram[pass+LLMaterial::SHADER_COUNT]); +	} +  	sVertexProgram->bind();  	normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);  	specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP); @@ -1237,6 +1252,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  		if (impostor)  		{ +#if DEFERRED_IMPOSTORS  			if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && avatarp->mImpostor.isComplete())   			{  				if (normal_channel > -1) @@ -1248,6 +1264,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  					avatarp->mImpostor.bindTexture(1, specular_channel);  				}  			} +#endif  			avatarp->renderImpostor(LLColor4U(255,255,255,255), sDiffuseChannel);  		}  		return; diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index 08a36bddf1..d1b5080650 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -72,6 +72,12 @@ void LLDrawPoolMaterials::beginDeferredPass(S32 pass)  	};  	mShader = &(gDeferredMaterialProgram[shader_idx[pass]]); + +	if (LLPipeline::sUnderWaterRender) +	{ +		mShader = &(gDeferredMaterialWaterProgram[shader_idx[pass]]); +	} +  	mShader->bind();  	diffuse_channel = mShader->enableTexture(LLShaderMgr::DIFFUSE_MAP); @@ -215,3 +221,4 @@ void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture,  		gGL.matrixMode(LLRender::MM_MODELVIEW);  	}  } + diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp index 7f7d9f65c6..ef8bdc3304 100755 --- a/indra/newview/lldrawpoolsky.cpp +++ b/indra/newview/lldrawpoolsky.cpp @@ -155,3 +155,4 @@ void LLDrawPoolSky::renderSkyCubeFace(U8 side)  void LLDrawPoolSky::endRenderPass( S32 pass )  {  } + diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 5ddc15df42..6774926f62 100755 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -522,13 +522,20 @@ void LLDrawPoolWater::shade()  	F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight(); -	if (deferred_render) +	if (eyedepth < 0.f && LLPipeline::sWaterReflections)  	{ -		shader = &gDeferredWaterProgram; +		if (deferred_render) +		{ +			shader = &gDeferredUnderWaterProgram; +		} +		else +		{ +			shader = &gUnderWaterProgram; +		}		  	} -	else if (eyedepth < 0.f && LLPipeline::sWaterReflections) +	else if (deferred_render)  	{ -		shader = &gUnderWaterProgram; +		shader = &gDeferredWaterProgram;  	}  	else  	{ diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index b5faff7968..53339222eb 100755 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -420,3 +420,4 @@ void LLDrawPoolWLSky::restoreGL()  		sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE);  	}  } + diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index f90b35a7bd..bbebeea3e0 100755 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -890,7 +890,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		{  			gGL.setColorMask(true, true); -			if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) +			if (LLPipeline::sRenderDeferred)  			{  				gPipeline.mDeferredScreen.bindTarget();  				glClearColor(1,0,1,1); @@ -939,7 +939,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			gGL.setColorMask(true, false); -			if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) +			if (LLPipeline::sRenderDeferred)  			{  				gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance());  			} @@ -976,7 +976,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		if (to_texture)  		{ -			if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) +			if (LLPipeline::sRenderDeferred)  			{  				gPipeline.mDeferredScreen.flush();  				if(LLRenderTarget::sUseFBO) @@ -1002,7 +1002,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			}  		} -		if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) +		if (LLPipeline::sRenderDeferred)  		{  			gPipeline.renderDeferredLighting();  		} @@ -1623,3 +1623,4 @@ void display_cleanup()  {  	gDisconnectedImagep = NULL;  } + diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 6d9a0dd261..e9c3990e9a 100755 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -168,6 +168,7 @@ LLGLSLShader			gPostNightVisionProgram;  // Deferred rendering shaders  LLGLSLShader			gDeferredImpostorProgram;  LLGLSLShader			gDeferredWaterProgram; +LLGLSLShader			gDeferredUnderWaterProgram;  LLGLSLShader			gDeferredDiffuseProgram;  LLGLSLShader			gDeferredDiffuseAlphaMaskProgram;  LLGLSLShader			gDeferredNonIndexedDiffuseProgram; @@ -189,6 +190,7 @@ LLGLSLShader			gDeferredMultiSpotLightProgram;  LLGLSLShader			gDeferredSunProgram;  LLGLSLShader			gDeferredBlurLightProgram;  LLGLSLShader			gDeferredSoftenProgram; +LLGLSLShader			gDeferredSoftenWaterProgram;  LLGLSLShader			gDeferredShadowProgram;  LLGLSLShader			gDeferredShadowCubeProgram;  LLGLSLShader			gDeferredShadowAlphaMaskProgram; @@ -215,6 +217,7 @@ LLGLSLShader			gNormalMapGenProgram;  // Deferred materials shaders  LLGLSLShader			gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; +LLGLSLShader			gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];  LLViewerShaderMgr::LLViewerShaderMgr() :  	mVertexShaderLevel(SHADER_COUNT, 0), @@ -280,6 +283,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() :  	mShaderList.push_back(&gUnderWaterProgram);  	mShaderList.push_back(&gDeferredSunProgram);  	mShaderList.push_back(&gDeferredSoftenProgram); +	mShaderList.push_back(&gDeferredSoftenWaterProgram);  	mShaderList.push_back(&gDeferredMaterialProgram[1]);  	mShaderList.push_back(&gDeferredMaterialProgram[5]);  	mShaderList.push_back(&gDeferredMaterialProgram[9]); @@ -288,6 +292,14 @@ LLViewerShaderMgr::LLViewerShaderMgr() :  	mShaderList.push_back(&gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT]);  	mShaderList.push_back(&gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT]);  	mShaderList.push_back(&gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT]);	 +	mShaderList.push_back(&gDeferredMaterialWaterProgram[1]); +	mShaderList.push_back(&gDeferredMaterialWaterProgram[5]); +	mShaderList.push_back(&gDeferredMaterialWaterProgram[9]); +	mShaderList.push_back(&gDeferredMaterialWaterProgram[13]); +	mShaderList.push_back(&gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT]); +	mShaderList.push_back(&gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT]); +	mShaderList.push_back(&gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT]); +	mShaderList.push_back(&gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT]);	  	mShaderList.push_back(&gDeferredAlphaProgram);  	mShaderList.push_back(&gDeferredSkinnedAlphaProgram);  	mShaderList.push_back(&gDeferredFullbrightProgram); @@ -298,6 +310,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() :  	mShaderList.push_back(&gDeferredEmissiveProgram);  	mShaderList.push_back(&gDeferredAvatarEyesProgram);  	mShaderList.push_back(&gDeferredWaterProgram); +	mShaderList.push_back(&gDeferredUnderWaterProgram);	  	mShaderList.push_back(&gDeferredAvatarAlphaProgram);  	mShaderList.push_back(&gDeferredWLSkyProgram);  	mShaderList.push_back(&gDeferredWLCloudProgram); @@ -1123,6 +1136,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSunProgram.unload();  		gDeferredBlurLightProgram.unload();  		gDeferredSoftenProgram.unload(); +		gDeferredSoftenWaterProgram.unload();  		gDeferredShadowProgram.unload();  		gDeferredShadowCubeProgram.unload();  		gDeferredShadowAlphaMaskProgram.unload(); @@ -1141,6 +1155,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredPostGammaCorrectProgram.unload();  		gFXAAProgram.unload();  		gDeferredWaterProgram.unload(); +		gDeferredUnderWaterProgram.unload();  		gDeferredWLSkyProgram.unload();  		gDeferredWLCloudProgram.unload();  		gDeferredStarProgram.unload(); @@ -1152,6 +1167,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)  		{  			gDeferredMaterialProgram[i].unload(); +			gDeferredMaterialWaterProgram[i].unload();  		}  		return TRUE;  	} @@ -1279,6 +1295,15 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;  	gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; +	gDeferredMaterialWaterProgram[1].mFeatures.hasLighting = false; +	gDeferredMaterialWaterProgram[5].mFeatures.hasLighting = false; +	gDeferredMaterialWaterProgram[9].mFeatures.hasLighting = false; +	gDeferredMaterialWaterProgram[13].mFeatures.hasLighting = false; +	gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; +	gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; +	gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; +	gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; +  	for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)  	{  		if (success) @@ -1305,6 +1330,34 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  			success = gDeferredMaterialProgram[i].createShader(NULL, NULL);  		} + +		if (success) +		{ +			gDeferredMaterialWaterProgram[i].mName = llformat("Deferred Underwater Material Shader %d", i); + +			U32 alpha_mode = i & 0x3; + +			gDeferredMaterialWaterProgram[i].mShaderFiles.clear(); +			gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB)); +			gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB)); +			gDeferredMaterialWaterProgram[i].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +			gDeferredMaterialWaterProgram[i].mShaderGroup = LLGLSLShader::SG_WATER; + +			gDeferredMaterialWaterProgram[i].addPermutation("HAS_NORMAL_MAP", i & 0x8? "1" : "0"); +			gDeferredMaterialWaterProgram[i].addPermutation("HAS_SPECULAR_MAP", i & 0x4 ? "1" : "0"); +			gDeferredMaterialWaterProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); +			gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0"); +			bool has_skin = i & 0x10; +			gDeferredMaterialWaterProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0"); +			gDeferredMaterialWaterProgram[i].addPermutation("WATER_FOG","1"); + +			if (has_skin) +			{ +				gDeferredMaterialWaterProgram[i].mFeatures.hasObjectSkinning = true; +			} + +			success = gDeferredMaterialWaterProgram[i].createShader(NULL, NULL);//&mWLUniforms); +		}  	}  	gDeferredMaterialProgram[1].mFeatures.hasLighting = true; @@ -1316,6 +1369,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;  	gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; +	gDeferredMaterialWaterProgram[1].mFeatures.hasLighting = true; +	gDeferredMaterialWaterProgram[5].mFeatures.hasLighting = true; +	gDeferredMaterialWaterProgram[9].mFeatures.hasLighting = true; +	gDeferredMaterialWaterProgram[13].mFeatures.hasLighting = true; +	gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; +	gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; +	gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; +	gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;  	if (success) @@ -1584,6 +1645,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ +		// load water shader +		gDeferredUnderWaterProgram.mName = "Deferred Under Water Shader"; +		gDeferredUnderWaterProgram.mFeatures.calculatesAtmospherics = true; +		gDeferredUnderWaterProgram.mFeatures.hasGamma = true; +		gDeferredUnderWaterProgram.mFeatures.hasTransport = true; +		gDeferredUnderWaterProgram.mShaderFiles.clear(); +		gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredUnderWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		success = gDeferredUnderWaterProgram.createShader(NULL, &mWaterUniforms); +	} + +	if (success) +	{  		gDeferredSoftenProgram.mName = "Deferred Soften Shader";  		gDeferredSoftenProgram.mShaderFiles.clear();  		gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1601,6 +1676,26 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ +		gDeferredSoftenWaterProgram.mName = "Deferred Soften Underwater Shader"; +		gDeferredSoftenWaterProgram.mShaderFiles.clear(); + +		gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + +		gDeferredSoftenWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredSoftenWaterProgram.addPermutation("WATER_FOG", "1"); +		gDeferredSoftenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + +		if (gSavedSettings.getBOOL("RenderDeferredSSAO")) +		{ //if using SSAO, take screen space light map into account as if shadows are enabled +			gDeferredSoftenWaterProgram.mShaderLevel = llmax(gDeferredSoftenWaterProgram.mShaderLevel, 2); +		} + +		success = gDeferredSoftenWaterProgram.createShader(NULL, &mWLUniforms); +	} + +	if (success) +	{  		gDeferredShadowProgram.mName = "Deferred Shadow Shader";  		gDeferredShadowProgram.mShaderFiles.clear();  		gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER_ARB)); @@ -3180,3 +3275,4 @@ LLViewerShaderMgr::shader_iter LLViewerShaderMgr::endShaders() const  {  	return mShaderList.end();  } + diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index f3a419b1f2..f14180d957 100755 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -330,6 +330,7 @@ extern LLGLSLShader			gPostNightVisionProgram;  // Deferred rendering shaders  extern LLGLSLShader			gDeferredImpostorProgram;  extern LLGLSLShader			gDeferredWaterProgram; +extern LLGLSLShader			gDeferredUnderWaterProgram;  extern LLGLSLShader			gDeferredDiffuseProgram;  extern LLGLSLShader			gDeferredDiffuseAlphaMaskProgram;  extern LLGLSLShader			gDeferredNonIndexedDiffuseAlphaMaskProgram; @@ -350,6 +351,7 @@ extern LLGLSLShader			gDeferredSunProgram;  extern LLGLSLShader			gDeferredBlurLightProgram;  extern LLGLSLShader			gDeferredAvatarProgram;  extern LLGLSLShader			gDeferredSoftenProgram; +extern LLGLSLShader			gDeferredSoftenWaterProgram;  extern LLGLSLShader			gDeferredShadowProgram;  extern LLGLSLShader			gDeferredShadowCubeProgram;  extern LLGLSLShader			gDeferredShadowAlphaMaskProgram; @@ -377,5 +379,6 @@ extern LLGLSLShader			gNormalMapGenProgram;  // Deferred materials shaders  extern LLGLSLShader			gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; - +extern LLGLSLShader			gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];  #endif + diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index b545e99a32..3d6c5398d5 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5390,7 +5390,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  					{  						if (te->getColor().mV[3] >= 0.999f)  						{ -							material_pass = true; +							registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);  						}  						else  						{ diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index c9f8a4d9ee..d88cb30887 100755 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -122,6 +122,10 @@  //#define DEBUG_INDICES  #endif +// Expensive and currently broken +// +#define MATERIALS_IN_REFLECTIONS 0 +  bool gShiftFrame = false;  //cached settings @@ -1232,13 +1236,30 @@ void LLPipeline::createGLBuffers()  	updateRenderDeferred(); +	bool materials_in_water = false; + +#if MATERIALS_IN_REFLECTIONS +	materials_in_water = gSavedSettings.getS32("RenderWaterMaterials"); +#endif +  	if (LLPipeline::sWaterReflections)  	{ //water reflection texture  		U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512); -			 -		mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE); -		//always use FBO for mWaterDis so it can be used for avatar texture bakes -		mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true); +		 +		// Set up SRGB targets if we're doing deferred-path reflection rendering +		// +		if (LLPipeline::sRenderDeferred && materials_in_water) +		{ +			mWaterRef.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE); +			//always use FBO for mWaterDis so it can be used for avatar texture bakes +			mWaterDis.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true); +		} +		else +		{ +			mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE); +			//always use FBO for mWaterDis so it can be used for avatar texture bakes +			mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true); +		}  	}  	mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE); @@ -2448,7 +2469,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl  	if (to_texture)  	{ -		if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) +		if (LLPipeline::sRenderDeferred)  		{  			mOcclusionDepth.bindTarget();  		} @@ -2593,7 +2614,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl  	if (to_texture)  	{ -		if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) +		if (LLPipeline::sRenderDeferred)  		{  			mOcclusionDepth.flush();  		} @@ -8466,7 +8487,7 @@ void LLPipeline::renderDeferredLighting()  		if (RenderDeferredAtmospheric)  		{ //apply sunlight contribution   			LLFastTimer ftm(FTM_ATMOSPHERICS); -			bindDeferredShader(gDeferredSoftenProgram);	 +			bindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);	  			{  				LLGLDepthTest depth(GL_FALSE);  				LLGLDisable blend(GL_BLEND); @@ -8488,7 +8509,7 @@ void LLPipeline::renderDeferredLighting()  				gGL.popMatrix();  			} -			unbindDeferredShader(gDeferredSoftenProgram); +			unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);  		}  		{ //render non-deferred geometry (fullbright, alpha, etc) @@ -8891,6 +8912,537 @@ void LLPipeline::renderDeferredLighting()  } +void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) +{ +	if (!sCull) +	{ +		return; +	} + +	{ +		LLFastTimer ftm(FTM_RENDER_DEFERRED); + +		LLViewerCamera* camera = LLViewerCamera::getInstance(); + +		{ +			LLGLDepthTest depth(GL_TRUE); +			mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), +							0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);	 +		} + +		LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); + +		if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) +		{ +			gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); +		} + +		//ati doesn't seem to love actually using the stencil buffer on FBO's +		LLGLDisable stencil(GL_STENCIL_TEST); +		//glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); +		//glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + +		gGL.setColorMask(true, true); +		 +		//draw a cube around every light +		LLVertexBuffer::unbind(); + +		LLGLEnable cull(GL_CULL_FACE); +		LLGLEnable blend(GL_BLEND); + +		glh::matrix4f mat = glh_copy_matrix(gGLModelView); + +		LLStrider<LLVector3> vert;  +		mDeferredVB->getVertexStrider(vert); +		 +		vert[0].set(-1,1,0); +		vert[1].set(-1,-3,0); +		vert[2].set(3,1,0); +		 +		{ +			setupHWLights(NULL); //to set mSunDir; +			LLVector4 dir(mSunDir, 0.f); +			glh::vec4f tc(dir.mV); +			mat.mult_matrix_vec(tc); +			mTransformedSunDir.set(tc.v); +		} + +		gGL.pushMatrix(); +		gGL.loadIdentity(); +		gGL.matrixMode(LLRender::MM_PROJECTION); +		gGL.pushMatrix(); +		gGL.loadIdentity(); + +		if (RenderDeferredSSAO || RenderShadowDetail > 0) +		{ +			mDeferredLight.bindTarget(); +			{ //paint shadow/SSAO light map (direct lighting lightmap) +				LLFastTimer ftm(FTM_SUN_SHADOW); +				bindDeferredShader(gDeferredSunProgram); +				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +				glClearColor(1,1,1,1); +				mDeferredLight.clear(GL_COLOR_BUFFER_BIT); +				glClearColor(0,0,0,0); + +				glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); + +				const U32 slice = 32; +				F32 offset[slice*3]; +				for (U32 i = 0; i < 4; i++) +				{ +					for (U32 j = 0; j < 8; j++) +					{ +						glh::vec3f v; +						v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); +						v.normalize(); +						inv_trans.mult_matrix_vec(v); +						v.normalize(); +						offset[(i*8+j)*3+0] = v.v[0]; +						offset[(i*8+j)*3+1] = v.v[2]; +						offset[(i*8+j)*3+2] = v.v[1]; +					} +				} + +				gDeferredSunProgram.uniform3fv("offset", slice, offset); +				gDeferredSunProgram.uniform2f("screenRes", mDeferredLight.getWidth(), mDeferredLight.getHeight()); +				 +				{ +					LLGLDisable blend(GL_BLEND); +					LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); +					stop_glerror(); +					mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); +					stop_glerror(); +				} +				 +				unbindDeferredShader(gDeferredSunProgram); +			} +			mDeferredLight.flush(); +		} +				 +		stop_glerror(); +		gGL.popMatrix(); +		stop_glerror(); +		gGL.matrixMode(LLRender::MM_MODELVIEW); +		stop_glerror(); +		gGL.popMatrix(); +		stop_glerror(); + +		target->bindTarget(); + +		//clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky +		glClearColor(0,0,0,0); +		target->clear(GL_COLOR_BUFFER_BIT); +		 +		if (RenderDeferredAtmospheric) +		{ //apply sunlight contribution  +			LLFastTimer ftm(FTM_ATMOSPHERICS); +			bindDeferredShader(gDeferredSoftenProgram);	 +			{ +				LLGLDepthTest depth(GL_FALSE); +				LLGLDisable blend(GL_BLEND); +				LLGLDisable test(GL_ALPHA_TEST); + +				//full screen blit +				gGL.pushMatrix(); +				gGL.loadIdentity(); +				gGL.matrixMode(LLRender::MM_PROJECTION); +				gGL.pushMatrix(); +				gGL.loadIdentity(); + +				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +				 +				mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + +				gGL.popMatrix(); +				gGL.matrixMode(LLRender::MM_MODELVIEW); +				gGL.popMatrix(); +			} + +			unbindDeferredShader(gDeferredSoftenProgram); +		} + +		{ //render non-deferred geometry (fullbright, alpha, etc) +			LLGLDisable blend(GL_BLEND); +			LLGLDisable stencil(GL_STENCIL_TEST); +			gGL.setSceneBlendType(LLRender::BT_ALPHA); + +			gPipeline.pushRenderTypeMask(); +			 +			gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, +										LLPipeline::RENDER_TYPE_CLOUDS, +										LLPipeline::RENDER_TYPE_WL_SKY, +										LLPipeline::END_RENDER_TYPES); +								 +			 +			renderGeomPostDeferred(*LLViewerCamera::getInstance(), false); +			gPipeline.popRenderTypeMask(); +		} + +		BOOL render_local = RenderLocalLights; +				 +		if (render_local) +		{ +			gGL.setSceneBlendType(LLRender::BT_ADD); +			std::list<LLVector4> fullscreen_lights; +			LLDrawable::drawable_list_t spot_lights; +			LLDrawable::drawable_list_t fullscreen_spot_lights; + +			for (U32 i = 0; i < 2; i++) +			{ +				mTargetShadowSpotLight[i] = NULL; +			} + +			std::list<LLVector4> light_colors; + +			LLVertexBuffer::unbind(); + +			{ +				bindDeferredShader(gDeferredLightProgram); +				 +				if (mCubeVB.isNull()) +				{ +					mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); +				} + +				mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +				 +				LLGLDepthTest depth(GL_TRUE, GL_FALSE); +				for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) +				{ +					LLDrawable* drawablep = *iter; +					 +					LLVOVolume* volume = drawablep->getVOVolume(); +					if (!volume) +					{ +						continue; +					} + +					if (volume->isAttachment()) +					{ +						if (!sRenderAttachedLights) +						{ +							continue; +						} +					} + + +					LLVector4a center; +					center.load3(drawablep->getPositionAgent().mV); +					const F32* c = center.getF32ptr(); +					F32 s = volume->getLightRadius()*1.5f; + +					LLColor3 col = volume->getLightColor(); +					 +					if (col.magVecSquared() < 0.001f) +					{ +						continue; +					} + +					if (s <= 0.001f) +					{ +						continue; +					} + +					LLVector4a sa; +					sa.splat(s); +					if (camera->AABBInFrustumNoFarClip(center, sa) == 0) +					{ +						continue; +					} + +					sVisibleLightCount++; +										 +					if (camera->getOrigin().mV[0] > c[0] + s + 0.2f || +						camera->getOrigin().mV[0] < c[0] - s - 0.2f || +						camera->getOrigin().mV[1] > c[1] + s + 0.2f || +						camera->getOrigin().mV[1] < c[1] - s - 0.2f || +						camera->getOrigin().mV[2] > c[2] + s + 0.2f || +						camera->getOrigin().mV[2] < c[2] - s - 0.2f) +					{ //draw box if camera is outside box +						if (render_local) +						{ +							if (volume->isLightSpotlight()) +							{ +								drawablep->getVOVolume()->updateSpotLightPriority(); +								spot_lights.push_back(drawablep); +								continue; +							} +							 +							/*col.mV[0] = powf(col.mV[0], 2.2f); +							col.mV[1] = powf(col.mV[1], 2.2f); +							col.mV[2] = powf(col.mV[2], 2.2f);*/ +							 +							LLFastTimer ftm(FTM_LOCAL_LIGHTS); +							gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); +							gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); +							gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); +							gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); +							gGL.syncMatrices(); +							 +							mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); +							stop_glerror(); +						} +					} +					else +					{	 +						if (volume->isLightSpotlight()) +						{ +							drawablep->getVOVolume()->updateSpotLightPriority(); +							fullscreen_spot_lights.push_back(drawablep); +							continue; +						} + +						glh::vec3f tc(c); +						mat.mult_matrix_vec(tc); +					 +						fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s)); +						light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f)); +					} +				} +				unbindDeferredShader(gDeferredLightProgram); +			} + +			if (!spot_lights.empty()) +			{ +				LLGLDepthTest depth(GL_TRUE, GL_FALSE); +				bindDeferredShader(gDeferredSpotLightProgram); + +				mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + +				gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); + +				for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter) +				{ +					LLFastTimer ftm(FTM_PROJECTORS); +					LLDrawable* drawablep = *iter; + +					LLVOVolume* volume = drawablep->getVOVolume(); + +					LLVector4a center; +					center.load3(drawablep->getPositionAgent().mV); +					const F32* c = center.getF32ptr(); +					F32 s = volume->getLightRadius()*1.5f; + +					sVisibleLightCount++; + +					setupSpotLight(gDeferredSpotLightProgram, drawablep); +					 +					LLColor3 col = volume->getLightColor(); +					/*col.mV[0] = powf(col.mV[0], 2.2f); +					col.mV[1] = powf(col.mV[1], 2.2f); +					col.mV[2] = powf(col.mV[2], 2.2f);*/ +					 +					gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); +					gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); +					gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); +					gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); +					gGL.syncMatrices(); +										 +					mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); +				} +				gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); +				unbindDeferredShader(gDeferredSpotLightProgram); +			} + +			//reset mDeferredVB to fullscreen triangle +			mDeferredVB->getVertexStrider(vert); +			vert[0].set(-1,1,0); +			vert[1].set(-1,-3,0); +			vert[2].set(3,1,0); + +			{ +				LLGLDepthTest depth(GL_FALSE); + +				//full screen blit +				gGL.pushMatrix(); +				gGL.loadIdentity(); +				gGL.matrixMode(LLRender::MM_PROJECTION); +				gGL.pushMatrix(); +				gGL.loadIdentity(); + +				U32 count = 0; + +				const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT; +				LLVector4 light[max_count]; +				LLVector4 col[max_count]; + +				F32 far_z = 0.f; + +				while (!fullscreen_lights.empty()) +				{ +					LLFastTimer ftm(FTM_FULLSCREEN_LIGHTS); +					light[count] = fullscreen_lights.front(); +					fullscreen_lights.pop_front(); +					col[count] = light_colors.front(); +					light_colors.pop_front(); +					 +					/*col[count].mV[0] = powf(col[count].mV[0], 2.2f); +					col[count].mV[1] = powf(col[count].mV[1], 2.2f); +					col[count].mV[2] = powf(col[count].mV[2], 2.2f);*/ +					 +					far_z = llmin(light[count].mV[2]-light[count].mV[3], far_z); +					//col[count] = pow4fsrgb(col[count], 2.2f); +					count++; +					if (count == max_count || fullscreen_lights.empty()) +					{ +						U32 idx = count-1; +						bindDeferredShader(gDeferredMultiLightProgram[idx]); +						gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count); +						gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light); +						gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col); +						gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z); +						far_z = 0.f; +						count = 0;  +						mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +						mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); +					} +				} +				 +				unbindDeferredShader(gDeferredMultiLightProgram[0]); + +				bindDeferredShader(gDeferredMultiSpotLightProgram); + +				gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); + +				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + +				for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter) +				{ +					LLFastTimer ftm(FTM_PROJECTORS); +					LLDrawable* drawablep = *iter; +					 +					LLVOVolume* volume = drawablep->getVOVolume(); + +					LLVector3 center = drawablep->getPositionAgent(); +					F32* c = center.mV; +					F32 s = volume->getLightRadius()*1.5f; + +					sVisibleLightCount++; + +					glh::vec3f tc(c); +					mat.mult_matrix_vec(tc); +					 +					setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); + +					LLColor3 col = volume->getLightColor(); +					 +					/*col.mV[0] = powf(col.mV[0], 2.2f); +					col.mV[1] = powf(col.mV[1], 2.2f); +					col.mV[2] = powf(col.mV[2], 2.2f);*/ +					 +					gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v); +					gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); +					gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); +					gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); +					mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); +				} + +				gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); +				unbindDeferredShader(gDeferredMultiSpotLightProgram); + +				gGL.popMatrix(); +				gGL.matrixMode(LLRender::MM_MODELVIEW); +				gGL.popMatrix(); +			} +		} + +		gGL.setColorMask(true, true); +	} + +	/*target->flush(); + +	//gamma correct lighting +	gGL.matrixMode(LLRender::MM_PROJECTION); +	gGL.pushMatrix(); +	gGL.loadIdentity(); +	gGL.matrixMode(LLRender::MM_MODELVIEW); +	gGL.pushMatrix(); +	gGL.loadIdentity(); + +	{ +		LLGLDepthTest depth(GL_FALSE, GL_FALSE); + +		LLVector2 tc1(0,0); +		LLVector2 tc2((F32) target->getWidth()*2, +				  (F32) target->getHeight()*2); + +		target->bindTarget(); +		// Apply gamma correction to the frame here. +		gDeferredPostGammaCorrectProgram.bind(); +		//mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +		S32 channel = 0; +		channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, target->getUsage()); +		if (channel > -1) +		{ +			target->bindTexture(0,channel); +			gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +		} +		 +		gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, target->getWidth(), target->getHeight()); +		 +		F32 gamma = 1.0/2.2; + +		gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, gamma); +		 +		gGL.begin(LLRender::TRIANGLE_STRIP); +		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +		gGL.vertex2f(-1,-1); +		 +		gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +		gGL.vertex2f(-1,3); +		 +		gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +		gGL.vertex2f(3,-1); +		 +		gGL.end(); +		 +		gGL.getTexUnit(channel)->unbind(target->getUsage()); +		gDeferredPostGammaCorrectProgram.unbind(); +		target->flush(); +	} + +	gGL.matrixMode(LLRender::MM_PROJECTION); +	gGL.popMatrix(); +	gGL.matrixMode(LLRender::MM_MODELVIEW); +	gGL.popMatrix();	 + +	target->bindTarget();*/ + +	{ //render non-deferred geometry (alpha, fullbright, glow) +		LLGLDisable blend(GL_BLEND); +		LLGLDisable stencil(GL_STENCIL_TEST); + +		pushRenderTypeMask(); +		andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, +						 LLPipeline::RENDER_TYPE_FULLBRIGHT, +						 LLPipeline::RENDER_TYPE_VOLUME, +						 LLPipeline::RENDER_TYPE_GLOW, +						 LLPipeline::RENDER_TYPE_BUMP, +						 LLPipeline::RENDER_TYPE_PASS_SIMPLE, +						 LLPipeline::RENDER_TYPE_PASS_ALPHA, +						 LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, +						 LLPipeline::RENDER_TYPE_PASS_BUMP, +						 LLPipeline::RENDER_TYPE_PASS_POST_BUMP, +						 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, +						 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, +						 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, +						 LLPipeline::RENDER_TYPE_PASS_GLOW, +						 LLPipeline::RENDER_TYPE_PASS_GRASS, +						 LLPipeline::RENDER_TYPE_PASS_SHINY, +						 LLPipeline::RENDER_TYPE_PASS_INVISIBLE, +						 LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, +						 LLPipeline::RENDER_TYPE_AVATAR, +						 LLPipeline::RENDER_TYPE_ALPHA_MASK, +						 LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, +						 END_RENDER_TYPES); +		 +		renderGeomPostDeferred(*LLViewerCamera::getInstance()); +		popRenderTypeMask(); +	} + +	//target->flush();				 +} +  void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)  {  	//construct frustum @@ -9137,6 +9689,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  			water_clip = 1;  		} +		bool materials_in_water = false; + +#if MATERIALS_IN_REFLECTIONS +		materials_in_water = gSavedSettings.getS32("RenderWaterMaterials"); +#endif +  		if (!LLViewerCamera::getInstance()->cameraUnderWater())  		{	//generate planar reflection map @@ -9145,7 +9703,9 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  			LLPipeline::sUseOcclusion = 0;  			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  			glClearColor(0,0,0,0); +  			mWaterRef.bindTarget(); +  			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0;  			gGL.setColorMask(true, true);  			mWaterRef.clear(); @@ -9194,11 +9754,27 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  					updateCull(camera, result);  					stateSort(camera, result); -					renderGeom(camera, TRUE); +					if (LLPipeline::sRenderDeferred && materials_in_water) +					{ +						mWaterRef.flush(); + +						gPipeline.grabReferences(result); +						gPipeline.mDeferredScreen.bindTarget(); +						gGL.setColorMask(true, true);						 +						glClearColor(0,0,0,0); +						gPipeline.mDeferredScreen.clear(); +						renderGeomDeferred(camera);						 +					} +					else +					{ +						renderGeom(camera, TRUE); +					}					 +						  					gPipeline.popRenderTypeMask(); -				} +				}					 +				gGL.setColorMask(true, false);  				gPipeline.pushRenderTypeMask();  				clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER, @@ -9236,10 +9812,24 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  					{  						gPipeline.grabReferences(ref_result);  						LLGLUserClipPlane clip_plane(plane, mat, projection); -						renderGeom(camera); + +						if (LLPipeline::sRenderDeferred && materials_in_water) +						{							 +							renderGeomDeferred(camera); +						} +						else +						{ +							renderGeom(camera); +						}  					}  				}	 +				if (LLPipeline::sRenderDeferred && materials_in_water) +				{ +					gPipeline.mDeferredScreen.flush(); +					renderDeferredLightingToRT(&mWaterRef); +				} +  				gPipeline.popRenderTypeMask();  			}	  			glCullFace(GL_BACK); @@ -9274,12 +9864,14 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  			LLViewerCamera::updateFrustumPlanes(camera);  			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +			  			LLColor4& col = LLDrawPoolWater::sWaterFogColor;  			glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);  			mWaterDis.bindTarget();  			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1; -			mWaterDis.getViewport(gGLViewport); +			mWaterDis.getViewport(gGLViewport); +  			if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate)  			{  				//clip out geometry on the same side of water as the camera @@ -9290,17 +9882,39 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  				static LLCullResult result;  				updateCull(camera, result, water_clip, &plane);  				stateSort(camera, result); - +			  				gGL.setColorMask(true, true);  				mWaterDis.clear(); -				gGL.setColorMask(true, false); +				 -				renderGeom(camera); +				gGL.setColorMask(true, false); +				 +				if (LLPipeline::sRenderDeferred && materials_in_water) +				{										 +					mWaterDis.flush(); +					gPipeline.mDeferredScreen.bindTarget(); +					gGL.setColorMask(true, true); +					glClearColor(0,0,0,0); +					gPipeline.mDeferredScreen.clear(); +					gPipeline.grabReferences(result); +					renderGeomDeferred(camera);					 +				} +				else +				{ +					renderGeom(camera);					 +				} +				 +				if (LLPipeline::sRenderDeferred && materials_in_water) +				{ +					gPipeline.mDeferredScreen.flush(); +					renderDeferredLightingToRT(&mWaterDis); +				}  			} -			LLPipeline::sUnderWaterRender = FALSE;  			mWaterDis.flush(); +			LLPipeline::sUnderWaterRender = FALSE; +			  		}  		last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate; @@ -10648,7 +11262,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  	S32 occlusion = sUseOcclusion;  	sUseOcclusion = 0; -	sReflectionRender = sRenderDeferred ? FALSE : TRUE; +	//sReflectionRender = sRenderDeferred ? FALSE : TRUE;  	sShadowRender = TRUE;  	sImpostorRender = TRUE; @@ -10745,25 +11359,27 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  			LLFastTimer t(FTM_IMPOSTOR_ALLOCATE);  			avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE); +#if DEFERRED_IMPOSTORS  			if (LLPipeline::sRenderDeferred)  			{  				addDeferredAttachments(avatar->mImpostor);  			} -		 +#endif +			  			gGL.getTexUnit(0)->bind(&avatar->mImpostor);  			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);  			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  		} -		else if(resX != avatar->mImpostor.getWidth() || -			resY != avatar->mImpostor.getHeight()) +		else if(resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight())  		{  			LLFastTimer t(FTM_IMPOSTOR_RESIZE);  			avatar->mImpostor.resize(resX,resY,GL_RGBA);  		} -		avatar->mImpostor.bindTarget(); +		avatar->mImpostor.bindTarget();		  	} +#if DEFERRED_IMPOSTORS  	if (LLPipeline::sRenderDeferred)  	{  		avatar->mImpostor.clear(); @@ -10771,20 +11387,24 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  		renderGeomPostDeferred(camera);  	}  	else -	{ +#endif +	{		  		LLGLEnable scissor(GL_SCISSOR_TEST); -		glScissor(0, 0, resX, resY); +		glScissor(0, 0, resX, resY);	  		avatar->mImpostor.clear();  		renderGeom(camera);  	}  	{ //create alpha mask based on depth buffer (grey out if muted)  		LLFastTimer t(FTM_IMPOSTOR_BACKGROUND); + +#if DEFERRED_IMPOSTORS  		if (LLPipeline::sRenderDeferred)  		{  			GLuint buff = GL_COLOR_ATTACHMENT0;  			glDrawBuffersARB(1, &buff);  		} +#endif  		LLGLDisable blend(GL_BLEND); @@ -11164,6 +11784,3 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id )  	}  } - - - diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 70dcf80407..36b293b998 100755 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -288,7 +288,8 @@ public:  	void unbindDeferredShader(LLGLSLShader& shader);  	void renderDeferredLighting(); -	 +	void renderDeferredLightingToRT(LLRenderTarget* target); +  	void generateWaterReflection(LLCamera& camera);  	void generateSunShadow(LLCamera& camera);  	void generateHighlight(LLCamera& camera); @@ -954,3 +955,4 @@ extern BOOL gDebugPipeline;  extern const LLMatrix4* gGLLastMatrix;  #endif + | 
