diff options
Diffstat (limited to 'indra/newview')
210 files changed, 11160 insertions, 3598 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 639982a305..3689c2856d 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -4,6 +4,7 @@ project(viewer)  include(00-Common)  include(Boost) +include(BuildVersion)  include(DBusGlib)  include(DirectX)  include(OpenSSL) @@ -173,6 +174,7 @@ set(viewer_SOURCE_FILES      lldrawpoolavatar.cpp      lldrawpoolbump.cpp      lldrawpoolground.cpp +    lldrawpoolmaterials.cpp      lldrawpoolsimple.cpp      lldrawpoolsky.cpp      lldrawpoolterrain.cpp @@ -357,6 +359,7 @@ set(viewer_SOURCE_FILES      llmaniptranslate.cpp      llmarketplacefunctions.cpp      llmarketplacenotifications.cpp +    llmaterialmgr.cpp      llmediactrl.cpp      llmediadataclient.cpp      llmenuoptionpathfindingrebakenavmesh.cpp @@ -755,6 +758,7 @@ set(viewer_HEADER_FILES      lldrawpoolalpha.h      lldrawpoolavatar.h      lldrawpoolbump.h +    lldrawpoolmaterials.h      lldrawpoolground.h      lldrawpoolsimple.h      lldrawpoolsky.h @@ -939,6 +943,7 @@ set(viewer_HEADER_FILES      llmaniptranslate.h      llmarketplacefunctions.h      llmarketplacenotifications.h +    llmaterialmgr.h      llmediactrl.h      llmediadataclient.h      llmenuoptionpathfindingrebakenavmesh.h @@ -1567,7 +1572,7 @@ endif (WINDOWS)  if (OPENAL)    set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_OPENAL") -endif (OPENAL) +endif (OPENAL)            if (FMODEX)    set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX") @@ -2141,6 +2146,40 @@ if (LL_TESTS)    )    set_source_files_properties( +    llviewerhelputil.cpp +    PROPERTIES +    LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}" +  ) + +  set_source_files_properties( +    llremoteparcelrequest.cpp +    PROPERTIES +    LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}" +  ) + +  set_source_files_properties( +    llworldmap.cpp +    llworldmipmap.cpp +    PROPERTIES +    LL_TEST_ADDITIONAL_SOURCE_FILES  +    tests/llviewertexture_stub.cpp +    #llviewertexturelist.cpp +    LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}" +  ) + +  set_source_files_properties( +    llmediadataclient.cpp +    PROPERTIES +    LL_TEST_ADDITIONAL_LIBRARIES "${LLPRIMITIVE_LIBRARIES}" +  ) + +  set_source_files_properties( +    llagentaccess.cpp +    PROPERTIES +    LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}" +  ) + +  set_source_files_properties(      lllogininstance.cpp      PROPERTIES      LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}" diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 65afb3b886..9575d51bad 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -3.5.4 +3.6.1 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 29427bbaa3..a255793017 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -41,7 +41,7 @@              <string>                  Time before automatically setting AFK (away from keyboard) mode (seconds, 0=never).                  Valid values are: 0, 120, 300, 600, 1800 -    </string> +</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> @@ -2873,6 +2873,17 @@        <key>Value</key>        <integer>0</integer>      </map> +  <key>DefaultBlankNormalTexture</key> +  <map> +    <key>Comment</key> +    <string>Texture used as 'Blank' in texture picker for normal maps. (UUID texture reference)</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>String</string> +    <key>Value</key> +    <string>5b53359e-59dd-d8a2-04c3-9e65134da47a</string> +  </map>  	<key>DefaultFemaleAvatar</key>  	<map>  	  <key>Comment</key> @@ -2895,7 +2906,28 @@  	  <key>Value</key>  	  <string>Male Shape & Outfit</string>  	</map> - +  <key>DefaultObjectNormalTexture</key> +  <map> +    <key>Comment</key> +    <string>Texture used as 'Default' in texture picker for normal map. (UUID texture reference)</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>String</string> +    <key>Value</key> +    <string>85f28839-7a1c-b4e3-d71d-967792970a7b</string> +  </map> +  <key>DefaultObjectSpecularTexture</key> +  <map> +    <key>Comment</key> +    <string>Texture used as 'Default' in texture picker for specular map. (UUID texture reference)</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>String</string> +    <key>Value</key> +    <string>87e0e8f7-8729-1ea8-cfc9-8915773009db</string> +  </map>      <key>DefaultObjectTexture</key>      <map>        <key>Comment</key> @@ -3347,17 +3379,6 @@        <key>Value</key>        <integer>1</integer>      </map> -    <key>EnableTextureAtlas</key> -    <map> -      <key>Comment</key> -      <string>Whether to use texture atlas or not</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>0</integer> -    </map>      <key>EnableUIHints</key>      <map>        <key>Comment</key> @@ -8472,7 +8493,7 @@    <key>RenderSpotLightsInNondeferred</key>    <map>      <key>Comment</key> -    <string>Whether to support projectors as spotlights when Lighting and Shadows is disabled</string> +    <string>Whether to support projectors as spotlights when Advanced Lighting Model is disabled</string>      <key>Persist</key>      <integer>1</integer>      <key>Type</key> @@ -8613,7 +8634,7 @@      <key>Type</key>      <string>U32</string>      <key>Value</key> -    <real>512</real> +    <real>1024</real>    </map>    <key>RenderSpecularResY</key> @@ -8625,7 +8646,7 @@      <key>Type</key>      <string>U32</string>      <key>Value</key> -    <real>128</real> +    <real>256</real>    </map>    <key>RenderSpecularExponent</key> @@ -8643,7 +8664,7 @@    <key>RenderDeferred</key>    <map>      <key>Comment</key> -    <string>Use deferred rendering pipeline.</string> +    <string>Use deferred rendering pipeline (Advanced Lighting Model).</string>      <key>Persist</key>      <integer>1</integer>      <key>Type</key> @@ -8831,7 +8852,7 @@      <key>RenderAutoMaskAlphaNonDeferred</key>      <map>        <key>Comment</key> -      <string>Use alpha masks where appropriate, in the non-deferred (non-'Lighting and Shadows') graphics mode</string> +      <string>Use alpha masks where appropriate when not using the Advanced Lighting Model</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> @@ -8842,7 +8863,7 @@      <key>RenderAutoMaskAlphaDeferred</key>      <map>        <key>Comment</key> -      <string>Use alpha masks where appropriate, in the deferred ('Lighting and Shadows') graphics mode</string> +      <string>Use alpha masks where appropriate in the Advanced Lighting Model</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> @@ -12526,17 +12547,6 @@        <key>Value</key>        <integer>3</integer>      </map> -    <key>UpdaterWillingToTest</key> -    <map> -      <key>Comment</key> -      <string>Allow upgrades to release candidate viewers with new features and fixes.</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>1</integer> -    </map>      <key>UpdaterServiceCheckPeriod</key>      <map>        <key>Comment</key> @@ -12931,7 +12941,6 @@        <key>Type</key>        <string>LLSD</string>        <key>Value</key> -      <string/>      </map>      <key>VFSOldSize</key>      <map> @@ -14622,5 +14631,16 @@      <key>Value</key>      <integer>7000</integer>    </map> +  <key>DisablePrecacheDelayAfterTeleporting</key> +  <map> +    <key>Comment</key> +    <string>Disables the artificial delay in the viewer that precaches some incoming assets</string> +    <key>Persist</key> +    <integer>0</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>0</integer> +  </map>  </map>  </llsd> diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index dd87ddb330..77a53a71aa 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -25,17 +25,33 @@  #extension GL_ARB_texture_rectangle : enable +#define INDEXED 1 +#define NON_INDEXED 2 +#define NON_INDEXED_NO_COLOR 3 +  #ifdef DEFINE_GL_FRAGCOLOR  out vec4 frag_color;  #else  #define frag_color gl_FragColor  #endif -uniform sampler2DRect depthMap; +#if HAS_SHADOW +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; -vec4 diffuseLookup(vec2 texcoord); +uniform vec2 shadow_res; -uniform vec2 screen_res; +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform float shadow_bias; + +#endif + +#ifdef USE_DIFFUSE_TEX +uniform sampler2D diffuseMap; +#endif  vec3 atmosLighting(vec3 light);  vec3 scaleSoftClip(vec3 light); @@ -45,11 +61,77 @@ VARYING vec3 vary_directional;  VARYING vec3 vary_fragcoord;  VARYING vec3 vary_position;  VARYING vec3 vary_pointlight_col; +VARYING vec2 vary_texcoord0; +VARYING vec3 vary_norm; +#ifdef USE_VERTEX_COLOR  VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; +#endif + +uniform vec4 light_position[8]; +uniform vec3 light_direction[8]; +uniform vec3 light_attenuation[8];  +uniform vec3 light_diffuse[8]; + +uniform vec2 screen_res; + +vec3 calcDirectionalLight(vec3 n, vec3 l) +{ +	float a = max(dot(n,l),0.0); +	return vec3(a,a,a); +} + +vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +{ +	//get light vector +	vec3 lv = lp.xyz-v; +	 +	//get distance +	float d = dot(lv,lv); +	 +	float da = 0.0; + +	if (d > 0.0 && la > 0.0 && fa > 0.0) +	{ +		//normalize light vector +		lv = normalize(lv); +	 +		//distance attenuation +		float dist2 = d/la; +		da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); +		da = pow(da, 2.2) * 2.2; + +		// spotlight coefficient. +		float spot = max(dot(-ln, lv), is_pointlight); +		da *= spot*spot; // GL_SPOT_EXPONENT=2 + +		//angular attenuation +		da *= max(dot(n, lv), 0.0);		 +	} + +	return vec3(da,da,da);	 +} + +#if HAS_SHADOW +float pcfShadow(sampler2DShadow shadowMap, vec4 stc) +{ +	stc.xyz /= stc.w; +	stc.z += shadow_bias; +		 +	stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here +	 +	float cs = shadow2D(shadowMap, stc.xyz).x; +	float shadow = cs; +	 +    shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; +    shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; +    shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; +    shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; +                        +    return shadow*0.2; +} +#endif -uniform mat4 inv_proj;  void main()   { @@ -58,16 +140,119 @@ void main()  	vec4 pos = vec4(vary_position, 1.0); -	vec4 diff= diffuseLookup(vary_texcoord0.xy); -	vec4 col = vec4(vary_ambient + vary_directional.rgb, vertex_color.a); +#if HAS_SHADOW +	float shadow = 0.0; +	vec4 spos = pos; +		 +	if (spos.z > -shadow_clip.w) +	{	 +		vec4 lpos; +		 +		vec4 near_split = shadow_clip*-0.75; +		vec4 far_split = shadow_clip*-1.25; +		vec4 transition_domain = near_split-far_split; +		float weight = 0.0; + +		if (spos.z < near_split.z) +		{ +			lpos = shadow_matrix[3]*spos; +			 +			float w = 1.0; +			w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; +			shadow += pcfShadow(shadowMap3, lpos)*w; +			weight += w; +			shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); +		} + +		if (spos.z < near_split.y && spos.z > far_split.z) +		{ +			lpos = shadow_matrix[2]*spos; +			 +			float w = 1.0; +			w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; +			w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; +			shadow += pcfShadow(shadowMap2, lpos)*w; +			weight += w; +		} + +		if (spos.z < near_split.x && spos.z > far_split.y) +		{ +			lpos = shadow_matrix[1]*spos; +			 +			float w = 1.0; +			w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; +			w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; +			shadow += pcfShadow(shadowMap1, lpos)*w; +			weight += w; +		} + +		if (spos.z > far_split.x) +		{ +			lpos = shadow_matrix[0]*spos; +							 +			float w = 1.0; +			w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; +				 +			shadow += pcfShadow(shadowMap0, lpos)*w; +			weight += w; +		} +		 + +		shadow /= weight; +	} +	else +	{ +		shadow = 1.0; +	} +#endif + +#ifdef USE_INDEXED_TEX +	vec4 diff = diffuseLookup(vary_texcoord0.xy); +#else +	vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy); +#endif + +	diff.rgb = pow(diff.rgb, vec3(2.2f, 2.2f, 2.2f)); + +#ifdef USE_VERTEX_COLOR +	float vertex_color_alpha = vertex_color.a;	 +#else +	float vertex_color_alpha = 1.0; +#endif +	 +	vec3 normal = vary_norm;  +	 +	vec3 l = light_position[0].xyz; +	vec3 dlight = calcDirectionalLight(normal, l) * 2.6; +	dlight = dlight * vary_directional.rgb * vary_pointlight_col; + +#if HAS_SHADOW +	vec4 col = vec4(vary_ambient + dlight * shadow, vertex_color_alpha); +#else +	vec4 col = vec4(vary_ambient + dlight, vertex_color_alpha); +#endif +  	vec4 color = diff * col;  	color.rgb = atmosLighting(color.rgb);  	color.rgb = scaleSoftClip(color.rgb); +	col = vec4(0,0,0,0); + +   #define LIGHT_LOOP(i) col.rgb += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, normal, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); + +	LIGHT_LOOP(1) +	LIGHT_LOOP(2) +	LIGHT_LOOP(3) +	LIGHT_LOOP(4) +	LIGHT_LOOP(5) +	LIGHT_LOOP(6) +	LIGHT_LOOP(7) + +	color.rgb += diff.rgb * vary_pointlight_col * col.rgb; -	color.rgb += diff.rgb * vary_pointlight_col.rgb; +	color.rgb = pow(color.rgb, vec3(1.0/2.2));  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl index beb3290187..2ce44d599f 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl @@ -47,9 +47,51 @@ VARYING vec3 vary_position;  VARYING vec3 vary_pointlight_col;  VARYING vec2 vary_texcoord0;  VARYING vec4 vertex_color; +VARYING vec3 vary_norm;  uniform mat4 inv_proj; +uniform vec4 light_position[8]; +uniform vec3 light_direction[8]; +uniform vec3 light_attenuation[8];  +uniform vec3 light_diffuse[8]; + +vec3 calcDirectionalLight(vec3 n, vec3 l) +{ +        float a = pow(max(dot(n,l),0.0), 0.7); +        return vec3(a,a,a); +} + +vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +{ +	//get light vector +	vec3 lv = lp.xyz-v; +	 +	//get distance +	float d = dot(lv,lv); +	 +	float da = 0.0; + +	if (d > 0.0 && la > 0.0 && fa > 0.0) +	{ +		//normalize light vector +		lv = normalize(lv); +	 +		//distance attenuation +		float dist2 = d/la; +		da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + +		// spotlight coefficient. +		float spot = max(dot(-ln, lv), is_pointlight); +		da *= spot*spot; // GL_SPOT_EXPONENT=2 + +		//angular attenuation +		da *= max(pow(dot(n, lv), 0.7), 0.0);		 +	} + +	return vec3(da,da,da);	 +} +  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).a; @@ -72,14 +114,33 @@ void main()  	vec4 diff= texture2D(diffuseMap,vary_texcoord0.xy); -	vec4 col = vec4(vary_ambient + vary_directional.rgb, vertex_color.a); +	vec3 n = vary_norm; +	vec3 l = light_position[0].xyz; +	vec3 dlight = calcDirectionalLight(n, l); +	dlight = dlight * vary_directional.rgb * vary_pointlight_col; + +	vec4 col = vec4(vary_ambient + dlight, vertex_color.a);  	vec4 color = diff * col;  	color.rgb = atmosLighting(color.rgb);  	color.rgb = scaleSoftClip(color.rgb); +	vec3 light_col = vec3(0,0,0); + +  #define LIGHT_LOOP(i) \ +	light_col += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, vary_norm, light_position[i], light_direction[i], light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); + +	LIGHT_LOOP(1) +	LIGHT_LOOP(2) +	LIGHT_LOOP(3) +	LIGHT_LOOP(4) +	LIGHT_LOOP(5) +	LIGHT_LOOP(6) +	LIGHT_LOOP(7) + +	color.rgb += diff.rgb * vary_pointlight_col * light_col; -	color.rgb += diff.rgb * vary_pointlight_col.rgb; +	color.rgb = pow(color.rgb, vec3(1.0/2.2));  	frag_color = color;  	//frag_color = vec4(1,0,1,1); diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl index 5a0e8ff684..5f93986f1d 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl @@ -46,6 +46,7 @@ VARYING vec3 vary_pointlight_col;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; +VARYING vec3 vary_norm;  uniform float near_clip; @@ -104,7 +105,7 @@ void main()  	norm = position.xyz + normal.xyz;  	norm = normalize(( trans*vec4(norm, 1.0) ).xyz-pos.xyz); -	 +	vary_norm = norm;  	vec4 frag_pos = projection_matrix * pos;  	gl_Position = frag_pos; @@ -112,27 +113,18 @@ void main()  	calcAtmospherics(pos.xyz); +	//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));  	vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a); - -	// Collect normal lights -	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z); -	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z); -	col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z); -	col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z); -	col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z); -	col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z); - -	vary_pointlight_col = col.rgb*diffuse_color.rgb; - +	vary_pointlight_col = diffuse_color.rgb;  	col.rgb = vec3(0,0,0);  	// Add windlight lights  	col.rgb = atmosAmbient(vec3(0.));  	vary_ambient = col.rgb*diffuse_color.rgb; -	vary_directional = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a))); +	vary_directional.rgb = atmosAffectDirectionalLight(1); -	col.rgb = min(col.rgb*diffuse_color.rgb, 1.0); +	col.rgb = col.rgb*diffuse_color.rgb;  	vertex_color = col; diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index cf38a2f4f7..247ee0a34f 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -23,21 +23,42 @@   * $/LicenseInfo$   */ +#define INDEXED 1 +#define NON_INDEXED 2 +#define NON_INDEXED_NO_COLOR 3 +  uniform mat3 normal_matrix;  uniform mat4 texture_matrix0; +uniform mat4 projection_matrix;  uniform mat4 modelview_matrix;  uniform mat4 modelview_projection_matrix;  ATTRIBUTE vec3 position; + +#ifdef USE_INDEXED_TEX  void passTextureIndex(); +#endif +  ATTRIBUTE vec3 normal; + +#ifdef USE_VERTEX_COLOR  ATTRIBUTE vec4 diffuse_color; +#endif +  ATTRIBUTE vec2 texcoord0; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +#else +#ifdef IS_AVATAR_SKIN +mat4 getSkinnedTransform(); +#endif +#endif +  vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);  void calcAtmospherics(vec3 inPositionEye); -float calcDirectionalLight(vec3 n, vec3 l); +vec3 calcDirectionalLight(vec3 n, vec3 l);  vec3 atmosAmbient(vec3 light);  vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -50,26 +71,30 @@ VARYING vec3 vary_fragcoord;  VARYING vec3 vary_position;  VARYING vec3 vary_pointlight_col; +#ifdef USE_VERTEX_COLOR  VARYING vec4 vertex_color; +#endif +  VARYING vec2 vary_texcoord0; +VARYING vec3 vary_norm;  uniform float near_clip; -uniform float shadow_offset; -uniform float shadow_bias;  uniform vec4 light_position[8];  uniform vec3 light_direction[8];  uniform vec3 light_attenuation[8];   uniform vec3 light_diffuse[8]; -float calcDirectionalLight(vec3 n, vec3 l) +uniform vec3 sun_dir; + +vec3 calcDirectionalLight(vec3 n, vec3 l)  {          float a = max(dot(n,l),0.0); -        return a; +        return vec3(a,a,a);  } -float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)  {  	//get light vector  	vec3 lv = lp.xyz-v; @@ -96,53 +121,110 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa  		da *= max(dot(n, lv), 0.0);		  	} -	return da;	 +	return vec3(da,da,da);	  }  void main()  { +	vec4 pos; +	vec3 norm; +	  	//transform vertex +#ifdef HAS_SKIN +	mat4 trans = getObjectSkinnedTransform(); +	trans = modelview_matrix * trans; +	 +	pos = trans * vec4(position.xyz, 1.0); +	 +	norm = position.xyz + normal.xyz; +	norm = normalize((trans * vec4(norm, 1.0)).xyz - pos.xyz); +	vec4 frag_pos = projection_matrix * pos; +	gl_Position = frag_pos; +#else + +#ifdef IS_AVATAR_SKIN +	mat4 trans = getSkinnedTransform(); +	vec4 pos_in = vec4(position.xyz, 1.0); +	pos.x = dot(trans[0], pos_in); +	pos.y = dot(trans[1], pos_in); +	pos.z = dot(trans[2], pos_in); +	pos.w = 1.0; +	 +	norm.x = dot(trans[0].xyz, normal); +	norm.y = dot(trans[1].xyz, normal); +	norm.z = dot(trans[2].xyz, normal); +	norm = normalize(norm); +	 +	vec4 frag_pos = projection_matrix * pos; +	gl_Position = frag_pos; +#else +	norm = normalize(normal_matrix * normal);  	vec4 vert = vec4(position.xyz, 1.0); -	passTextureIndex(); -	vec4 pos = (modelview_matrix * vert); +	pos = (modelview_matrix * vert);  	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); +#endif +#endif + +#ifdef USE_INDEXED_TEX +	passTextureIndex();  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; +#else +	vary_texcoord0 = texcoord0; +#endif -	vec3 norm = normalize(normal_matrix * normal); -	 -	float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz)); -	vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset; -		 +	vary_norm = norm; +	vary_position = pos.xyz; +  	calcAtmospherics(pos.xyz); +#ifndef USE_VERTEX_COLOR +	vec4 diffuse_color = vec4(1,1,1,1); +#endif  	//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));  	vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a); +	 +	vec3 diff = pow(diffuse_color.rgb, vec3(2.2)); + +	 + +	vary_pointlight_col = diff; -	// Collect normal lights -	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z); -	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z); -	col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z); -	col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z); -	col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z); -	col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z); -	vary_pointlight_col = col.rgb*diffuse_color.rgb;  	col.rgb = vec3(0,0,0);  	// Add windlight lights -	col.rgb = atmosAmbient(vec3(0.)); +	col.rgb = atmosAmbient(col.rgb); -	vary_ambient = col.rgb*diffuse_color.rgb; -	vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a))); +	float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); +	ambient *= 0.5; +	ambient *= ambient; +	ambient = (1.0-ambient); + +	col.rgb *= ambient; + +	vary_ambient = col.rgb*diff.rgb; + +	vary_directional.rgb = atmosAffectDirectionalLight(1.0f); -	col.rgb = col.rgb*diffuse_color.rgb; +	col.rgb = col.rgb*diff.rgb; +#ifdef USE_VERTEX_COLOR  	vertex_color = col; - -	 +#endif +#ifdef HAS_SKIN +	vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip); +#else + +#ifdef IS_AVATAR_SKIN +	vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); +#else  	pos = modelview_projection_matrix * vert;  	vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); +#endif +#endif +  } + diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl index 81961d7746..3f90600ace 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl @@ -39,7 +39,12 @@ void main()  	mat = modelview_matrix * mat;  	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; +  	vec4 p = projection_matrix * vec4(pos, 1.0); +#if !DEPTH_CLAMP  	p.z = max(p.z, -p.w+0.01);  	gl_Position = p; +#else +	gl_Position = p; +#endif  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl index 5f395801e5..c8ddefac26 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl @@ -47,6 +47,7 @@ VARYING vec3 vary_directional;  VARYING vec3 vary_fragcoord;  VARYING vec3 vary_pointlight_col;  VARYING vec2 vary_texcoord0; +VARYING vec3 vary_norm;  uniform float near_clip; @@ -112,6 +113,7 @@ void main()  	norm.y = dot(trans[1].xyz, normal);  	norm.z = dot(trans[2].xyz, normal);  	norm = normalize(norm); +	vary_norm = norm;  	vec4 frag_pos = projection_matrix * pos;  	gl_Position = frag_pos; diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index bfd9b9b3eb..bcccbf77d2 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -34,6 +34,12 @@ uniform sampler2D diffuseMap;  VARYING vec3 vary_normal;  VARYING vec2 vary_texcoord0; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} +  void main()   {  	vec4 diff = texture2D(diffuseMap, vary_texcoord0.xy); @@ -46,6 +52,6 @@ void main()  	frag_data[0] = vec4(diff.rgb, 0.0);  	frag_data[1] = vec4(0,0,0,0);  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); +	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl index 3686f2f647..b809b73973 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl @@ -31,12 +31,16 @@ out vec4 frag_color;  uniform sampler2D diffuseMap; +#if !DEPTH_CLAMP  VARYING vec4 post_pos; +#endif  void main()   {  	frag_color = vec4(1,1,1,1); +#if !DEPTH_CLAMP  	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); +#endif  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl index 23feb09d72..bde1ad4e9f 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl @@ -31,7 +31,9 @@ ATTRIBUTE vec3 position;  ATTRIBUTE vec3 normal;  ATTRIBUTE vec2 texcoord0; +#if !DEPTH_CLAMP  VARYING vec4 post_pos; +#endif  void main()  { @@ -51,9 +53,13 @@ void main()  	norm = normalize(norm);  	pos = projection_matrix * pos; +#if !DEPTH_CLAMP  	post_pos = pos;  	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +#else +	gl_Position = pos; +#endif  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index f400eb7a5b..eebeb91bf8 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -64,11 +64,46 @@ vec4 getPosition(vec2 pos_screen)  	return pos;  } +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif +  void main()   {      vec2 tc = vary_fragcoord.xy;  	vec3 norm = texture2DRect(normalMap, tc).xyz; -	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +	norm = decode_normal(norm.xy); // unpack norm +  	vec3 pos = getPosition(tc).xyz;  	vec4 ccol = texture2DRect(lightMap, tc).rgba; diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl index 23c4ea2fff..595c11fae2 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -39,6 +39,12 @@ VARYING vec3 vary_mat2;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} +  void main()   {  	vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb; @@ -52,5 +58,5 @@ void main()  	frag_data[1] = vertex_color.aaaa; // spec  	//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested  	vec3 nvn = normalize(tnorm); -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); +	frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl index 8ba75010a2..10144f3e16 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl @@ -30,7 +30,7 @@ ATTRIBUTE vec3 position;  ATTRIBUTE vec4 diffuse_color;  ATTRIBUTE vec3 normal;  ATTRIBUTE vec2 texcoord0; -ATTRIBUTE vec3 binormal; +ATTRIBUTE vec4 tangent;  VARYING vec3 vary_mat0;  VARYING vec3 vary_mat1; @@ -52,8 +52,8 @@ void main()  	vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz); -	vec3 b = normalize((mat * vec4(binormal.xyz+position.xyz, 1.0)).xyz-pos.xyz); -	vec3 t = cross(b, n); +	vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz); +	vec3 b = cross(n, t) * tangent.w;  	vary_mat0 = vec3(t.x, b.x, n.x);  	vary_mat1 = vec3(t.y, b.y, n.y); diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl index c8d38bb8f7..9f9749394e 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl @@ -31,7 +31,7 @@ ATTRIBUTE vec3 position;  ATTRIBUTE vec4 diffuse_color;  ATTRIBUTE vec3 normal;  ATTRIBUTE vec2 texcoord0; -ATTRIBUTE vec3 binormal; +ATTRIBUTE vec4 tangent;  VARYING vec3 vary_mat0;  VARYING vec3 vary_mat1; @@ -46,8 +46,8 @@ void main()  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;  	vec3 n = normalize(normal_matrix * normal); -	vec3 b = normalize(normal_matrix * binormal); -	vec3 t = cross(b, n); +	vec3 t = normalize(normal_matrix * tangent.xyz); +	vec3 b = cross(n, t) * tangent.w;  	vary_mat0 = vec3(t.x, b.x, n.x);  	vary_mat1 = vec3(t.y, b.y, n.y); diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl index c1fa9e4aac..7930b5d18b 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl @@ -37,6 +37,12 @@ VARYING vec3 vary_normal;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} +  void main()   {  	vec4 col = texture2D(diffuseMap, vary_texcoord0.xy) * vertex_color; @@ -49,6 +55,6 @@ void main()  	frag_data[0] = vec4(col.rgb, 0.0);  	frag_data[1] = vec4(0,0,0,0); // spec  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); +	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl index 4c68123fac..59d109b886 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl @@ -36,6 +36,12 @@ uniform float minimum_alpha;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} +  void main()   {  	vec4 col = diffuseLookup(vary_texcoord0.xy) * vertex_color; @@ -48,5 +54,5 @@ void main()  	frag_data[0] = vec4(col.rgb, 0.0);  	frag_data[1] = vec4(0,0,0,0);  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); +	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl index ad65c7d330..37d70a2412 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl @@ -37,6 +37,12 @@ uniform sampler2D diffuseMap;  VARYING vec3 vary_normal;  VARYING vec2 vary_texcoord0; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} +  void main()   {  	vec4 col = texture2D(diffuseMap, vary_texcoord0.xy); @@ -49,6 +55,6 @@ void main()  	frag_data[0] = vec4(col.rgb, 0.0);  	frag_data[1] = vec4(0,0,0,0); // spec  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); +	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index 86390bdd83..6befb1bd8b 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -35,6 +35,12 @@ VARYING vec3 vary_normal;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} +  void main()   {  	vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb; @@ -42,6 +48,6 @@ void main()  	frag_data[1] = vertex_color.aaaa; // spec  	//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); +	frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl index 788b966af8..a2c3ec3355 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl @@ -33,13 +33,20 @@ VARYING vec3 vary_normal;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +  void main()   {  	vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;  	frag_data[0] = vec4(col, 0.0);  	frag_data[1] = vertex_color.aaaa; // spec -	//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested +	frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); +	frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 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 76d29b1df7..3c026796c8 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl @@ -47,6 +47,6 @@ void main()  	passTextureIndex();  	vary_normal = normalize(normal_matrix * normal); - +	  	vertex_color = diffuse_color;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl index 6aa4d7b4ed..ed02c4a481 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl @@ -42,7 +42,7 @@ void main()  	float shadow = 1.0;  	vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color; -	 +	color.rgb = pow(color.rgb, vec3(2.2));  	color.rgb = fullbrightAtmosTransport(color.rgb);  	color.rgb = fullbrightScaleSoftClip(color.rgb); diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index 36433a5827..dc1dead656 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -31,6 +31,10 @@ out vec4 frag_color;  #define frag_color gl_FragColor  #endif +#if !HAS_DIFFUSE_LOOKUP +uniform sampler2D diffuseMap; +#endif +  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; @@ -40,14 +44,20 @@ vec3 fullbrightScaleSoftClip(vec3 light);  void main()   { -	float shadow = 1.0; - +#if HAS_DIFFUSE_LOOKUP  	vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color; +#else +	vec4 color = texture2D(diffuseMap, vary_texcoord0.xy)*vertex_color; +#endif + +	color.rgb = pow(color.rgb,vec3(2.2f,2.2f,2.2f));  	color.rgb = fullbrightAtmosTransport(color.rgb);  	color.rgb = fullbrightScaleSoftClip(color.rgb); +	color.rgb = pow(color.rgb, vec3(1.0/2.2)); +  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl new file mode 100644 index 0000000000..b0db9876d3 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl @@ -0,0 +1,72 @@ +/**  + * @file fullbrightShinyF.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_color; +#else +#define frag_color gl_FragColor +#endif + +#ifndef diffuseLookup +uniform sampler2D diffuseMap; +#endif + +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; +VARYING vec3 vary_texcoord1; + +uniform samplerCube environmentMap; + +vec3 fullbrightShinyAtmosTransport(vec3 light); +vec3 fullbrightScaleSoftClip(vec3 light); + +void main() +{ +#if HAS_DIFFUSE_LOOKUP +	vec4 color = diffuseLookup(vary_texcoord0.xy); +#else +	vec4 color = texture2D(diffuseMap, vary_texcoord0.xy); +#endif + +	 +	color.rgb *= vertex_color.rgb; +	 +	vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;	 +	color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a); + +	color.rgb = pow(color.rgb,vec3(2.2f,2.2f,2.2f)); +	 +	color.rgb = fullbrightShinyAtmosTransport(color.rgb); +	color.rgb = fullbrightScaleSoftClip(color.rgb); + +	color.a = 1.0; + +	color.rgb = pow(color.rgb, vec3(1.0/2.2)); + +	frag_color = color; +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl new file mode 100644 index 0000000000..34bd8d445a --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl @@ -0,0 +1,67 @@ +/** + * @file fullbrightShinyV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat3 normal_matrix; +uniform mat4 texture_matrix0; +uniform mat4 texture_matrix1; +uniform mat4 modelview_matrix; +uniform mat4 modelview_projection_matrix; + + +void calcAtmospherics(vec3 inPositionEye); + +uniform vec4 origin; + + + +ATTRIBUTE vec3 position; +void passTextureIndex(); +ATTRIBUTE vec3 normal; +ATTRIBUTE vec4 diffuse_color; +ATTRIBUTE vec2 texcoord0; + +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; +VARYING vec3 vary_texcoord1; + + +void main() +{ +	//transform vertex +	vec4 vert = vec4(position.xyz,1.0); +	passTextureIndex(); +	vec4 pos = (modelview_matrix * vert); +	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); +	 +	vec3 norm = normalize(normal_matrix * normal); +	vec3 ref = reflect(pos.xyz, -norm); + +	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; +	vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz; + +	calcAtmospherics(pos.xyz); + +	vertex_color = diffuse_color; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl index 2e6982d101..3f09a15375 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl @@ -57,8 +57,6 @@ void main()  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;  	calcAtmospherics(pos.xyz); -	 -	vertex_color = diffuse_color; -	 +	vertex_color = diffuse_color;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl new file mode 100644 index 0000000000..de2f74b681 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -0,0 +1,695 @@ +/**  + * @file materialF.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$ + */ +  +#define DIFFUSE_ALPHA_MODE_IGNORE	0 +#define DIFFUSE_ALPHA_MODE_BLEND	1 +#define DIFFUSE_ALPHA_MODE_MASK		2 +#define DIFFUSE_ALPHA_MODE_EMISSIVE 3 + +uniform float emissive_brightness; + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +#if HAS_SUN_SHADOW + +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; + +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform vec2 shadow_res; +uniform float shadow_bias; + +float pcfShadow(sampler2DShadow shadowMap, vec4 stc) +{ +	stc.xyz /= stc.w; +	stc.z += shadow_bias; +		 +	stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here +	 +	float cs = shadow2D(shadowMap, stc.xyz).x; +	float shadow = cs; +	 +    shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; +    shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; +    shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; +    shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; +                        +    return shadow*0.2; +} + +#endif + +uniform samplerCube environmentMap; +uniform sampler2D	  lightFunc; + +// Inputs +uniform vec4 morphFactor; +uniform vec3 camPosLocal; +//uniform vec4 camPosWorld; +uniform vec4 gamma; +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +uniform vec4 blue_density; +uniform float haze_horizon; +uniform float haze_density; +uniform float cloud_shadow; +uniform float density_multiplier; +uniform float distance_multiplier; +uniform float max_y; +uniform vec4 glow; +uniform float scene_light_strength; +uniform mat3 env_mat; +uniform mat3 ssao_effect_mat; + +uniform vec3 sun_dir; +VARYING vec2 vary_fragcoord; + +VARYING vec3 vary_position; + +vec3 vary_PositionEye; + +vec3 vary_SunlitColor; +vec3 vary_AmblitColor; +vec3 vary_AdditiveColor; +vec3 vary_AtmosAttenuation; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +uniform vec4 light_position[8]; +uniform vec3 light_direction[8]; +uniform vec3 light_attenuation[8];  +uniform vec3 light_diffuse[8]; + +vec3 calcDirectionalLight(vec3 n, vec3 l) +{ +	float a = max(dot(n,l),0.0); +	return vec3(a,a,a); +} + + +vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare) +{ +	//get light vector +	vec3 lv = lp.xyz-v; +	 +	//get distance +	float d = dot(lv,lv); +	 +	float da = 1.0; + +	vec3 col = vec3(0,0,0); + +	if (d > 0.0 && la > 0.0 && fa > 0.0) +	{ +		//normalize light vector +		lv = normalize(lv); +	 +		//distance attenuation +		float dist2 = d/la; +		float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + +		// spotlight coefficient. +		float spot = max(dot(-ln, lv), is_pointlight); +		da *= spot*spot; // GL_SPOT_EXPONENT=2 + +		//angular attenuation +		da *= max(dot(n, lv), 0.0);		 +		 +		float lit = max(da * dist_atten, 0.0); + +		col = light_col*lit*diffuse; + +		if (spec.a > 0.0) +		{ +			//vec3 ref = dot(pos+lv, norm); +			vec3 h = normalize(lv+npos); +			float nh = dot(n, h); +			float nv = dot(n, npos); +			float vh = dot(npos, h); +			float sa = nh; +			float fres = pow(1 - dot(h, npos), 5)*0.4+0.5; + +			float gtdenom = 2 * nh; +			float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); +								 +			if (nh > 0.0) +			{ +				float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); +				vec3 speccol = lit*scol*light_col.rgb*spec.rgb; +				col += speccol; + +				float cur_glare = max(speccol.r, speccol.g); +				cur_glare = max(cur_glare, speccol.b); +				glare = max(glare, speccol.r); +				glare += max(cur_glare, 0.0); +				//col += spec.rgb; +			} +		} +	} + +	return max(col, vec3(0.0,0.0,0.0));	 + +} + +vec4 getPosition_d(vec2 pos_screen, float depth) +{ +	vec2 sc = pos_screen.xy*2.0; +	sc /= screen_res; +	sc -= vec2(1.0,1.0); +	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); +	vec4 pos = inv_proj * ndc; +	pos /= pos.w; +	pos.w = 1.0; +	return pos; +} + +vec3 getPositionEye() +{ +	return vary_PositionEye; +} +vec3 getSunlitColor() +{ +	return vary_SunlitColor; +} +vec3 getAmblitColor() +{ +	return vary_AmblitColor; +} +vec3 getAdditiveColor() +{ +	return vary_AdditiveColor; +} +vec3 getAtmosAttenuation() +{ +	return vary_AtmosAttenuation; +} + +void setPositionEye(vec3 v) +{ +	vary_PositionEye = v; +} + +void setSunlitColor(vec3 v) +{ +	vary_SunlitColor = v; +} + +void setAmblitColor(vec3 v) +{ +	vary_AmblitColor = v; +} + +void setAdditiveColor(vec3 v) +{ +	vary_AdditiveColor = v; +} + +void setAtmosAttenuation(vec3 v) +{ +	vary_AtmosAttenuation = v; +} + +void calcAtmospherics(vec3 inPositionEye, float ambFactor) { + +	vec3 P = inPositionEye; +	setPositionEye(P); +	 +	vec3 tmpLightnorm = lightnorm.xyz; + +	vec3 Pn = normalize(P); +	float Plen = length(P); + +	vec4 temp1 = vec4(0); +	vec3 temp2 = vec3(0); +	vec4 blue_weight; +	vec4 haze_weight; +	vec4 sunlight = sunlight_color; +	vec4 light_atten; + +	//sunlight attenuation effect (hue and brightness) due to atmosphere +	//this is used later for sunlight modulation at various altitudes +	light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); +		//I had thought blue_density and haze_density should have equal weighting, +		//but attenuation due to haze_density tends to seem too strong + +	temp1 = blue_density + vec4(haze_density); +	blue_weight = blue_density / temp1; +	haze_weight = vec4(haze_density) / temp1; + +	//(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) +	temp2.y = max(0.0, tmpLightnorm.y); +	temp2.y = 1. / temp2.y; +	sunlight *= exp( - light_atten * temp2.y); + +	// main atmospheric scattering line integral +	temp2.z = Plen * density_multiplier; + +	// Transparency (-> temp1) +	// ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati +	// compiler gets confused. +	temp1 = exp(-temp1 * temp2.z * distance_multiplier); + +	//final atmosphere attenuation factor +	setAtmosAttenuation(temp1.rgb); +	 +	//compute haze glow +	//(can use temp2.x as temp because we haven't used it yet) +	temp2.x = dot(Pn, tmpLightnorm.xyz); +	temp2.x = 1. - temp2.x; +		//temp2.x is 0 at the sun and increases away from sun +	temp2.x = max(temp2.x, .03);	//was glow.y +		//set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) +	temp2.x *= glow.x; +		//higher glow.x gives dimmer glow (because next step is 1 / "angle") +	temp2.x = pow(temp2.x, glow.z); +		//glow.z should be negative, so we're doing a sort of (1 / "angle") function + +	//add "minimum anti-solar illumination" +	temp2.x += .25; +	 +	//increase ambient when there are more clouds +	vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5; +	 +	/*  decrease value and saturation (that in HSV, not HSL) for occluded areas +	 * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html +	 * // The following line of code performs the equivalent of: +	 * float ambAlpha = tmpAmbient.a; +	 * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis +	 * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); +	 * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); +	 */ +	tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); + +	//haze color +	setAdditiveColor( +		vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient) +	  + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x +		  + tmpAmbient))); + +	//brightness of surface both sunlight and ambient +	setSunlitColor(pow(vec3(sunlight * .5), vec3(2.2)) * 2.2); +	setAmblitColor(pow(vec3(tmpAmbient * .25), vec3(2.2)) * 2.2); +	setAdditiveColor(pow(getAdditiveColor() * vec3(1.0 - temp1), vec3(2.2)) * 2.2); +} + +vec3 atmosLighting(vec3 light) +{ +	light *= getAtmosAttenuation().r; +	light += getAdditiveColor(); +	return (2.0 * light); +} + +vec3 atmosTransport(vec3 light) { +	light *= getAtmosAttenuation().r; +	light += getAdditiveColor() * 2.0; +	return light; +} +vec3 atmosGetDiffuseSunlightColor() +{ +	return getSunlitColor(); +} + +vec3 scaleDownLight(vec3 light) +{ +	return (light / vec3(scene_light_strength, scene_light_strength, scene_light_strength)); +} + +vec3 scaleUpLight(vec3 light) +{ +	return (light * vec3(scene_light_strength, scene_light_strength, scene_light_strength)); +} + +vec3 atmosAmbient(vec3 light) +{ +	return getAmblitColor() + (light * vec3(0.5f, 0.5f, 0.5f)); +} + +vec3 atmosAffectDirectionalLight(float lightIntensity) +{ +	return getSunlitColor() * vec3(lightIntensity, lightIntensity, lightIntensity); +} + +vec3 scaleSoftClip(vec3 light) +{ +	//soft clip effect: +    vec3 zeroes = vec3(0.0f, 0.0f, 0.0f); +    vec3 ones   = vec3(1.0f, 1.0f, 1.0f); + +	light = ones - clamp(light, zeroes, ones); +	light = ones - pow(light, gamma.xxx); + +	return light; +} + +vec3 fullbrightAtmosTransport(vec3 light) { +	float brightness = dot(light.rgb, vec3(0.33333)); + +	return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness); +} + +vec3 fullbrightScaleSoftClip(vec3 light) +{ +	//soft clip effect: +	return light; +} + +#else +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData +#endif +#endif + +uniform sampler2D diffuseMap; + +#if HAS_NORMAL_MAP +uniform sampler2D bumpMap; +#endif + +#if HAS_SPECULAR_MAP +uniform sampler2D specularMap; + +VARYING vec2 vary_texcoord2; +#endif + +uniform float env_intensity; +uniform vec4 specular_color;  // specular color RGB and specular exponent (glossiness) in alpha + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK) +uniform float minimum_alpha; +#endif + +#if HAS_NORMAL_MAP +VARYING vec3 vary_mat0; +VARYING vec3 vary_mat1; +VARYING vec3 vary_mat2; +VARYING vec2 vary_texcoord1; +#else +VARYING vec3 vary_normal; +#endif + +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; + +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif + +void main()  +{ +	vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy); +	diffcol.rgb *= vertex_color.rgb; + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK) +	if (diffcol.a < minimum_alpha) +	{ +		discard; +	} +#endif + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) +	vec3 old_diffcol = diffcol.rgb; +	diffcol.rgb = pow(diffcol.rgb, vec3(2.2)); +#endif + +#if HAS_SPECULAR_MAP +	vec4 spec = texture2D(specularMap, vary_texcoord2.xy); +	spec.rgb *= specular_color.rgb; +#else +	vec4 spec = vec4(specular_color.rgb, 1.0); +#endif + +#if HAS_NORMAL_MAP +	vec4 norm = texture2D(bumpMap, vary_texcoord1.xy); + +	norm.xyz = norm.xyz * 2 - 1; + +	vec3 tnorm = vec3(dot(norm.xyz,vary_mat0), +			  dot(norm.xyz,vary_mat1), +			  dot(norm.xyz,vary_mat2)); +#else +	vec4 norm = vec4(0,0,0,1.0); +	vec3 tnorm = vary_normal; +#endif + +    norm.xyz = tnorm; +    norm.xyz = normalize(norm.xyz); + +	vec4 final_color = diffcol; +	 +#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE) +	final_color.a = emissive_brightness; +#else +	final_color.a = max(final_color.a, emissive_brightness); +#endif + +	vec4 final_specular = spec; +#if HAS_SPECULAR_MAP +	vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0); +	final_specular.a = specular_color.a * norm.a; +#else +	vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0); +	final_specular.a = specular_color.a; +#endif +	 + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) +		//forward rendering, output just lit RGBA +	vec3 pos = vary_position; + +#if HAS_SUN_SHADOW +	float shadow = 0.0; +	 +	vec4 spos = vec4(pos,1.0); +		 +	if (spos.z > -shadow_clip.w) +	{	 +		vec4 lpos; +		 +		vec4 near_split = shadow_clip*-0.75; +		vec4 far_split = shadow_clip*-1.25; +		vec4 transition_domain = near_split-far_split; +		float weight = 0.0; + +		if (spos.z < near_split.z) +		{ +			lpos = shadow_matrix[3]*spos; +			 +			float w = 1.0; +			w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; +			shadow += pcfShadow(shadowMap3, lpos)*w; +			weight += w; +			shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); +		} + +		if (spos.z < near_split.y && spos.z > far_split.z) +		{ +			lpos = shadow_matrix[2]*spos; +			 +			float w = 1.0; +			w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; +			w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; +			shadow += pcfShadow(shadowMap2, lpos)*w; +			weight += w; +		} + +		if (spos.z < near_split.x && spos.z > far_split.y) +		{ +			lpos = shadow_matrix[1]*spos; +			 +			float w = 1.0; +			w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; +			w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; +			shadow += pcfShadow(shadowMap1, lpos)*w; +			weight += w; +		} + +		if (spos.z > far_split.x) +		{ +			lpos = shadow_matrix[0]*spos; +							 +			float w = 1.0; +			w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; +				 +			shadow += pcfShadow(shadowMap0, lpos)*w; +			weight += w; +		} +		 + +		shadow /= weight; +	} +	else +	{ +		shadow = 1.0; +	} +#else +	float shadow = 1.0; +#endif + +	spec = final_specular; +	vec4 diffuse = final_color; +	float envIntensity = final_normal.z; + +    vec3 col = vec3(0.0f,0.0f,0.0f); + +	float bloom = 0.0; +	calcAtmospherics(pos.xyz, 1.0); +	 +	vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); + +	float da =dot(norm.xyz, sun_dir.xyz); +    float final_da = da; +          final_da = min(final_da, shadow); +          final_da = max(final_da, diffuse.a); +          final_da = max(final_da, 0.0f); + +	col.rgb = atmosAmbient(col); +	 +	float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); +	ambient *= 0.5; +	ambient *= ambient; +	ambient = (1.0-ambient); + +	col.rgb *= ambient; + +	col.rgb = col.rgb + atmosAffectDirectionalLight(final_da * 2.6); +	col.rgb *= diffuse.rgb; +	 + +	float glare = 0.0; + +	if (spec.a > 0.0) // specular reflection +	{ +		// the old infinite-sky shiny reflection +		// +				 +		float sa = dot(refnormpersp, sun_dir.xyz); +		vec3 dumbshiny = vary_SunlitColor*shadow*(texture2D(lightFunc, vec2(sa, spec.a)).r); +							 +		// add the two types of shiny together +		vec3 spec_contrib = dumbshiny * spec.rgb; +		bloom = dot(spec_contrib, spec_contrib) / 6; + +		glare = max(spec_contrib.r, spec_contrib.g); +		glare = max(glare, spec_contrib.b); + +		col += spec_contrib; +	} + +	col = mix(col.rgb, old_diffcol.rgb, diffuse.a); + +	if (envIntensity > 0.0) +	{ +		//add environmentmap +		vec3 env_vec = env_mat * refnormpersp; +		float exponent = mix(2.2, 1.0, diffuse.a); + +		vec3 refcol = pow(textureCube(environmentMap, env_vec).rgb, vec3(exponent))*exponent; + +		col = mix(col.rgb, refcol,  +			envIntensity);   + +		float cur_glare = max(refcol.r, refcol.g); +		cur_glare = max(cur_glare, refcol.b); +		cur_glare *= envIntensity*4.0; +		glare += cur_glare; +	} + +	float exponent = mix(1.0, 2.2, diffuse.a); +	col = pow(col, vec3(exponent)); +				 +	 +	col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a); +	col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a); + +			 +	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); + +		LIGHT_LOOP(1) +		LIGHT_LOOP(2) +		LIGHT_LOOP(3) +		LIGHT_LOOP(4) +		LIGHT_LOOP(5) +		LIGHT_LOOP(6) +		LIGHT_LOOP(7) + + +	col.rgb = pow(col.rgb, vec3(1.0/2.2)); + +	frag_color.rgb = col.rgb; +	glare = min(glare, 1.0); +	frag_color.a = max(diffcol.a,glare)*vertex_color.a; + +#else +	frag_data[0] = final_color; +	frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent. +	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 new file mode 100644 index 0000000000..b25032866b --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl @@ -0,0 +1,144 @@ +/**  + * @file bumpV.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$ + */ + +#define DIFFUSE_ALPHA_MODE_IGNORE 0 +#define DIFFUSE_ALPHA_MODE_BLEND 1 +#define DIFFUSE_ALPHA_MODE_MASK 2 +#define DIFFUSE_ALPHA_MODE_EMISSIVE 3 + +#if HAS_SKIN +uniform mat4 modelview_matrix; +uniform mat4 projection_matrix; +mat4 getObjectSkinnedTransform(); +#else +uniform mat3 normal_matrix; +uniform mat4 modelview_projection_matrix; +#endif + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) + +#if !HAS_SKIN +uniform mat4 modelview_matrix; +#endif + +VARYING vec3 vary_position; + +#endif + +uniform mat4 texture_matrix0; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec4 diffuse_color; +ATTRIBUTE vec3 normal; +ATTRIBUTE vec2 texcoord0; + + +#if HAS_NORMAL_MAP +ATTRIBUTE vec4 tangent; +ATTRIBUTE vec2 texcoord1; + +VARYING vec3 vary_mat0; +VARYING vec3 vary_mat1; +VARYING vec3 vary_mat2; + +VARYING vec2 vary_texcoord1; +#else +VARYING vec3 vary_normal; +#endif + +#if HAS_SPECULAR_MAP +ATTRIBUTE vec2 texcoord2; +VARYING vec2 vary_texcoord2; +#endif +  +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; + +void main() +{ +#if HAS_SKIN +	mat4 mat = getObjectSkinnedTransform(); + +	mat = modelview_matrix * mat; + +	vec3 pos = (mat*vec4(position.xyz,1.0)).xyz; + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) +	vary_position = pos; +#endif + +	gl_Position = projection_matrix*vec4(pos,1.0); + +#else +	//transform vertex +	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);  + +#endif +	 +	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; +	 +#if HAS_NORMAL_MAP +	vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy; +#endif + +#if HAS_SPECULAR_MAP +	vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy; +#endif + +#if HAS_SKIN +	vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); +#if HAS_NORMAL_MAP +	vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz); +	vec3 b = cross(n, t)*tangent.w; +	 +	vary_mat0 = vec3(t.x, b.x, n.x); +	vary_mat1 = vec3(t.y, b.y, n.y); +	vary_mat2 = vec3(t.z, b.z, n.z); +#else //HAS_NORMAL_MAP +vary_normal  = n; +#endif //HAS_NORMAL_MAP +#else //HAS_SKIN +	vec3 n = normalize(normal_matrix * normal); +#if HAS_NORMAL_MAP +	vec3 t = normalize(normal_matrix * tangent.xyz); +	vec3 b = cross(n,t)*tangent.w; +	//vec3 t = cross(b,n) * binormal.w; +	 +	vary_mat0 = vec3(t.x, b.x, n.x); +	vary_mat1 = vec3(t.y, b.y, n.y); +	vary_mat2 = vec3(t.z, b.z, n.z); +#else //HAS_NORMAL_MAP +	vary_normal = n; +#endif //HAS_NORMAL_MAP +#endif //HAS_SKIN +	 +	vertex_color = diffuse_color; + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) +#if !HAS_SKIN +	vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz; +#endif +#endif +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 7e79317543..b35ba549f6 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -56,6 +56,40 @@ uniform float far_z;  uniform mat4 inv_proj; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif +  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).r; @@ -79,7 +113,7 @@ void main()  	}  	vec3 norm = texture2DRect(normalMap, frag.xy).xyz; -	norm = (norm.xyz-0.5)*2.0; // unpack norm +	norm = decode_normal(norm.xy); // unpack norm  	norm = normalize(norm);  	vec4 spec = texture2DRect(specularRect, frag.xy);  	vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb; @@ -110,27 +144,39 @@ void main()  		{  			lv = normalize(lv);  			da = dot(norm, lv); -					 +			  			float fa = light_col[i].a+1.0;  			float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); +			 +			dist_atten = pow(dist_atten, 2.2) * 2.2; +  			dist_atten *= noise;  			float lit = da * dist_atten; -			 +						  			vec3 col = light_col[i].rgb*lit*diff; +			  			//vec3 col = vec3(dist2, light_col[i].a, lit);  			if (spec.a > 0.0)  			{ +				lit = min(da*6.0, 1.0) * dist_atten;  				//vec3 ref = dot(pos+lv, norm); -				 -				float sa = dot(normalize(lv+npos),norm); -				 -				if (sa > 0.0) +				vec3 h = normalize(lv+npos); +				float nh = dot(norm, h); +				float nv = dot(norm, npos); +				float vh = dot(npos, h); +				float sa = nh; +				float fres = pow(1 - dot(h, npos), 5)*0.4+0.5; + +				float gtdenom = 2 * nh; +				float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); +								 +				if (nh > 0.0)  				{ -					sa = 6 * texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0); -					sa *= noise; -					col += da*sa*light_col[i].rgb*spec.rgb; +					float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); +					col += lit*scol*light_col[i].rgb*spec.rgb; +					//col += spec.rgb;  				}  			} diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index bff87cb6aa..36fb4afa52 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -40,6 +40,7 @@ uniform sampler2DRect normalMap;  uniform samplerCube environmentMap;  uniform sampler2D noiseMap;  uniform sampler2D projectionMap; +uniform sampler2D lightFunc;  uniform mat4 proj_mat; //screen space to light space  uniform float proj_near; //near clip for projection @@ -66,9 +67,49 @@ uniform vec2 screen_res;  uniform mat4 inv_proj; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif + +vec4 correctWithGamma(vec4 col) +{ +	return vec4(pow(col.rgb, vec3(2.2)), col.a); +} +  vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); +	ret = correctWithGamma(ret);  	vec2 dist = tc-vec2(0.5); @@ -84,6 +125,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); +	ret = correctWithGamma(ret);  	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); @@ -101,6 +143,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); +	ret = correctWithGamma(ret);  	vec2 dist = tc-vec2(0.5); @@ -142,7 +185,9 @@ void main()  	}  	vec3 norm = texture2DRect(normalMap, frag.xy).xyz; -	norm = vec3((norm.xy-0.5)*2.0, norm.z); +	float envIntensity = norm.z; + +	norm = decode_normal(norm.xy);  	norm = normalize(norm);  	float l_dist = -dot(lv, proj_n); @@ -157,6 +202,7 @@ void main()  	float fa = falloff+1.0;  	float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); +	dist_atten = pow(dist_atten, 2.2) * 2.2;  	if (dist_atten <= 0.0)  	{  		discard; @@ -169,7 +215,8 @@ void main()  	vec3 col = vec3(0,0,0);  	vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; -		 +	vec3 dlit = vec3(0, 0, 0); +	  	float noise = texture2D(noiseMap, frag.xy/128.0).b;  	if (proj_tc.z > 0.0 &&  		proj_tc.x < 1.0 && @@ -187,14 +234,13 @@ void main()  			vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); -			vec3 lcol = color.rgb * plcol.rgb * plcol.a; +			dlit = color.rgb * plcol.rgb * plcol.a;  			lit = da * dist_atten * noise; -			col = lcol*lit*diff_tex; +			col = dlit*lit*diff_tex;  			amb_da += (da*0.5)*proj_ambiance;  		} -		  		//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);  		vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); @@ -203,14 +249,39 @@ void main()  		amb_da *= dist_atten * noise;  		amb_da = min(amb_da, 1.0-lit); -			 -		col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; +		col += amb_da*color.rgb*diff_tex*amb_plcol.rgb*amb_plcol.a;  	}  	vec4 spec = texture2DRect(specularRect, frag.xy); +	  	if (spec.a > 0.0)  	{ +		dlit *= min(da*6.0, 1.0) * dist_atten; + +		vec3 npos = -normalize(pos); + +		//vec3 ref = dot(pos+lv, norm); +		vec3 h = normalize(lv+npos); +		float nh = dot(norm, h); +		float nv = dot(norm, npos); +		float vh = dot(npos, h); +		float sa = nh; +		float fres = pow(1 - dot(h, npos), 5)*0.4+0.5; + +		float gtdenom = 2 * nh; +		float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); + +		if (nh > 0.0) +		{ +			float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); +			col += dlit*scol*spec.rgb; +			//col += spec.rgb; +		} +	}	 + +	if (envIntensity > 0.0) +	{  		vec3 ref = reflect(normalize(pos), norm);  		//project from point pos in direction ref to plane proj_p, proj_n @@ -227,8 +298,9 @@ void main()  			{  				stc.xy /= stc.w; -				float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); +				float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0); +				//stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);  				stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);  				if (stc.x < 1.0 && @@ -236,8 +308,7 @@ void main()  					stc.x > 0.0 &&  					stc.y > 0.0)  				{ -					vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); -					col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb; +					col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*spec.rgb;										  				}  			}  		} diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index 75757b26c8..c6b1eb7c8d 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -54,6 +54,40 @@ uniform vec2 screen_res;  uniform mat4 inv_proj;  uniform vec4 viewport; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif +  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).r; @@ -84,7 +118,7 @@ void main()  	}  	vec3 norm = texture2DRect(normalMap, frag.xy).xyz; -	norm = (norm.xyz-0.5)*2.0; // unpack norm +	norm = decode_normal(norm.xy); // unpack norm  	float da = dot(norm, lv);  	if (da < 0.0)  	{ @@ -100,19 +134,30 @@ void main()  	vec3 col = texture2DRect(diffuseRect, frag.xy).rgb;  	float fa = falloff+1.0;  	float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); +	dist_atten = pow(dist_atten, 2.2) * 2.2;  	float lit = da * dist_atten * noise; -	 +  	col = color.rgb*lit*col;  	vec4 spec = texture2DRect(specularRect, frag.xy);  	if (spec.a > 0.0)  	{ -		float sa = dot(normalize(lv-normalize(pos)),norm); -		if (sa > 0.0) +		lit = min(da*6.0, 1.0) * dist_atten; + +		vec3 npos = -normalize(pos); +		vec3 h = normalize(lv+npos); +		float nh = dot(norm, h); +		float nv = dot(norm, npos); +		float vh = dot(npos, h); +		float sa = nh; +		float fres = pow(1 - dot(h, npos), 5) * 0.4+0.5; +		float gtdenom = 2 * nh; +		float gt = max(0,(min(gtdenom * nv / vh, gtdenom * da / vh))); + +		if (nh > 0.0)  		{ -			sa = 6 * texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0); -			sa *= noise; -			col += da*sa*color.rgb*spec.rgb; +			float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); +			col += lit*scol*color.rgb*spec.rgb;  		}  	} diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl new file mode 100644 index 0000000000..6f2cfae6d2 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl @@ -0,0 +1,46 @@ +/**  + * @file postDeferredGammaCorrect.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ +  +#extension GL_ARB_texture_rectangle : enable + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform sampler2DRect diffuseRect; + +uniform vec2 screen_res; +VARYING vec2 vary_fragcoord; + +uniform float texture_gamma; + +void main()  +{ +	vec4 diff = texture2DRect(diffuseRect, vary_fragcoord); +	frag_color = pow(diff, vec4(texture_gamma, texture_gamma, texture_gamma, 1.0f)); +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl index bced4a5577..91a96977f0 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl @@ -31,8 +31,12 @@ out vec4 frag_color;  uniform sampler2D diffuseMap; +#if !DEPTH_CLAMP  VARYING float pos_zd2; +#endif +  VARYING float pos_w; +  VARYING float target_pos_x;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; @@ -56,5 +60,7 @@ void main()  	frag_color = vec4(1,1,1,1); +#if !DEPTH_CLAMP  	gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0); +#endif  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl index c1f2d90712..11411a605c 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl @@ -31,8 +31,12 @@ ATTRIBUTE vec3 position;  ATTRIBUTE vec4 diffuse_color;  ATTRIBUTE vec2 texcoord0; +#if !DEPTH_CLAMP  VARYING float pos_zd2; +#endif +  VARYING float pos_w; +  VARYING float target_pos_x;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; @@ -45,10 +49,16 @@ void main()  	vec4 pre_pos = vec4(position.xyz, 1.0);  	vec4 pos = modelview_projection_matrix * pre_pos;  	target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x; +  	pos_w = pos.w; + +#if !DEPTH_CLAMP  	pos_zd2 = pos.z * 0.5;  	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +#else +	gl_Position = pos; +#endif  	passTextureIndex(); diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl index 6195e2f1ec..ef153dfc5b 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl @@ -27,7 +27,9 @@ uniform mat4 modelview_projection_matrix;  ATTRIBUTE vec3 position; +#if !DEPTH_CLAMP  VARYING vec4 post_pos; +#endif  uniform vec3 box_center;  uniform vec3 box_size; @@ -37,8 +39,12 @@ void main()  	//transform vertex  	vec3 p = position*box_size+box_center;  	vec4 pos = modelview_projection_matrix*vec4(p.xyz, 1.0); -	 + +#if !DEPTH_CLAMP  	post_pos = pos; -	 +  	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +#else +	gl_Position = pos; +#endif  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl index 7e55fdc12a..3d1b182875 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl @@ -29,11 +29,16 @@ out vec4 frag_color;  #define frag_color gl_FragColor  #endif +#if !DEPTH_CLAMP  VARYING vec4 post_pos; +#endif  void main()   {  	frag_color = vec4(1,1,1,1); +#if !DEPTH_CLAMP  	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); +#endif +  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl index 8b46e81f90..cc77a4cea0 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl @@ -27,14 +27,20 @@ uniform mat4 modelview_projection_matrix;  ATTRIBUTE vec3 position; +#if !DEPTH_CLAMP  VARYING vec4 post_pos; +#endif  void main()  {  	//transform vertex  	vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0); +#if !DEPTH_CLAMP  	post_pos = pos; -	 +  	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +#else +	gl_Position = pos; +#endif  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl index faa54a316e..22f4729e2e 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl @@ -61,6 +61,6 @@ void main()  	/// Gamma correct for WL (soft clip effect).  	frag_data[0] = vec4(scaleSoftClip(color.rgb), 1.0);  	frag_data[1] = vec4(0.0,0.0,0.0,0.0); -	frag_data[2] = vec4(0,0,1,0); +	frag_data[2] = vec4(0.5,0.5,0.0,1.0); //1.0 in norm.w masks off fog  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 89448e2167..b40850e769 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -60,6 +60,7 @@ uniform float density_multiplier;  uniform float distance_multiplier;  uniform float max_y;  uniform vec4 glow; +uniform float global_gamma;  uniform float scene_light_strength;  uniform mat3 env_mat;  uniform mat3 ssao_effect_mat; @@ -77,6 +78,34 @@ vec3 vary_AtmosAttenuation;  uniform mat4 inv_proj;  uniform vec2 screen_res; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif +  vec4 getPosition_d(vec2 pos_screen, float depth)  {  	vec2 sc = pos_screen.xy*2.0; @@ -116,7 +145,6 @@ vec3 getAtmosAttenuation()  	return vary_AtmosAttenuation;  } -  void setPositionEye(vec3 v)  {  	vary_PositionEye = v; @@ -220,9 +248,9 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {  		  + tmpAmbient)));  	//brightness of surface both sunlight and ambient -	setSunlitColor(vec3(sunlight * .5)); -	setAmblitColor(vec3(tmpAmbient * .25)); -	setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); +	setSunlitColor(pow(vec3(sunlight * .5), vec3(global_gamma)) * global_gamma); +	setAmblitColor(pow(vec3(tmpAmbient * .25), vec3(global_gamma)) * global_gamma); +	setAdditiveColor(pow(getAdditiveColor() * vec3(1.0 - temp1), vec3(global_gamma)) * global_gamma);  }  vec3 atmosLighting(vec3 light) @@ -237,6 +265,15 @@ vec3 atmosTransport(vec3 light) {  	light += getAdditiveColor() * 2.0;  	return light;  } + +vec3 fullbrightAtmosTransport(vec3 light) { +	float brightness = dot(light.rgb, vec3(0.33333)); + +	return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness); +} + + +  vec3 atmosGetDiffuseSunlightColor()  {  	return getSunlitColor(); @@ -271,59 +308,88 @@ vec3 scaleSoftClip(vec3 light)  	return light;  } + +vec3 fullbrightScaleSoftClip(vec3 light) +{ +	//soft clip effect: +	return light; +} +  void main()   {  	vec2 tc = vary_fragcoord.xy;  	float depth = texture2DRect(depthMap, tc.xy).r;  	vec3 pos = getPosition_d(tc, depth).xyz; -	vec3 norm = texture2DRect(normalMap, tc).xyz; -	norm = (norm.xyz-0.5)*2.0; // unpack norm +	vec4 norm = texture2DRect(normalMap, tc); +	float envIntensity = norm.z; +	norm.xyz = decode_normal(norm.xy); // unpack norm  	float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); -	 +  	vec4 diffuse = texture2DRect(diffuseRect, tc);  	vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); -	  	vec3 col;  	float bloom = 0.0; -	if (diffuse.a < 0.9)  	{  		calcAtmospherics(pos.xyz, 1.0);  		col = atmosAmbient(vec3(0)); -		col += atmosAffectDirectionalLight(max(min(da, 1.0), diffuse.a)); +		float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); +		ambient *= 0.5; +		ambient *= ambient; +		ambient = (1.0-ambient); + +		col.rgb *= ambient; + +		col += atmosAffectDirectionalLight(max(min(da, 1.0) * 2.6, 0.0));  		col *= diffuse.rgb; +		vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); +  		if (spec.a > 0.0) // specular reflection  		{  			// the old infinite-sky shiny reflection  			// -			vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); +			  			float sa = dot(refnormpersp, sun_dir.xyz); -			vec3 dumbshiny = vary_SunlitColor*(6 * texture2D(lightFunc, vec2(sa, spec.a)).r); +			vec3 dumbshiny = vary_SunlitColor*(texture2D(lightFunc, vec2(sa, spec.a)).r);  			// add the two types of shiny together  			vec3 spec_contrib = dumbshiny * spec.rgb; -			bloom = dot(spec_contrib, spec_contrib) / 4; +			bloom = dot(spec_contrib, spec_contrib) / 6;  			col += spec_contrib; - -			//add environmentmap +		} +		 +		 +		col = mix(col.rgb, pow(diffuse.rgb, vec3(1.0/2.2)), diffuse.a); +		 +		 +		if (envIntensity > 0.0) +		{ //add environmentmap  			vec3 env_vec = env_mat * refnormpersp; -			col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb,  -				max(spec.a-diffuse.a*2.0, 0.0));  +			 +			float exponent = mix(2.2, 1.0, diffuse.a); +			vec3 refcol = pow(textureCube(environmentMap, env_vec).rgb, vec3(exponent))*exponent; + +			col = mix(col.rgb, refcol,  +				envIntensity);   +  		} -	 -		col = atmosLighting(col); -		col = scaleSoftClip(col); -		col = mix(col.rgb, diffuse.rgb, diffuse.a); -	} -	else -	{ -		col = diffuse.rgb; -	} +		float exponent = mix(1.0, 2.2, diffuse.a); +		col = pow(col, vec3(exponent)); +				 +		if (norm.w < 0.5) +		{ +			col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a); +			col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a); +		} +		//col = vec3(1,0,1); +		//col.g = envIntensity; +	} +	  	frag_color.rgb = col;  	frag_color.a = bloom; diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl index c6031fc45a..b59fcbe017 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl @@ -35,6 +35,6 @@ void main()  	//transform vertex  	vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);  	gl_Position = pos;  -		 +	  	vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl index cca63872de..3539c8d2b2 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -22,18 +22,15 @@   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ - +#extension GL_ARB_texture_rectangle : enable +  #ifdef DEFINE_GL_FRAGCOLOR  out vec4 frag_color;  #else  #define frag_color gl_FragColor  #endif -//class 1 -- no shadows - -#extension GL_ARB_texture_rectangle : enable -  uniform sampler2DRect diffuseRect;  uniform sampler2DRect specularRect;  uniform sampler2DRect depthMap; @@ -41,6 +38,7 @@ uniform sampler2DRect normalMap;  uniform samplerCube environmentMap;  uniform sampler2D noiseMap;  uniform sampler2D projectionMap; +uniform sampler2D lightFunc;  uniform mat4 proj_mat; //screen space to light space  uniform float proj_near; //near clip for projection @@ -57,20 +55,59 @@ uniform float far_clip;  uniform vec3 proj_origin; //origin of projection to be used for angular attenuation  uniform float sun_wash; +uniform float size;  uniform vec3 color;  uniform float falloff; -uniform float size; -VARYING vec4 vary_fragcoord;  VARYING vec3 trans_center; - +VARYING vec4 vary_fragcoord;  uniform vec2 screen_res;  uniform mat4 inv_proj; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif + +vec4 correctWithGamma(vec4 col) +{ +	return vec4(pow(col.rgb, vec3(2.2)), col.a); +} +  vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); +	ret = correctWithGamma(ret);  	vec2 dist = tc-vec2(0.5); @@ -86,6 +123,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); +	ret = correctWithGamma(ret);  	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); @@ -103,6 +141,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); +	ret = correctWithGamma(ret);  	vec2 dist = tc-vec2(0.5); @@ -142,9 +181,11 @@ void main()  	{  		discard;  	} +	  	vec3 norm = texture2DRect(normalMap, frag.xy).xyz; -	norm = vec3((norm.xy-0.5)*2.0, norm.z); +	float envIntensity = norm.z; +	norm = decode_normal(norm.xy);  	norm = normalize(norm);  	float l_dist = -dot(lv, proj_n); @@ -159,6 +200,7 @@ void main()  	float fa = falloff+1.0;  	float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); +	dist_atten = pow(dist_atten, 2.2) * 2.2;  	if (dist_atten <= 0.0)  	{  		discard; @@ -172,31 +214,35 @@ void main()  	vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; +	vec4 spec = texture2DRect(specularRect, frag.xy); + +	 +  	float noise = texture2D(noiseMap, frag.xy/128.0).b; +	vec3 dlit = vec3(0, 0, 0); +	  	if (proj_tc.z > 0.0 &&  		proj_tc.x < 1.0 &&  		proj_tc.y < 1.0 &&  		proj_tc.x > 0.0 &&  		proj_tc.y > 0.0)  	{ -		float lit = 0.0;  		float amb_da = proj_ambiance; +		float lit = 0.0;  		if (da > 0.0)  		{ +			lit = da * dist_atten * noise; +  			float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);  			float lod = diff * proj_lod;  			vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); -		 -			vec3 lcol = color.rgb * plcol.rgb * plcol.a; -			 -			lit = da * dist_atten * noise; +			dlit = color.rgb * plcol.rgb * plcol.a; -			col = lcol*lit*diff_tex; -			amb_da += (da*0.5)*proj_ambiance; +			col = dlit*lit*diff_tex; +			//amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;  		} -		  		//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);  		vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); @@ -205,14 +251,41 @@ void main()  		amb_da *= dist_atten * noise;  		amb_da = min(amb_da, 1.0-lit); -			 -		col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; +		col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a*diff_tex.rgb;  	} -	 -	vec4 spec = texture2DRect(specularRect, frag.xy); +  	if (spec.a > 0.0)  	{ +		dlit *= min(da*6.0, 1.0) * dist_atten; +		vec3 npos = -normalize(pos); + +		//vec3 ref = dot(pos+lv, norm); +		vec3 h = normalize(lv+npos); +		float nh = dot(norm, h); +		float nv = dot(norm, npos); +		float vh = dot(npos, h); +		float sa = nh; +		float fres = pow(1 - dot(h, npos), 5)*0.4+0.5; + +		float gtdenom = 2 * nh; +		float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); +								 +		if (nh > 0.0) +		{ +			 +			float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); +			col += dlit*scol*spec.rgb; +			//col += spec.rgb; +		} +	}	 +	 +	 +	 +	 + +	if (envIntensity > 0.0) +	{  		vec3 ref = reflect(normalize(pos), norm);  		//project from point pos in direction ref to plane proj_p, proj_n @@ -229,8 +302,9 @@ void main()  			{  				stc.xy /= stc.w; -				float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); +				float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0); +				//stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);  				stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);  				if (stc.x < 1.0 && @@ -238,8 +312,7 @@ void main()  					stc.x > 0.0 &&  					stc.y > 0.0)  				{ -					vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); -					col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb; +					col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*spec.rgb;										  				}  			}  		} diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl index bac74cbbef..6653f57ee1 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -49,6 +49,40 @@ VARYING vec2 vary_fragcoord;  uniform mat4 inv_proj;  uniform vec2 screen_res; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif +  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).r; @@ -123,7 +157,7 @@ void main()  	vec4 pos = getPosition(pos_screen);  	vec3 norm = texture2DRect(normalMap, pos_screen).xyz; -	norm = (norm.xyz-0.5)*2.0; // unpack norm +	norm = decode_normal(norm.xy);  	frag_color[0] = 1.0;  	frag_color[1] = calcAmbientOcclusion(pos, norm); diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl index daf1cc7ea2..52a429465f 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl @@ -39,6 +39,12 @@ VARYING vec3 vary_normal;  VARYING vec4 vary_texcoord0;  VARYING vec4 vary_texcoord1; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} +  void main()  {  	/// Note: This should duplicate the blending functionality currently used for the terrain rendering. @@ -56,6 +62,6 @@ void main()  	frag_data[0] = vec4(outColor.rgb, 0.0);  	frag_data[1] = vec4(0,0,0,0);  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); +	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index da253846ef..808750496f 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -37,6 +37,12 @@ VARYING vec2 vary_texcoord0;  uniform float minimum_alpha; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} +  void main()   {  	vec4 col = texture2D(diffuseMap, vary_texcoord0.xy); @@ -48,5 +54,5 @@ void main()  	frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0);  	frag_data[1] = vec4(0,0,0,0);  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0); +	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 1ae006bc8a..daa2fb390a 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -67,6 +67,12 @@ VARYING vec4 littleWave;  VARYING vec4 view;  VARYING vec4 vary_position; +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} +  void main()   {  	vec4 color; @@ -161,5 +167,5 @@ void main()  	frag_data[0] = vec4(color.rgb, 0.5); // diffuse  	frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec -	frag_data[2] = vec4(screenspacewavef.xyz*0.5+0.5, screenspacewavef.z*0.5); // normalxyz, displace +	frag_data[2] = vec4(encode_normal(screenspacewavef), 0.0, 0.0); // normalxyz, displace  } diff --git a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl index 5aff156eae..352cea7aaa 100755 --- a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl @@ -82,7 +82,8 @@ void main()  	pos.w = 1.0;  	pos = modelview_matrix*pos; -	calcAtmospherics(view.xyz); +	calcAtmospherics(pos.xyz); +	  	//pass wave parameters to pixel shader  	vec2 bigWave =  (v.xy) * vec2(0.04,0.04)  + d1 * time * 0.055; diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightNormV.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightNormV.glsl new file mode 100644 index 0000000000..947c2b0065 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/highlightNormV.glsl @@ -0,0 +1,42 @@ +/**  + * @file highlightV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat4 texture_matrix0; +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec2 texcoord0; +ATTRIBUTE vec2 texcoord1; +ATTRIBUTE vec2 texcoord2; + +VARYING vec2 vary_texcoord0; + +void main() +{ +	//transform vertex +	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); +	vary_texcoord0 = (texture_matrix0 * vec4(texcoord1,0,1)).xy; +} + diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightSpecV.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightSpecV.glsl new file mode 100644 index 0000000000..c5d102b739 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/highlightSpecV.glsl @@ -0,0 +1,42 @@ +/**  + * @file highlightV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat4 texture_matrix0; +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec2 texcoord0; +ATTRIBUTE vec2 texcoord1; +ATTRIBUTE vec2 texcoord2; + +VARYING vec2 vary_texcoord0; + +void main() +{ +	//transform vertex +	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); +	vary_texcoord0 = (texture_matrix0 * vec4(texcoord2,0,1)).xy; +} + diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl index cf29939cb2..eaaa7b208d 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl @@ -39,13 +39,15 @@ VARYING vec2 vary_texcoord0;  void default_lighting()   { -	vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color; +	vec4 color = diffuseLookup(vary_texcoord0.xy);  	if (color.a < minimum_alpha)  	{  		discard;  	} +	color.rgb *= vertex_color.rgb; +  	color.rgb = atmosLighting(color.rgb);  	color.rgb = scaleSoftClip(color.rgb); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl index 4070d41f47..b9ddbc8e1c 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl @@ -41,13 +41,15 @@ VARYING vec2 vary_texcoord0;  void default_lighting()   { -	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color; +	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);  	if (color.a < minimum_alpha)  	{  		discard;  	} +	color.rgb *= vertex_color.rgb; +	  	color.rgb = atmosLighting(color.rgb);  	color.rgb = scaleSoftClip(color.rgb); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl index 6c34643aab..5740987ab1 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl @@ -30,6 +30,7 @@ out vec4 frag_color;  #endif  uniform float minimum_alpha; +uniform float texture_gamma;  vec3 fullbrightAtmosTransport(vec3 light);  vec3 fullbrightScaleSoftClip(vec3 light); @@ -39,13 +40,16 @@ VARYING vec2 vary_texcoord0;  void fullbright_lighting()  { -	vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color; +	vec4 color = diffuseLookup(vary_texcoord0.xy);  	if (color.a < minimum_alpha)  	{  		discard;  	} +	color.rgb *= vertex_color.rgb; + +	color.rgb = pow(color.rgb, vec3(texture_gamma));  	color.rgb = fullbrightAtmosTransport(color.rgb);  	color.rgb = fullbrightScaleSoftClip(color.rgb); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl index 2ff7f795b0..c8771a3f1e 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl @@ -32,6 +32,8 @@ out vec4 frag_color;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; +uniform float texture_gamma; +  vec3 fullbrightAtmosTransport(vec3 light);  vec3 fullbrightScaleSoftClip(vec3 light); @@ -39,10 +41,14 @@ void fullbright_lighting()  {  	vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color; +	color.rgb = pow(color.rgb, vec3(texture_gamma)); +  	color.rgb = fullbrightAtmosTransport(color.rgb);  	color.rgb = fullbrightScaleSoftClip(color.rgb); +	color.rgb = pow(color.rgb, vec3(1.0/texture_gamma)); +  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl index f4477bd29a..f72f20b03d 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl @@ -30,6 +30,7 @@ out vec4 frag_color;  #endif  uniform float minimum_alpha; +uniform float texture_gamma;  vec3 fullbrightAtmosTransport(vec3 light);  vec3 fullbrightScaleSoftClip(vec3 light); @@ -41,17 +42,22 @@ VARYING vec2 vary_texcoord0;  void fullbright_lighting()  { -	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color; +	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);  	if (color.a < minimum_alpha)  	{  		discard;  	} +	 +	color.rgb *= vertex_color.rgb; +	color.rgb = pow(color.rgb, vec3(texture_gamma));  	color.rgb = fullbrightAtmosTransport(color.rgb);  	color.rgb = fullbrightScaleSoftClip(color.rgb); +	color.rgb = pow(color.rgb, vec3(1.0/texture_gamma)); +  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl index 777c8b45bb..c8282e9a51 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl @@ -50,7 +50,7 @@ void fullbright_shiny_lighting()  	color.rgb = fullbrightScaleSoftClip(color.rgb); -	color.a = max(color.a, vertex_color.a); +	color.a = 1.0;  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl index 4fa3b1d939..e7dbd4bbd2 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl @@ -51,7 +51,7 @@ void fullbright_shiny_lighting()  	color.rgb = fullbrightScaleSoftClip(color.rgb); -	color.a = max(color.a, vertex_color.a); +	color.a = 1.0;  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl index 58984a4263..5886fc65be 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl @@ -48,7 +48,7 @@ void fullbright_shiny_lighting_water()  	color.rgb = fullbrightShinyAtmosTransport(color.rgb);  	color.rgb = fullbrightScaleSoftClip(color.rgb); -	color.a = max(color.a, vertex_color.a); +	color.a = 1.0;  	frag_color = applyWaterFog(color);  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl index a39b7205d7..cddc7d8df8 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl @@ -49,7 +49,7 @@ void fullbright_shiny_lighting_water()  	color.rgb = fullbrightShinyAtmosTransport(color.rgb);  	color.rgb = fullbrightScaleSoftClip(color.rgb); -	color.a = max(color.a, vertex_color.a); +	color.a = 1.0;  	frag_color = applyWaterFog(color);  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl index 9c82056fd7..6dd3bb937f 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl @@ -41,7 +41,9 @@ VARYING vec2 vary_texcoord0;  void fullbright_lighting_water()  { -	vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color; +	vec4 color = diffuseLookup(vary_texcoord0.xy); + +	color.rgb *= vertex_color.rgb;  	if (color.a < minimum_alpha)  	{ diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl index 52e3b2ad02..9208c148ef 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl @@ -50,7 +50,7 @@ void shiny_lighting()  	color.rgb = atmosLighting(color.rgb);  	color.rgb = scaleSoftClip(color.rgb); -	color.a = max(color.a, vertex_color.a); +	color.a = 1.0;  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl index 474d5ea496..92628faa68 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl @@ -51,7 +51,7 @@ void shiny_lighting()  	color.rgb = atmosLighting(color.rgb);  	color.rgb = scaleSoftClip(color.rgb); -	color.a = max(color.a, vertex_color.a); +	color.a = 1.0;  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl index d2a4c47aac..61841674e2 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl @@ -47,7 +47,7 @@ void shiny_lighting_water()  	color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);  	color.rgb = atmosLighting(color.rgb); -	color.a = max(color.a, vertex_color.a); +	color.a = 1.0;  	frag_color = applyWaterFog(color);  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl index f3bd662364..0b6e835fd0 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl @@ -48,7 +48,7 @@ void shiny_lighting_water()  	color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);  	color.rgb = atmosLighting(color.rgb); -	color.a = max(color.a, vertex_color.a); +	color.a = 1.0;  	frag_color = applyWaterFog(color);  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl index b68240ba0d..3426fea52f 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl @@ -39,7 +39,9 @@ VARYING vec2 vary_texcoord0;  void default_lighting_water()  { -	vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color; +	vec4 color = diffuseLookup(vary_texcoord0.xy); + +	color.rgb *= vertex_color.rgb;  	if (color.a < minimum_alpha)  	{ diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl index da3b20012d..d9faa9b314 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl @@ -41,7 +41,9 @@ VARYING vec2 vary_texcoord0;  void default_lighting_water()  { -	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color; +	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy); + +	color.rgb *= vertex_color.rgb;  	if (color.a < minimum_alpha)  	{ diff --git a/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl index 8494ffba52..9064904191 100755 --- a/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl @@ -48,11 +48,9 @@ void main()  	mat = modelview_matrix * mat;  	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; +	vertex_color = emissive; +  	calcAtmospherics(pos.xyz); -	vertex_color = emissive; -	  	gl_Position = projection_matrix*vec4(pos, 1.0); -		 -	  } diff --git a/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl index 44f1aa34a0..449d8d8b4e 100755 --- a/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl +++ b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl @@ -25,12 +25,12 @@  uniform mat3 normal_matrix; -ATTRIBUTE vec3 binormal; +ATTRIBUTE vec4 tangent; -VARYING vec4 binormal_out; +VARYING vec4 tangent_out;  void main()  { -	binormal_out = vec4(normal_matrix * binormal, 0.0); +	tangent_out = vec4(normal_matrix * tangent.xyz), tangent.w);  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl deleted file mode 100755 index 12706f130b..0000000000 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ /dev/null @@ -1,164 +0,0 @@ -/**  - * @file alphaF.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2007, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#extension GL_ARB_texture_rectangle : enable - -#ifdef DEFINE_GL_FRAGCOLOR -out vec4 frag_color; -#else -#define frag_color gl_FragColor -#endif - -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; - -uniform sampler2DShadow shadowMap0; -uniform sampler2DShadow shadowMap1; -uniform sampler2DShadow shadowMap2; -uniform sampler2DShadow shadowMap3; -uniform sampler2DRect depthMap; - -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip; -uniform vec2 screen_res; -uniform vec2 shadow_res; - -vec3 atmosLighting(vec3 light); -vec3 scaleSoftClip(vec3 light); - -VARYING vec3 vary_ambient; -VARYING vec3 vary_directional; -VARYING vec3 vary_fragcoord; -VARYING vec3 vary_position; -VARYING vec3 vary_pointlight_col; - -uniform float shadow_bias; - -uniform mat4 inv_proj; - -float pcfShadow(sampler2DShadow shadowMap, vec4 stc) -{ -	stc.xyz /= stc.w; -	stc.z += shadow_bias; -		 -	stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here -	 -	float cs = shadow2D(shadowMap, stc.xyz).x; -	float shadow = cs; -	 -    shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; -    shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; -    shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; -    shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; -                        -    return shadow*0.2; -} - - -void main()  -{ -	vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; -	frag *= screen_res; -	 -	float shadow = 0.0; -	vec4 pos = vec4(vary_position, 1.0); -	 -	vec4 spos = pos; -		 -	if (spos.z > -shadow_clip.w) -	{	 -		vec4 lpos; -		 -		vec4 near_split = shadow_clip*-0.75; -		vec4 far_split = shadow_clip*-1.25; -		vec4 transition_domain = near_split-far_split; -		float weight = 0.0; - -		if (spos.z < near_split.z) -		{ -			lpos = shadow_matrix[3]*spos; -			 -			float w = 1.0; -			w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; -			shadow += pcfShadow(shadowMap3, lpos)*w; -			weight += w; -			shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); -		} - -		if (spos.z < near_split.y && spos.z > far_split.z) -		{ -			lpos = shadow_matrix[2]*spos; -			 -			float w = 1.0; -			w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; -			w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; -			shadow += pcfShadow(shadowMap2, lpos)*w; -			weight += w; -		} - -		if (spos.z < near_split.x && spos.z > far_split.y) -		{ -			lpos = shadow_matrix[1]*spos; -			 -			float w = 1.0; -			w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; -			w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; -			shadow += pcfShadow(shadowMap1, lpos)*w; -			weight += w; -		} - -		if (spos.z > far_split.x) -		{ -			lpos = shadow_matrix[0]*spos; -							 -			float w = 1.0; -			w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; -				 -			shadow += pcfShadow(shadowMap0, lpos)*w; -			weight += w; -		} -		 - -		shadow /= weight; -	} -	else -	{ -		shadow = 1.0; -	} -	 -	vec4 diff = diffuseLookup(vary_texcoord0.xy); - -	vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, vertex_color.a); -	vec4 color = diff * col; -	 -	color.rgb = atmosLighting(color.rgb); - -	color.rgb = scaleSoftClip(color.rgb); - -	color.rgb += diff.rgb * vary_pointlight_col.rgb; - -	frag_color = color; -} - diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl index 228dc104ac..9670d59399 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl @@ -52,12 +52,54 @@ VARYING vec3 vary_position;  VARYING vec3 vary_pointlight_col;  VARYING vec2 vary_texcoord0;  VARYING vec4 vertex_color; +VARYING vec3 vary_norm;  uniform vec2 shadow_res;  uniform float shadow_bias;  uniform mat4 inv_proj; +uniform vec4 light_position[8]; +uniform vec3 light_direction[8]; +uniform vec3 light_attenuation[8];  +uniform vec3 light_diffuse[8]; + +vec3 calcDirectionalLight(vec3 n, vec3 l) +{ +        float a = pow(max(dot(n,l),0.0), 0.7); +        return vec3(a,a,a); +} + +vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +{ +	//get light vector +	vec3 lv = lp.xyz-v; +	 +	//get distance +	float d = dot(lv,lv); +	 +	float da = 0.0; + +	if (d > 0.0 && la > 0.0 && fa > 0.0) +	{ +		//normalize light vector +		lv = normalize(lv); +	 +		//distance attenuation +		float dist2 = d/la; +		da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + +		// spotlight coefficient. +		float spot = max(dot(-ln, lv), is_pointlight); +		da *= spot*spot; // GL_SPOT_EXPONENT=2 + +		//angular attenuation +		da *= max(pow(dot(n, lv), 0.7), 0.0);		 +	} + +	return vec3(da,da,da);	 +} +  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).a; @@ -161,17 +203,32 @@ void main()  	{  		shadow = 1.0;  	} - +	vec3 n = vary_norm; +	vec3 l = light_position[0].xyz; +	vec3 dlight = calcDirectionalLight(n, l); +	dlight = dlight * vary_directional.rgb * vary_pointlight_col;  	vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy); -	vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, vertex_color.a); +	vec4 col = vec4(vary_ambient + dlight*shadow, vertex_color.a);  	vec4 color = diff * col;  	color.rgb = atmosLighting(color.rgb);  	color.rgb = scaleSoftClip(color.rgb); +	vec3 light_col = vec3(0,0,0); + +  #define LIGHT_LOOP(i) \ +		light_col += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, vary_norm, light_position[i], light_direction[i], light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); + +	LIGHT_LOOP(1) +	LIGHT_LOOP(2) +	LIGHT_LOOP(3) +	LIGHT_LOOP(4) +	LIGHT_LOOP(5) +	LIGHT_LOOP(6) +	LIGHT_LOOP(7) -	color.rgb += diff.rgb * vary_pointlight_col.rgb; +	color.rgb += diff.rgb * vary_pointlight_col * light_col;  	frag_color = color;	  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl index c3950a10e1..fae279fba0 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl @@ -53,6 +53,7 @@ VARYING vec3 vary_fragcoord;  VARYING vec3 vary_position;  VARYING vec3 vary_pointlight_col;  VARYING vec2 vary_texcoord0; +VARYING vec3 vary_norm;  uniform vec2 shadow_res; @@ -60,6 +61,47 @@ uniform float shadow_bias;  uniform mat4 inv_proj; +uniform vec4 light_position[8]; +uniform vec3 light_direction[8]; +uniform vec3 light_attenuation[8];  +uniform vec3 light_diffuse[8]; + +vec3 calcDirectionalLight(vec3 n, vec3 l) +{ +        float a = pow(max(dot(n,l),0.0), 0.7); +        return vec3(a, a, a); +} + +vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +{ +	//get light vector +	vec3 lv = lp.xyz-v; +	 +	//get distance +	float d = dot(lv,lv); +	 +	float da = 0.0; + +	if (d > 0.0 && la > 0.0 && fa > 0.0) +	{ +		//normalize light vector +		lv = normalize(lv); +	 +		//distance attenuation +		float dist2 = d/la; +		da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + +		// spotlight coefficient. +		float spot = max(dot(-ln, lv), is_pointlight); +		da *= spot*spot; // GL_SPOT_EXPONENT=2 + +		//angular attenuation +		da *= max(pow(dot(n, lv), 0.7), 0.0);		 +	} + +	return vec3(da,da,da);	 +} +  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).a; @@ -169,15 +211,31 @@ void main()  	{  		shadow = 1.0;  	} +	vec3 n = vary_norm; +	vec3 l = light_position[0].xyz; +	vec3 dlight = calcDirectionalLight(n, l); +	dlight = dlight * vary_directional.rgb * vary_pointlight_col; -	vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, 1.0); +	vec4 col = vec4(vary_ambient + dlight*shadow, 1.0);  	vec4 color = diff * col;  	color.rgb = atmosLighting(color.rgb);  	color.rgb = scaleSoftClip(color.rgb); +	vec3 light_col = vec3(0,0,0); + +  #define LIGHT_LOOP(i) \ +		light_col += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, vary_norm, light_position[i], light_direction[i], light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); + +	LIGHT_LOOP(1) +	LIGHT_LOOP(2) +	LIGHT_LOOP(3) +	LIGHT_LOOP(4) +	LIGHT_LOOP(5) +	LIGHT_LOOP(6) +	LIGHT_LOOP(7) -	color.rgb += diff.rgb * vary_pointlight_col.rgb; +	color.rgb += diff.rgb * vary_pointlight_col * light_col;  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl index 9629cfe824..7f4d82ecc6 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl @@ -50,7 +50,7 @@ VARYING vec3 vary_pointlight_col;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; - +VARYING vec3 vary_norm;  uniform float near_clip;  uniform float shadow_offset; @@ -115,7 +115,8 @@ void main()  	n.xyz = normalize(n.xyz-pos.xyz);  	vec3 norm = n.xyz; -	 +	vary_norm = norm; +  	float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));  	vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset; diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl index 1586aab0f2..13c6ffc607 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl @@ -25,19 +25,36 @@  uniform mat3 normal_matrix;  uniform mat4 texture_matrix0; +uniform mat4 projection_matrix;  uniform mat4 modelview_matrix;  uniform mat4 modelview_projection_matrix;  ATTRIBUTE vec3 position; + +#ifdef USE_INDEXED_TEX  void passTextureIndex(); +#endif +  ATTRIBUTE vec3 normal; + +#ifdef USE_VERTEX_COLOR  ATTRIBUTE vec4 diffuse_color; +#endif +  ATTRIBUTE vec2 texcoord0; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +#else +#ifdef IS_AVATAR_SKIN +mat4 getSkinnedTransform(); +#endif +#endif +  vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);  void calcAtmospherics(vec3 inPositionEye); -float calcDirectionalLight(vec3 n, vec3 l); +vec3 calcDirectionalLight(vec3 n, vec3 l);  vec3 atmosAmbient(vec3 light);  vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -50,9 +67,12 @@ VARYING vec3 vary_fragcoord;  VARYING vec3 vary_position;  VARYING vec3 vary_pointlight_col; +#ifdef USE_VERTEX_COLOR  VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; +#endif +VARYING vec2 vary_texcoord0; +VARYING vec3 vary_norm;  uniform float near_clip;  uniform float shadow_offset; @@ -63,13 +83,15 @@ uniform vec3 light_direction[8];  uniform vec3 light_attenuation[8];   uniform vec3 light_diffuse[8]; -float calcDirectionalLight(vec3 n, vec3 l) +uniform vec3 sun_dir; + +vec3 calcDirectionalLight(vec3 n, vec3 l)  {          float a = max(dot(n,l),0.0); -        return a; +        return vec3(a,a,a);  } -float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)  {  	//get light vector  	vec3 lv = lp.xyz-v; @@ -96,55 +118,107 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa  		da *= max(dot(n, lv), 0.0);		  	} -	return da;	 +	return vec3(da,da,da);	  }  void main()  { +	vec4 pos; +	vec3 norm; +	  	//transform vertex +#ifdef HAS_SKIN +	mat4 trans = getObjectSkinnedTransform(); +	trans = modelview_matrix * trans; +	 +	pos = trans * vec4(position.xyz, 1.0); +	 +	norm = position.xyz + normal.xyz; +	norm = normalize((trans * vec4(norm, 1.0)).xyz - pos.xyz); +	vec4 frag_pos = projection_matrix * pos; +	gl_Position = frag_pos; +#else + +#ifdef IS_AVATAR_SKIN +	mat4 trans = getSkinnedTransform(); +	vec4 pos_in = vec4(position.xyz, 1.0); +	pos.x = dot(trans[0], pos_in); +	pos.y = dot(trans[1], pos_in); +	pos.z = dot(trans[2], pos_in); +	pos.w = 1.0; +	 +	norm.x = dot(trans[0].xyz, normal); +	norm.y = dot(trans[1].xyz, normal); +	norm.z = dot(trans[2].xyz, normal); +	norm = normalize(norm); +	 +	vec4 frag_pos = projection_matrix * pos; +	gl_Position = frag_pos; +#else +	norm = normalize(normal_matrix * normal);  	vec4 vert = vec4(position.xyz, 1.0); -	passTextureIndex(); -	vec4 pos = (modelview_matrix * vert); +	pos = (modelview_matrix * vert);  	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); +#endif +#endif + +#ifdef USE_INDEXED_TEX +	passTextureIndex();  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -		 -	vec3 norm = normalize(normal_matrix * normal); +#else +	vary_texcoord0 = texcoord0; +#endif +	vary_norm = norm;  	float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));  	vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset; -		 +	  	calcAtmospherics(pos.xyz); +#ifndef USE_VERTEX_COLOR +	vec4 diffuse_color = vec4(1,1,1,1); +#endif +  	//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));  	vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a); -	 -	// Collect normal lights -	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z); -	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z); -	col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z); -	col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z); -	col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z); -	col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z); +	vec3 dff = pow(diffuse_color.rgb, vec3(2.2f,2.2f,2.2f)); -	vary_pointlight_col = col.rgb*diffuse_color.rgb; +	vary_pointlight_col = dff;  	col.rgb = vec3(0,0,0);  	// Add windlight lights -	col.rgb = atmosAmbient(vec3(0.)); +	col.rgb = atmosAmbient(col.rgb); -	vary_ambient = col.rgb*diffuse_color.rgb; -	vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a))); +	float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); +	ambient *= 0.5; +	ambient *= ambient; +	ambient = (1.0-ambient); + +	col.rgb *= ambient; + +	vary_directional.rgb = atmosAffectDirectionalLight(1.0f); +	vary_ambient = col.rgb*dff; -	col.rgb = col.rgb*diffuse_color.rgb; +	col.rgb = col.rgb*dff; +#ifdef USE_VERTEX_COLOR  	vertex_color = col; - -	 +#endif +#ifdef HAS_SKIN +	vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip); +#else + +#ifdef IS_AVATAR_SKIN +	vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); +#else  	pos = modelview_projection_matrix * vert;  	vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); -	 +#endif + +#endif +  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index 5621e47ab7..eaacb93cb9 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -39,6 +39,7 @@ uniform samplerCube environmentMap;  uniform sampler2DRect lightMap;  uniform sampler2D noiseMap;  uniform sampler2D projectionMap; +uniform sampler2D lightFunc;  uniform mat4 proj_mat; //screen space to light space  uniform float proj_near; //near clip for projection @@ -67,10 +68,51 @@ uniform vec2 screen_res;  uniform mat4 inv_proj; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif + +vec4 correctWithGamma(vec4 col) +{ +	return vec4(pow(col.rgb, vec3(2.2)), col.a); +} + +  vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	 +	ret = correctWithGamma(ret); +  	vec2 dist = tc-vec2(0.5);  	float det = max(1.0-lod/(proj_lod*0.5), 0.0); @@ -85,7 +127,8 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	 +	ret = correctWithGamma(ret); +  	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));  	float det = min(lod/(proj_lod*0.5), 1.0); @@ -102,7 +145,8 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); -	 +	ret = correctWithGamma(ret); +  	vec2 dist = tc-vec2(0.5);  	float d = dot(dist,dist); @@ -154,7 +198,10 @@ void main()  	}  	vec3 norm = texture2DRect(normalMap, frag.xy).xyz; -	norm = (norm.xyz-0.5)*2.0; // unpack norm +	 +	float envIntensity = norm.z; + +	norm = decode_normal(norm.xy);  	norm = normalize(norm);  	float l_dist = -dot(lv, proj_n); @@ -169,6 +216,7 @@ void main()  	float fa = falloff+1.0;  	float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); +	dist_atten = pow(dist_atten, 2.2) * 2.2;  	if (dist_atten <= 0.0)  	{  		discard; @@ -177,11 +225,15 @@ void main()  	lv = proj_origin-pos.xyz;  	lv = normalize(lv);  	float da = dot(norm, lv); -		 +  	vec3 col = vec3(0,0,0);  	vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; -		 +	 +	vec4 spec = texture2DRect(specularRect, frag.xy); + +	vec3 dlit = vec3(0, 0, 0); +  	float noise = texture2D(noiseMap, frag.xy/128.0).b;  	if (proj_tc.z > 0.0 &&  		proj_tc.x < 1.0 && @@ -189,21 +241,21 @@ void main()  		proj_tc.x > 0.0 &&  		proj_tc.y > 0.0)  	{ -		float lit = 0.0;  		float amb_da = proj_ambiance; -		 +		float lit = 0.0; +  		if (da > 0.0)  		{ +			lit = da * dist_atten * noise; +  			float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);  			float lod = diff * proj_lod;  			vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); -			vec3 lcol = color.rgb * plcol.rgb * plcol.a; +			dlit = color.rgb * plcol.rgb * plcol.a; -			lit = da * dist_atten * noise; -			 -			col = lcol*lit*diff_tex*shadow; +			col = dlit*lit*diff_tex*shadow;  			amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;  		} @@ -219,10 +271,37 @@ void main()  		col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;  	} -	 -	vec4 spec = texture2DRect(specularRect, frag.xy); +  	if (spec.a > 0.0)  	{ +		vec3 npos = -normalize(pos); +		dlit *= min(da*6.0, 1.0) * dist_atten; + +		//vec3 ref = dot(pos+lv, norm); +		vec3 h = normalize(lv+npos); +		float nh = dot(norm, h); +		float nv = dot(norm, npos); +		float vh = dot(npos, h); +		float sa = nh; +		float fres = pow(1 - dot(h, npos), 5)*0.4+0.5; + +		float gtdenom = 2 * nh; +		float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); +								 +		if (nh > 0.0) +		{ +			float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); +			col += dlit*scol*spec.rgb*shadow; +			//col += spec.rgb; +		} +	}	 +	 +	 +	 +	 + +	if (envIntensity > 0.0) +	{  		vec3 ref = reflect(normalize(pos), norm);  		//project from point pos in direction ref to plane proj_p, proj_n @@ -239,8 +318,9 @@ void main()  			{  				stc.xy /= stc.w; -				float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); +				float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0); +				//stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);  				stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);  				if (stc.x < 1.0 && @@ -248,8 +328,7 @@ void main()  					stc.x > 0.0 &&  					stc.y > 0.0)  				{ -					vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); -					col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb*shadow; +					col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*shadow*spec.rgb;										  				}  			}  		} diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 9df9d75905..4fe2f1551e 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -38,7 +38,6 @@ uniform sampler2DRect lightMap;  uniform sampler2DRect depthMap;  uniform samplerCube environmentMap;  uniform sampler2D	  lightFunc; -uniform vec3 gi_quad;  uniform float blur_size;  uniform float blur_fidelity; @@ -60,16 +59,13 @@ uniform float density_multiplier;  uniform float distance_multiplier;  uniform float max_y;  uniform vec4 glow; +uniform float global_gamma;  uniform float scene_light_strength;  uniform mat3 env_mat;  uniform vec4 shadow_clip;  uniform mat3 ssao_effect_mat; -uniform mat4 inv_proj; -uniform vec2 screen_res; -  uniform vec3 sun_dir; -  VARYING vec2 vary_fragcoord;  vec3 vary_PositionEye; @@ -79,6 +75,43 @@ vec3 vary_AmblitColor;  vec3 vary_AdditiveColor;  vec3 vary_AtmosAttenuation; +uniform mat4 inv_proj; +uniform vec2 screen_res; + +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif +  vec4 getPosition_d(vec2 pos_screen, float depth)  {  	vec2 sc = pos_screen.xy*2.0; @@ -118,7 +151,6 @@ vec3 getAtmosAttenuation()  	return vary_AtmosAttenuation;  } -  void setPositionEye(vec3 v)  {  	vary_PositionEye = v; @@ -222,9 +254,9 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {  		  + tmpAmbient)));  	//brightness of surface both sunlight and ambient -	setSunlitColor(vec3(sunlight * .5)); -	setAmblitColor(vec3(tmpAmbient * .25)); -	setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); +	setSunlitColor(pow(vec3(sunlight * .5), vec3(global_gamma)) * global_gamma); +	setAmblitColor(pow(vec3(tmpAmbient * .25), vec3(global_gamma)) * global_gamma); +	setAdditiveColor(pow(getAdditiveColor() * vec3(1.0 - temp1), vec3(global_gamma)) * global_gamma);  }  vec3 atmosLighting(vec3 light) @@ -239,6 +271,15 @@ vec3 atmosTransport(vec3 light) {  	light += getAdditiveColor() * 2.0;  	return light;  } + +vec3 fullbrightAtmosTransport(vec3 light) { +	float brightness = dot(light.rgb, vec3(0.33333)); + +	return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness); +} + + +  vec3 atmosGetDiffuseSunlightColor()  {  	return getSunlitColor(); @@ -273,22 +314,28 @@ vec3 scaleSoftClip(vec3 light)  	return light;  } + +vec3 fullbrightScaleSoftClip(vec3 light) +{ +	//soft clip effect: +	return light; +} +  void main()   {  	vec2 tc = vary_fragcoord.xy;  	float depth = texture2DRect(depthMap, tc.xy).r;  	vec3 pos = getPosition_d(tc, depth).xyz; -	vec3 norm = texture2DRect(normalMap, tc).xyz; -	norm = (norm.xyz-0.5)*2.0; // unpack norm +	vec4 norm = texture2DRect(normalMap, tc); +	float envIntensity = norm.z; +	norm.xyz = decode_normal(norm.xy); // unpack norm  	float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); -	 -	vec4 diffuse = texture2DRect(diffuseRect, tc); +	vec4 diffuse = texture2DRect(diffuseRect, tc); +	  	vec3 col;  	float bloom = 0.0; - -	if (diffuse.a < 0.9)  	{  		vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); @@ -299,39 +346,62 @@ void main()  		calcAtmospherics(pos.xyz, ambocc);  		col = atmosAmbient(vec3(0)); -		col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a)); +		float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); +		ambient *= 0.5; +		ambient *= ambient; +		ambient = (1.0-ambient); + +		col.rgb *= ambient; + +		col += atmosAffectDirectionalLight(max(min(da, scol) * 2.6, 0.0));  		col *= diffuse.rgb; +		vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); +  		if (spec.a > 0.0) // specular reflection  		{  			// the old infinite-sky shiny reflection  			// -			vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); +			  			float sa = dot(refnormpersp, sun_dir.xyz); -			vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(6 * texture2D(lightFunc, vec2(sa, spec.a)).r); - +			vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(texture2D(lightFunc, vec2(sa, spec.a)).r); +			  			// add the two types of shiny together  			vec3 spec_contrib = dumbshiny * spec.rgb; -			bloom = dot(spec_contrib, spec_contrib) / 4; +			bloom = dot(spec_contrib, spec_contrib) / 6;  			col += spec_contrib; - -			//add environmentmap -			vec3 env_vec = env_mat * refnormpersp; -			col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb,  -				max(spec.a-diffuse.a*2.0, 0.0));   		} +	 +		 +		col = mix(col.rgb, pow(diffuse.rgb, vec3(1.0/2.2)), diffuse.a); +		 +		 +		if (envIntensity > 0.0) +		{ //add environmentmap +			vec3 env_vec = env_mat * refnormpersp; -		col = atmosLighting(col); -		col = scaleSoftClip(col); +			float exponent = mix(2.2, 1.0, diffuse.a); +			vec3 refcol = pow(textureCube(environmentMap, env_vec).rgb, vec3(exponent))*exponent; -		col = mix(col, diffuse.rgb, diffuse.a); -	} -	else -	{ -		col = diffuse.rgb; +			col = mix(col.rgb, refcol,  +				envIntensity);   + +		} + +		float exponent = mix(1.0, 2.2, diffuse.a); +		col = pow(col, vec3(exponent)); +				 +		if (norm.w < 0.5) +		{ +			col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a); +			col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a); +		} + +		//col = vec3(1,0,1); +		//col.g = envIntensity;  	} -		 +	  	frag_color.rgb = col;  	frag_color.a = bloom;  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index 6d6ad6d565..bdb713d682 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -39,6 +39,7 @@ uniform samplerCube environmentMap;  uniform sampler2DRect lightMap;  uniform sampler2D noiseMap;  uniform sampler2D projectionMap; +uniform sampler2D lightFunc;  uniform mat4 proj_mat; //screen space to light space  uniform float proj_near; //near clip for projection @@ -67,9 +68,49 @@ uniform vec2 screen_res;  uniform mat4 inv_proj; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif + +vec4 correctWithGamma(vec4 col) +{ +	return vec4(pow(col.rgb, vec3(2.2)), col.a); +} +  vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); +	ret = correctWithGamma(ret);  	vec2 dist = tc-vec2(0.5); @@ -85,6 +126,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); +	ret = correctWithGamma(ret);  	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); @@ -102,6 +144,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)  vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); +	ret = correctWithGamma(ret);  	vec2 dist = tc-vec2(0.5); @@ -154,7 +197,8 @@ void main()  	}  	vec3 norm = texture2DRect(normalMap, frag.xy).xyz; -	norm = (norm.xyz-0.5)*2.0; // unpack norm +	float envIntensity = norm.z; +	norm = decode_normal(norm.xy);  	norm = normalize(norm);  	float l_dist = -dot(lv, proj_n); @@ -169,6 +213,7 @@ void main()  	float fa = falloff+1.0;  	float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); +	dist_atten = pow(dist_atten, 2.2) * 2.2;  	if (dist_atten <= 0.0)  	{  		discard; @@ -182,6 +227,10 @@ void main()  	vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; +	vec4 spec = texture2DRect(specularRect, frag.xy); + +	vec3 dlit = vec3(0, 0, 0); +  	float noise = texture2D(noiseMap, frag.xy/128.0).b;  	if (proj_tc.z > 0.0 &&  		proj_tc.x < 1.0 && @@ -189,21 +238,21 @@ void main()  		proj_tc.x > 0.0 &&  		proj_tc.y > 0.0)  	{ -		float lit = 0.0;  		float amb_da = proj_ambiance; +		float lit = 0.0;  		if (da > 0.0)  		{ +			lit = da * dist_atten * noise; +  			float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);  			float lod = diff * proj_lod;  			vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); -			vec3 lcol = color.rgb * plcol.rgb * plcol.a; -			 -			lit = da * dist_atten * noise; +			dlit = color.rgb * plcol.rgb * plcol.a; -			col = lcol*lit*diff_tex*shadow; +			col = dlit*lit*diff_tex*shadow;  			amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;  		} @@ -219,10 +268,37 @@ void main()  		col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;  	} -	 -	vec4 spec = texture2DRect(specularRect, frag.xy); +  	if (spec.a > 0.0)  	{ +		dlit *= min(da*6.0, 1.0) * dist_atten; +		vec3 npos = -normalize(pos); + +		//vec3 ref = dot(pos+lv, norm); +		vec3 h = normalize(lv+npos); +		float nh = dot(norm, h); +		float nv = dot(norm, npos); +		float vh = dot(npos, h); +		float sa = nh; +		float fres = pow(1 - dot(h, npos), 5)*0.4+0.5; + +		float gtdenom = 2 * nh; +		float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); +								 +		if (nh > 0.0) +		{ +			float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); +			col += dlit*scol*spec.rgb*shadow; +			//col += spec.rgb; +		} +	}	 +	 +	 +	 +	 + +	if (envIntensity > 0.0) +	{  		vec3 ref = reflect(normalize(pos), norm);  		//project from point pos in direction ref to plane proj_p, proj_n @@ -239,8 +315,9 @@ void main()  			{  				stc.xy /= stc.w; -				float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); +				float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0); +				//stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);  				stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);  				if (stc.x < 1.0 && @@ -248,8 +325,7 @@ void main()  					stc.x > 0.0 &&  					stc.y > 0.0)  				{ -					vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); -					col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb*shadow; +					col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*shadow*spec.rgb;										  				}  			}  		} diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index 890486c4b1..7b09dd29dd 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -65,6 +65,40 @@ uniform float shadow_offset;  uniform float spot_shadow_bias;  uniform float spot_shadow_offset; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif +  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).r; @@ -125,11 +159,9 @@ void main()  	vec4 pos = getPosition(pos_screen); -	vec4 nmap4 = texture2DRect(normalMap, pos_screen); -	nmap4 = vec4((nmap4.xyz-0.5)*2.0,nmap4.w); // unpack norm -	float displace = nmap4.w; -	vec3 norm = nmap4.xyz; -	 +	vec3 norm = texture2DRect(normalMap, pos_screen).xyz; +	norm = decode_normal(norm.xy); // unpack norm +		  	/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL  	{  		frag_color = vec4(0.0); // doesn't matter @@ -138,8 +170,8 @@ void main()  	float shadow = 0.0;  	float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz)); - -	vec3 shadow_pos = pos.xyz + displace*norm; +	 +	vec3 shadow_pos = pos.xyz;  	vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);  	vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0); diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 2dcd3d656f..01e34ed792 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -66,6 +66,40 @@ uniform float shadow_offset;  uniform float spot_shadow_bias;  uniform float spot_shadow_offset; +#ifdef SINGLE_FP_ONLY +vec2 encode_normal(vec3 n) +{ +	vec2 sn; +	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); +	return sn; +} + +vec3 decode_normal (vec2 enc) +{ +	vec3 n; +	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); +	n.z = sqrt(1.0f - dot(n.xy,n.xy)); +	return n; +} +#else +vec2 encode_normal(vec3 n) +{ +	float f = sqrt(8 * n.z + 8); +	return n.xy / f + 0.5; +} + +vec3 decode_normal (vec2 enc) +{ +    vec2 fenc = enc*4-2; +    float f = dot(fenc,fenc); +    float g = sqrt(1-f/4); +    vec3 n; +    n.xy = fenc*g; +    n.z = 1-f/2; +    return n; +} +#endif +  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).r; @@ -186,11 +220,9 @@ void main()  	vec4 pos = getPosition(pos_screen); -	vec4 nmap4 = texture2DRect(normalMap, pos_screen); -	nmap4 = vec4((nmap4.xyz-0.5)*2.0,nmap4.w); // unpack norm -	float displace = nmap4.w; -	vec3 norm = nmap4.xyz; -	 +	vec3 norm = texture2DRect(normalMap, pos_screen).xyz; +	norm = decode_normal(norm.xy); // unpack norm +		  	/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL  	{  		frag_color = vec4(0.0); // doesn't matter @@ -199,8 +231,8 @@ void main()  	float shadow = 0.0;  	float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz)); - -	vec3 shadow_pos = pos.xyz + displace*norm; +	 +	vec3 shadow_pos = pos.xyz;  	vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);  	vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0); diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl index da3d922017..8fd06c7e2f 100755 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl @@ -54,6 +54,7 @@ uniform float density_multiplier;  uniform float distance_multiplier;  uniform float max_y;  uniform vec4 glow; +uniform float global_gamma;  void calcAtmospherics(vec3 inPositionEye) { @@ -129,11 +130,11 @@ void calcAtmospherics(vec3 inPositionEye) {  		vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)  	  + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x  		  + tmpAmbient))); - +	  	//brightness of surface both sunlight and ambient -	setSunlitColor(vec3(sunlight * .5)); -	setAmblitColor(vec3(tmpAmbient * .25)); -	setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); +	setSunlitColor(pow(vec3(sunlight * .5), vec3(global_gamma)) * global_gamma); +	setAmblitColor(pow(vec3(tmpAmbient * .25), vec3(global_gamma)) * global_gamma); +	setAdditiveColor(pow(getAdditiveColor() * vec3(1.0 - temp1), vec3(global_gamma)) * global_gamma);  	// vary_SunlitColor = vec3(0);  	// vary_AmblitColor = vec3(0); diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index 284e9c44b2..e5b385f4aa 100755 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -1084,8 +1084,7 @@           scale="0 0 .5" />        </param_skeleton>      </param> - -    <param +                          <param       id="11001"       group="0"       name="Hover" @@ -12308,7 +12307,7 @@ render_pass="bump">  	 <param_driver />      </param> -    <param +  <param       id="11000"       group="0"       name="AppearanceMessage_Version" diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 861991f3c2..e158dc7505 100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -65,10 +65,10 @@ using namespace LLAvatarAppearanceDefines;  void wear_and_edit_cb(const LLUUID& inv_item)  {  	if (inv_item.isNull()) return; - +	  	// Request editing the item after it gets worn.  	gAgentWearables.requestEditingWearable(inv_item); - +	  	// Wear it.  	LLAppearanceMgr::instance().wearItemOnAvatar(inv_item);  } @@ -181,7 +181,7 @@ void LLAgentWearables::initClass()  }  void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar) -{  +{  	llassert(avatar);  	avatar->outputRezTiming("Sending wearables request");  	sendAgentWearablesRequest(); diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp index 2d2d730396..8b6b6db525 100755 --- a/indra/newview/llagentwearablesfetch.cpp +++ b/indra/newview/llagentwearablesfetch.cpp @@ -36,44 +36,44 @@  void order_my_outfits_cb() -{ -	if (!LLApp::isRunning())  	{ -		llwarns << "called during shutdown, skipping" << llendl; -		return; -	} +		if (!LLApp::isRunning()) +		{ +			llwarns << "called during shutdown, skipping" << llendl; +			return; +		} -	const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); -	if (my_outfits_id.isNull()) return; +		const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); +		if (my_outfits_id.isNull()) return; -	LLInventoryModel::cat_array_t* cats; -	LLInventoryModel::item_array_t* items; -	gInventory.getDirectDescendentsOf(my_outfits_id, cats, items); -	if (!cats) return; +		LLInventoryModel::cat_array_t* cats; +		LLInventoryModel::item_array_t* items; +		gInventory.getDirectDescendentsOf(my_outfits_id, cats, items); +		if (!cats) return; -	//My Outfits should at least contain saved initial outfit and one another outfit -	if (cats->size() < 2) -	{ -		llwarning("My Outfits category was not populated properly", 0); -		return; -	} +		//My Outfits should at least contain saved initial outfit and one another outfit +		if (cats->size() < 2) +		{ +			llwarning("My Outfits category was not populated properly", 0); +			return; +		} -	llinfos << "Starting updating My Outfits with wearables ordering information" << llendl; +		llinfos << "Starting updating My Outfits with wearables ordering information" << llendl; -	for (LLInventoryModel::cat_array_t::iterator outfit_iter = cats->begin(); -		 outfit_iter != cats->end(); ++outfit_iter) -	{ -		const LLUUID& cat_id = (*outfit_iter)->getUUID(); -		if (cat_id.isNull()) continue; +		for (LLInventoryModel::cat_array_t::iterator outfit_iter = cats->begin(); +			outfit_iter != cats->end(); ++outfit_iter) +		{ +			const LLUUID& cat_id = (*outfit_iter)->getUUID(); +			if (cat_id.isNull()) continue; -		// saved initial outfit already contains wearables ordering information -		if (cat_id == LLAppearanceMgr::getInstance()->getBaseOutfitUUID()) continue; +			// saved initial outfit already contains wearables ordering information +			if (cat_id == LLAppearanceMgr::getInstance()->getBaseOutfitUUID()) continue; -		LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(cat_id); -	} +			LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(cat_id); +		} -	llinfos << "Finished updating My Outfits with wearables ordering information" << llendl; -} +		llinfos << "Finished updating My Outfits with wearables ordering information" << llendl; +	}  LLInitialWearablesFetch::LLInitialWearablesFetch(const LLUUID& cof_id) :  	LLInventoryFetchDescendentsObserver(cof_id) diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 652f199e28..fd9236c8b3 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -196,7 +196,7 @@ public:  		LLEventTimer(5.0)  	{  		if (!mTrackingPhase.empty()) -		{ +	{  			selfStartPhase(mTrackingPhase);  		}  	} @@ -212,23 +212,23 @@ public:  			addItem(item->getUUID());  		}  	} - +		  	// Request or re-request operation for specified item.  	void addItem(const LLUUID& item_id)  	{  		LL_DEBUGS("Avatar") << "item_id " << item_id << llendl; -		 +  		if (!requestOperation(item_id))  		{  			LL_DEBUGS("Avatar") << "item_id " << item_id << " requestOperation false, skipping" << llendl;  			return; -		} +	}  		mPendingRequests++;  		// On a re-request, this will reset the timer.  		mWaitTimes[item_id] = LLTimer();  		if (mRetryCounts.find(item_id) == mRetryCounts.end()) -		{ +	{  			mRetryCounts[item_id] = 0;  		}  		else @@ -242,7 +242,7 @@ public:  	void onOp(const LLUUID& src_id, const LLUUID& dst_id, LLTimer timestamp)  	{  		if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateLateOpRate")) -		{ +	{  			llwarns << "Simulating late operation by punting handling to later" << llendl;  			doAfterInterval(boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,src_id,dst_id,timestamp),  							mRetryAfter); @@ -265,12 +265,12 @@ public:  			onCompletionOrFailure();  		}  	} - +		  	void onCompletionOrFailure()  	{  		assert (!mCompletionOrFailureCalled);  		mCompletionOrFailureCalled = true; -		 +  		// Will never call onCompletion() if any item has been flagged as  		// a failure - otherwise could wind up with corrupted  		// outfit, involuntary nudity, etc. @@ -288,7 +288,7 @@ public:  			onFailure();  		}  	} - +		  	void onFailure()  	{  		llinfos << "failed" << llendl; @@ -300,7 +300,7 @@ public:  		llinfos << "done" << llendl;  		mOnCompletionFunc();  	} -	 +  	// virtual  	// Will be deleted after returning true - only safe to do this if all callbacks have fired.  	BOOL tick() @@ -313,7 +313,7 @@ public:  		// been serviced, since it will result in this object being  		// deleted.  		bool all_done = (mPendingRequests==0); - +		  		if (!mWaitTimes.empty())  		{  			llwarns << "still waiting on " << mWaitTimes.size() << " items" << llendl; @@ -323,20 +323,20 @@ public:  				// Use a copy of iterator because it may be erased/invalidated.  				std::map<LLUUID,LLTimer>::iterator curr_it = it;  				++it; -				 +  				F32 time_waited = curr_it->second.getElapsedTimeF32();  				S32 retries = mRetryCounts[curr_it->first];  				if (time_waited > mRetryAfter)  				{  					if (retries < mMaxRetries) -					{ +		{  						LL_DEBUGS("Avatar") << "Waited " << time_waited <<  							" for " << curr_it->first << ", retrying" << llendl;  						mRetryCount++;  						addItem(curr_it->first); -					} -					else -					{ +		} +		else +		{  						llwarns << "Giving up on " << curr_it->first << " after too many retries" << llendl;  						mWaitTimes.erase(curr_it);  						mFailCount++; @@ -347,8 +347,8 @@ public:  					onCompletionOrFailure();  				} -			}  		} +	}  		return all_done;  	} @@ -360,7 +360,7 @@ public:  		LL_DEBUGS("Avatar") << "Times: n " << mTimeStats.getCount() << " min " << mTimeStats.getMinValue() << " max " << mTimeStats.getMaxValue() << llendl;  		LL_DEBUGS("Avatar") << "Mean " << mTimeStats.getMean() << " stddev " << mTimeStats.getStdDev() << llendl;  	} -	 +  	virtual ~LLCallAfterInventoryBatchMgr()  	{  		LL_DEBUGS("Avatar") << "deleting" << llendl; @@ -397,9 +397,9 @@ public:  	{  		addItems(src_items);  	} -	 +  	virtual bool requestOperation(const LLUUID& item_id) -	{ +		{  		LLViewerInventoryItem *item = gInventory.getItem(item_id);  		llassert(item);  		LL_DEBUGS("Avatar") << "copying item " << item_id << llendl; @@ -479,9 +479,9 @@ public:  			LLAppearanceMgr::instance().purgeBaseOutfitLink(cof);  			if (catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT) -			{ +	{  				if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate")) -				{ +		{  					LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << llendl;  					return true;  				} @@ -841,69 +841,69 @@ bool LLWearableHoldingPattern::pollFetchCompletion()  void recovered_item_link_cb(const LLUUID& item_id, LLWearableType::EType type, LLViewerWearable *wearable, LLWearableHoldingPattern* holder)  {  	if (!holder->isMostRecent()) -	{ -		llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; -		// runway skip here? -	} +		{ +			llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +			// runway skip here? +		}  	llinfos << "Recovered item link for type " << type << llendl;  	holder->eraseTypeToLink(type); -	// Add wearable to FoundData for actual wearing -	LLViewerInventoryItem *item = gInventory.getItem(item_id); -	LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL; +		// Add wearable to FoundData for actual wearing +		LLViewerInventoryItem *item = gInventory.getItem(item_id); +		LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL; -	if (linked_item) -	{ -		gInventory.addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID()); -			 -		if (item) +		if (linked_item)  		{ -			LLFoundData found(linked_item->getUUID(), -							  linked_item->getAssetUUID(), -							  linked_item->getName(), -							  linked_item->getType(), -							  linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID, -							  true // is replacement -				); +			gInventory.addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID()); +			 +			if (item) +			{ +				LLFoundData found(linked_item->getUUID(), +								  linked_item->getAssetUUID(), +								  linked_item->getName(), +								  linked_item->getType(), +								  linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID, +								  true // is replacement +					);  			found.mWearable = wearable;  			holder->getFoundList().push_front(found); +			} +			else +			{ +				llwarns << self_av_string() << "inventory item not found for recovered wearable" << llendl; +			}  		}  		else  		{ -			llwarns << self_av_string() << "inventory item not found for recovered wearable" << llendl; +			llwarns << self_av_string() << "inventory link not found for recovered wearable" << llendl;  		}  	} -	else -	{ -		llwarns << self_av_string() << "inventory link not found for recovered wearable" << llendl; -	} -}  void recovered_item_cb(const LLUUID& item_id, LLWearableType::EType type, LLViewerWearable *wearable, LLWearableHoldingPattern* holder)  {  	if (!holder->isMostRecent()) -	{ -		// runway skip here? -		llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; -	} +		{ +			// runway skip here? +			llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; +		}  	LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << type << LL_ENDL; -	LLViewerInventoryItem *itemp = gInventory.getItem(item_id); +		LLViewerInventoryItem *itemp = gInventory.getItem(item_id);  	wearable->setItemID(item_id);  	LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_link_cb,_1,type,wearable,holder));  	holder->eraseTypeToRecover(type); -	llassert(itemp); -	if (itemp) -	{ -		link_inventory_item( gAgent.getID(), -							 item_id, -							 LLAppearanceMgr::instance().getCOF(), -							 itemp->getName(), -							 itemp->getDescription(), -							 LLAssetType::AT_LINK, -							 cb); +		llassert(itemp); +		if (itemp) +		{ +			link_inventory_item( gAgent.getID(), +					     item_id, +					     LLAppearanceMgr::instance().getCOF(), +					     itemp->getName(), +						 itemp->getDescription(), +					     LLAssetType::AT_LINK, +					     cb); +		}  	} -}  void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type)  { @@ -1290,7 +1290,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up  	if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID()))  	{  		LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(wear_on_avatar_cb,_1,replace)); -		copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(), cb); +		copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(),cb);  		return false;  	}   	else if (!gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getRootFolderID())) @@ -1680,8 +1680,8 @@ void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_lin  			}  			else  			{ -				gInventory.purgeObject(item->getUUID()); -			} +			gInventory.purgeObject(item->getUUID()); +		}  #else  			gInventory.purgeObject(item->getUUID());  		} @@ -2267,7 +2267,7 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego  	// Avoid unintentionally overwriting old wearables.  We have to do  	// this up front to avoid having to deal with the case of multiple  	// wearables being dirty. -	if (!category) return; +	if(!category) return;  	if ( !LLInventoryCallbackManager::is_instantiated() )  	{ @@ -2388,7 +2388,7 @@ void LLAppearanceMgr::addCOFItemLink(const LLUUID &item_id, bool do_update, LLPo  }  void modified_cof_cb(const LLUUID& inv_item) -{ +{		  	LLAppearanceMgr::instance().updateAppearanceFromCOF();  	// Start editing the item if previously requested. @@ -3237,7 +3237,7 @@ void LLAppearanceMgr::requestServerAppearanceUpdate(LLCurl::ResponderPtr respond  		llwarns << "No cap for UpdateAvatarAppearance." << llendl;  		return;  	} -	 +  	LLSD body;  	S32 cof_version = getCOFVersion();  	if (gSavedSettings.getBOOL("DebugAvatarExperimentalServerAppearanceUpdate")) @@ -3253,7 +3253,7 @@ void LLAppearanceMgr::requestServerAppearanceUpdate(LLCurl::ResponderPtr respond  		}  	}  	LL_DEBUGS("Avatar") << "request url " << url << " my_cof_version " << cof_version << llendl; -	 +  	//LLCurl::ResponderPtr responder_ptr;  	if (!responder_ptr.get())  	{ @@ -3347,33 +3347,33 @@ std::string LLAppearanceMgr::getAppearanceServiceURL() const  }  void show_created_outfit(LLUUID& folder_id, bool show_panel = true) -{ -	if (!LLApp::isRunning())  	{ -		llwarns << "called during shutdown, skipping" << llendl; -		return; -	} -	 -	LLSD key; -	 +		if (!LLApp::isRunning()) +		{ +			llwarns << "called during shutdown, skipping" << llendl; +			return; +		} + +		LLSD key; +		  	//EXT-7727. For new accounts inventory callback is created during login process  	// and may be processed after login process is finished  	if (show_panel) -	{ -		LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key); -		 -	} -	LLOutfitsList *outfits_list = -		dynamic_cast<LLOutfitsList*>(LLFloaterSidePanelContainer::getPanel("appearance", "outfitslist_tab")); -	if (outfits_list) -	{ +		{ +			LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key); + +		} +		LLOutfitsList *outfits_list = +			dynamic_cast<LLOutfitsList*>(LLFloaterSidePanelContainer::getPanel("appearance", "outfitslist_tab")); +		if (outfits_list) +		{  		outfits_list->setSelectedOutfitByUUID(folder_id); +		} + +		LLAppearanceMgr::getInstance()->updateIsDirty(); +		gAgentWearables.notifyLoadingFinished(); // New outfit is saved. +		LLAppearanceMgr::getInstance()->updatePanelOutfitName("");  	} -	 -	LLAppearanceMgr::getInstance()->updateIsDirty(); -	gAgentWearables.notifyLoadingFinished(); // New outfit is saved. -	LLAppearanceMgr::getInstance()->updatePanelOutfitName(""); -}  LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel)  { @@ -3415,13 +3415,13 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)  		llwarns << "called with empty list, nothing to do" << llendl;  	}  	for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it) -	{ +			{  		const LLUUID& id_to_remove = *it;  		const LLUUID& linked_item_id = gInventory.getLinkedItemID(id_to_remove);  		removeCOFItemLinks(linked_item_id); -	} +			}  	updateAppearanceFromCOF(); -} +	}  void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)  { diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 8c51bd4198..733c9cc9df 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -129,9 +129,9 @@  #if LL_WINDOWS -#	include <share.h> // For _SH_DENYWR in initMarkerFile +#	include <share.h> // For _SH_DENYWR in processMarkerFiles  #else -#   include <sys/file.h> // For initMarkerFile support +#   include <sys/file.h> // For processMarkerFiles  #endif  #include "llapr.h" @@ -601,7 +601,8 @@ static void settings_to_globals()  static void settings_modify()  {  	LLRenderTarget::sUseFBO				= gSavedSettings.getBOOL("RenderDeferred"); -	LLPipeline::sRenderDeferred			= gSavedSettings.getBOOL("RenderDeferred"); +	LLPipeline::sRenderBump				= gSavedSettings.getBOOL("RenderObjectBump"); +	LLPipeline::sRenderDeferred		= LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");  	LLVOAvatar::sUseImpostors			= gSavedSettings.getBOOL("RenderUseImpostors");  	LLVOSurfacePatch::sLODFactor		= gSavedSettings.getF32("RenderTerrainLODFactor");  	LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4] @@ -742,7 +743,9 @@ bool LLAppViewer::init()  	// this allows simple skinned file lookups to work  	gDirUtilp->setSkinFolder("default", "en"); -	initLogging(); +	initLoggingAndGetLastDuration(); +	 +	processMarkerFiles();  	//  	// OK to write stuff to logs now, we've now crash reported if necessary @@ -766,7 +769,7 @@ bool LLAppViewer::init()  	logdir += gDirUtilp->getDirDelimiter();  	setMiniDumpDir(logdir); -	// Although initLogging() is the right place to mess with +	// Although initLoggingAndGetLastDuration() is the right place to mess with  	// setFatalFunction(), we can't query gSavedSettings until after  	// initConfiguration().  	S32 rc(gSavedSettings.getS32("QAModeTermCode")); @@ -1083,9 +1086,9 @@ bool LLAppViewer::init()  	if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion())  	{  		if (gGLManager.mIsIntel) -	{ -		LLNotificationsUtil::add("IntelOldDriver"); -	} +		{ +			LLNotificationsUtil::add("IntelOldDriver"); +		}  		else if (gGLManager.mIsNVIDIA)  		{  			LLNotificationsUtil::add("NVIDIAOldDriver"); @@ -1815,6 +1818,8 @@ bool LLAppViewer::cleanup()  	llinfos << "Cleaning up Objects" << llendflush;  	LLViewerObject::cleanupVOClasses(); + +	LLAvatarAppearance::cleanupClass();  	LLAvatarAppearance::cleanupClass(); @@ -2141,7 +2146,7 @@ void errorCallback(const std::string &error_string)  	LLError::crashAndLoop(error_string);  } -void LLAppViewer::initLogging() +void LLAppViewer::initLoggingAndGetLastDuration()  {  	//  	// Set up logging defaults for the viewer @@ -2166,24 +2171,35 @@ void LLAppViewer::initLogging()  	std::string start_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, START_MARKER_FILE_NAME);  	llstat start_marker_stat;  	llstat log_file_stat; -	if (   0 == LLFile::stat(start_marker_file_name, &start_marker_stat) -		&& 0 == LLFile::stat(log_file, &log_file_stat) -		) +	std::ostringstream duration_log_stream; // can't log yet, so save any message for when we can below +	int start_stat_result = LLFile::stat(start_marker_file_name, &start_marker_stat); +	int log_stat_result = LLFile::stat(log_file, &log_file_stat); +	if ( 0 == start_stat_result && 0 == log_stat_result )  	{  		int elapsed_seconds = log_file_stat.st_ctime - start_marker_stat.st_ctime;  		// only report a last run time if the last viewer was the same version  		// because this stat will be counted against this version -		gLastExecDuration = markerIsSameVersion(start_marker_file_name) ? elapsed_seconds : -1; +		if ( markerIsSameVersion(start_marker_file_name) ) +		{ +			gLastExecDuration = elapsed_seconds; +		} +		else +		{ +			duration_log_stream << "start marker from some other version; duration is not reported"; +			gLastExecDuration = -1; +		}  	}  	else  	{  		// at least one of the LLFile::stat calls failed, so we can't compute the run time +		duration_log_stream << "duration stat failure; start: "<< start_stat_result << " log: " << log_stat_result;  		gLastExecDuration = -1; // unknown  	} +	std::string duration_log_msg(duration_log_stream.str());  	// Create a new start marker file for comparison with log file time for the next run  	LLAPRFile start_marker_file ; -	start_marker_file.open(start_marker_file_name, LL_APR_W); +	start_marker_file.open(start_marker_file_name, LL_APR_WB);  	if (start_marker_file.getFileHandle())  	{  		recordMarkerVersion(start_marker_file); @@ -2195,6 +2211,10 @@ void LLAppViewer::initLogging()  	// Set the log file to SecondLife.log  	LLError::logToFile(log_file); +	if (!duration_log_msg.empty()) +	{ +		LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL; +	}  }  bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, @@ -2772,7 +2792,6 @@ bool LLAppViewer::initConfiguration()  	//  	// Check for another instance of the app running  	// -	mSecondInstance = anotherInstanceRunning();  	if (mSecondInstance && !gSavedSettings.getBOOL("AllowMultipleViewers"))  	{  		std::ostringstream msg; @@ -2784,8 +2803,6 @@ bool LLAppViewer::initConfiguration()  		return false;  	} -	initMarkerFile(); -		  	if (mSecondInstance)  	{  		// This is the second instance of SL. Turn off voice support, @@ -3005,7 +3022,7 @@ namespace {  			relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL"));  			substitutions["INFO_URL"] = relnotes_url.getString();  		} - +		  		LLNotificationsUtil::add(notification_name, substitutions, LLSD(), apply_callback);  	} @@ -3471,20 +3488,20 @@ void LLAppViewer::handleViewerCrash()  	//we're already in a crash situation	  	if (gDirUtilp)  	{ -		std::string crash_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, +		std::string crash_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,  																	 gLLErrorActivated  																	 ? LLERROR_MARKER_FILE_NAME  																	 : ERROR_MARKER_FILE_NAME); -		LLAPRFile crash_file ; -		crash_file.open(crash_file_name, LL_APR_W); -		if (crash_file.getFileHandle()) +		LLAPRFile crash_marker_file ; +		crash_marker_file.open(crash_marker_file_name, LL_APR_WB); +		if (crash_marker_file.getFileHandle())  		{ -			LL_INFOS("MarkerFile") << "Created crash marker file " << crash_file_name << LL_ENDL; -			recordMarkerVersion(crash_file); +			LL_INFOS("MarkerFile") << "Created crash marker file " << crash_marker_file_name << LL_ENDL; +			recordMarkerVersion(crash_marker_file);  		}  		else  		{ -			LL_WARNS("MarkerFile") << "Cannot create error marker file " << crash_file_name << LL_ENDL; +			LL_WARNS("MarkerFile") << "Cannot create error marker file " << crash_marker_file_name << LL_ENDL;  		}		  	}  	else @@ -3536,38 +3553,6 @@ void LLAppViewer::handleViewerCrash()  	return;  } -bool LLAppViewer::anotherInstanceRunning() -{ -	// We create a marker file when the program starts and remove the file when it finishes. -	// If the file is currently locked, that means another process is already running. - -	std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, MARKER_FILE_NAME); -	LL_DEBUGS("MarkerFile") << "Checking marker file '"<< marker_file << "' for lock..." << LL_ENDL; - -	//Freeze case checks -	if (LLAPRFile::isExist(marker_file, NULL, LL_APR_RB)) -	{ -		// File exists, try opening with write permissions -		LLAPRFile outfile ; -		outfile.open(marker_file, LL_APR_AB); -		apr_file_t* fMarker = outfile.getFileHandle() ;  -		if (!fMarker) -		{ -			// Another instance is running. Skip the rest of these operations. -			LL_INFOS("MarkerFile") << "Marker file is locked." << LL_ENDL; -			return true; -		} -		if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS) //flock(fileno(fMarker), LOCK_EX | LOCK_NB) == -1) -		{ -			LL_INFOS("MarkerFile") << "Marker file is locked." << LL_ENDL; -			return true; -		} -		// No other instances; we'll lock this file now & delete on quit.		 -	} -	LL_DEBUGS("MarkerFile") << "Marker file isn't locked." << LL_ENDL; -	return false; -} -  // static  void LLAppViewer::recordMarkerVersion(LLAPRFile& marker_file)   {		 @@ -3612,14 +3597,8 @@ bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const  	return sameVersion;  } -void LLAppViewer::initMarkerFile() +void LLAppViewer::processMarkerFiles()  { -	//First, check for the existence of other files. -	//There are marker files for two different types of crashes -	 -	mMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,MARKER_FILE_NAME); -	LL_DEBUGS("MarkerFile") << "Checking marker file for lock..." << LL_ENDL; -  	//We've got 4 things to test for here  	// - Other Process Running (SecondLife.exec_marker present, locked)  	// - Freeze (SecondLife.exec_marker present, not locked) @@ -3627,29 +3606,92 @@ void LLAppViewer::initMarkerFile()  	// - Other Crash (SecondLife.error_marker present)  	// These checks should also remove these files for the last 2 cases if they currently exist -	//LLError/Error checks. Only one of these should ever happen at a time. -	std::string logout_marker_file =  gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOGOUT_MARKER_FILE_NAME); -	std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME); -	std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME); +	bool marker_is_same_version = true; +	// first, look for the marker created at startup and deleted on a clean exit +	mMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,MARKER_FILE_NAME); +	if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB)) +	{ +		// File exists... +		// first, read it to see if it was created by the same version (we need this later) +		marker_is_same_version = markerIsSameVersion(mMarkerFileName); -	if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB) && !anotherInstanceRunning()) +		// now test to see if this file is locked by a running process (try to open for write) +		LL_DEBUGS("MarkerFile") << "Checking exec marker file for lock..." << LL_ENDL; +		mMarkerFile.open(mMarkerFileName, LL_APR_WB); +		apr_file_t* fMarker = mMarkerFile.getFileHandle() ;  +		if (!fMarker) +		{ +			LL_INFOS("MarkerFile") << "Exec marker file open failed - assume it is locked." << LL_ENDL; +			mSecondInstance = true; // lock means that instance is running. +		} +		else +		{ +			// We were able to open it, now try to lock it ourselves... +			if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS) +			{ +				LL_WARNS_ONCE("MarkerFile") << "Locking exec marker failed." << LL_ENDL; +				mSecondInstance = true; // lost a race? be conservative +			} +			else +			{ +				// No other instances; we've locked this file now, so record our version; delete on quit.		 +				recordMarkerVersion(mMarkerFile); +				LL_DEBUGS("MarkerFile") << "Exec marker file existed but was not locked; rewritten." << LL_ENDL; +			} +		} + +		if (mSecondInstance)  	{ -		if ( markerIsSameVersion(mMarkerFileName) ) +			LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' owned by another instance" << LL_ENDL; +		} +		else if (marker_is_same_version)  		{ -			LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found" << LL_ENDL; +			// the file existed, is ours, and matched our version, so we can report on what it says +			LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec FROZE" << LL_ENDL;  			gLastExecEvent = LAST_EXEC_FROZE; +				  		}  		else  		{  			LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found, but versions did not match" << LL_ENDL;  		}  	}     +	else // marker did not exist... last exec (if any) did not freeze +	{ +		// Create the marker file for this execution & lock it; it will be deleted on a clean exit +		apr_status_t s; +		s = mMarkerFile.open(mMarkerFileName, LL_APR_WB, TRUE);	 + +		if (s == APR_SUCCESS && mMarkerFile.getFileHandle()) +		{ +			LL_DEBUGS("MarkerFile") << "Exec marker file '"<< mMarkerFileName << "' created." << LL_ENDL; +			if (APR_SUCCESS == apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE))  +			{ +				recordMarkerVersion(mMarkerFile); +				LL_DEBUGS("MarkerFile") << "Exec marker file locked." << LL_ENDL; +			} +			else +			{ +				LL_WARNS("MarkerFile") << "Exec marker file cannot be locked." << LL_ENDL; +			} +		} +		else +		{ +			LL_WARNS("MarkerFile") << "Failed to create exec marker file '"<< mMarkerFileName << "'." << LL_ENDL; +		} +	} + +	// now check for cases in which the exec marker may have been cleaned up by crash handlers + +	// check for any last exec event report based on whether or not it happened during logout +	// (the logout marker is created when logout begins) +	std::string logout_marker_file =  gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOGOUT_MARKER_FILE_NAME);  	if(LLAPRFile::isExist(logout_marker_file, NULL, LL_APR_RB))  	{  		if (markerIsSameVersion(logout_marker_file))  		{  			gLastExecEvent = LAST_EXEC_LOGOUT_FROZE; -			LL_INFOS("MarkerFile") << "Logout crashed '"<< logout_marker_file << "', setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +			LL_INFOS("MarkerFile") << "Logout crash marker '"<< logout_marker_file << "', changing LastExecEvent to LOGOUT_FROZE" << LL_ENDL;  		}  		else  		{ @@ -3657,91 +3699,88 @@ void LLAppViewer::initMarkerFile()  		}  		LLAPRFile::remove(logout_marker_file);  	} +	// further refine based on whether or not a marker created during an llerr crash is found +	std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME);  	if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB))  	{  		if (markerIsSameVersion(llerror_marker_file))  		{ -			gLastExecEvent = ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE ) -				? LAST_EXEC_LOGOUT_CRASH : LAST_EXEC_LLERROR_CRASH; -			LL_INFOS("MarkerFile") << "Last exec LLError '"<< llerror_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +			if ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE ) +			{ +				gLastExecEvent = LAST_EXEC_LOGOUT_CRASH; +				LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;  		}  		else  		{ -			LL_INFOS("MarkerFile") << "Last exec LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL; +				gLastExecEvent = LAST_EXEC_LLERROR_CRASH; +				LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LLERROR_CRASH" << LL_ENDL;  		} -		LLAPRFile::remove(llerror_marker_file); -	} -	if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB)) -	{ -		if (markerIsSameVersion(error_marker_file)) -		{ -			gLastExecEvent = (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) -				? LAST_EXEC_LOGOUT_CRASH : LAST_EXEC_OTHER_CRASH; -			LL_INFOS("MarkerFile") << "Last exec '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;  		}  		else  		{ -			LL_INFOS("MarkerFile") << "Last exec '"<< error_marker_file << "' marker found, but versions did not match" << LL_ENDL; +			LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL;  		} -		LLAPRFile::remove(error_marker_file); +		LLAPRFile::remove(llerror_marker_file);  	} - -	// No new markers if another instance is running. -	if(anotherInstanceRunning())  +	// and last refine based on whether or not a marker created during a non-llerr crash is found +	std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME); +	if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))  	{ -		return; -	} -	 -	// Create the marker file for this execution & lock it -	apr_status_t s; -	s = mMarkerFile.open(mMarkerFileName, LL_APR_W, TRUE);	 - -	if (s == APR_SUCCESS && mMarkerFile.getFileHandle()) +		if (markerIsSameVersion(error_marker_file))  	{ -		LL_DEBUGS("MarkerFile") << "Marker file '"<< mMarkerFileName << "' created." << LL_ENDL; -		if (APR_SUCCESS == apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE))  +			if (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE)  		{ -			recordMarkerVersion(mMarkerFile); -			LL_DEBUGS("MarkerFile") << "Marker file locked." << LL_ENDL; +				gLastExecEvent = LAST_EXEC_LOGOUT_CRASH; +				LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;  		}  		else  		{ -			LL_INFOS("MarkerFile") << "Marker file cannot be locked." << LL_ENDL; +				gLastExecEvent = LAST_EXEC_OTHER_CRASH; +				LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;  		}  	}  	else  	{ -		LL_INFOS("MarkerFile") << "Failed to create marker file '"<< mMarkerFileName << "'." << LL_ENDL; +			LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' marker found, but versions did not match" << LL_ENDL; +		} +		LLAPRFile::remove(error_marker_file);  	}  }  void LLAppViewer::removeMarkerFile(bool leave_logout_marker)  { -	LL_DEBUGS("MarkerFile") << "removeMarkerFile("<<(leave_logout_marker?"leave":"remove") <<" logout)" << LL_ENDL; +	if (!mSecondInstance) +	{		 +		LL_DEBUGS("MarkerFile") << (leave_logout_marker?"leave":"remove") <<" logout" << LL_ENDL;  	if (mMarkerFile.getFileHandle())  	{ -		LL_DEBUGS("MarkerFile") << "removeMarkerFile marker '"<<mMarkerFileName<<"'"<< LL_ENDL; +			LL_DEBUGS("MarkerFile") << "removing exec marker '"<<mMarkerFileName<<"'"<< LL_ENDL;  		mMarkerFile.close();  		LLAPRFile::remove( mMarkerFileName );  	}  	else  	{ -		LL_WARNS("MarkerFile") << "removeMarkerFile marker '"<<mMarkerFileName<<"' not open"<< LL_ENDL; +			LL_WARNS("MarkerFile") << "marker '"<<mMarkerFileName<<"' not open"<< LL_ENDL;  	}  	if (!leave_logout_marker)  	{  		if (mLogoutMarkerFile.getFileHandle())  		{ -			LL_DEBUGS("MarkerFile") << "removeMarkerFile logout marker '"<<mLogoutMarkerFileName<<"'"<< LL_ENDL; +				LL_DEBUGS("MarkerFile") << "removing logout marker '"<<mLogoutMarkerFileName<<"'"<< LL_ENDL;  			mLogoutMarkerFile.close();  		}  		else  		{ -			LL_WARNS("MarkerFile") << "removeMarkerFile logout marker '"<<mLogoutMarkerFileName<<"' not open"<< LL_ENDL; +				LL_WARNS("MarkerFile") << "logout marker '"<<mLogoutMarkerFileName<<"' not open"<< LL_ENDL;  		}  		LLAPRFile::remove( mLogoutMarkerFileName );  	}  } +	else +	{ +		LL_WARNS("MarkerFile") << "leaving markers because this is a second instance" << LL_ENDL; +	} +}  void LLAppViewer::forceQuit()  {  @@ -3787,6 +3826,12 @@ void LLAppViewer::requestQuit()  	// Try to send metrics back to the grid  	metricsSend(!gDisconnected); + +	// Try to send last batch of avatar rez metrics. +	if (!gDisconnected && isAgentAvatarValid()) +	{ +		gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent. +	}  	// Try to send last batch of avatar rez metrics.  	if (!gDisconnected && isAgentAvatarValid()) @@ -4932,6 +4977,22 @@ void LLAppViewer::sendLogoutRequest()  {  	if(!mLogoutRequestSent && gMessageSystem)  	{ +		//Set internal status variables and marker files before actually starting the logout process +		gLogoutInProgress = TRUE; +		mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME); +		 +		LLAPRFile outfile ; +		mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB); +		if (mLogoutMarkerFile.getFileHandle()) +		{ +			LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << LL_ENDL; +			recordMarkerVersion(outfile); +		} +		else +		{ +			LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL; +		}		 +  		LLMessageSystem* msg = gMessageSystem;  		msg->newMessageFast(_PREHASH_LogoutRequest);  		msg->nextBlockFast(_PREHASH_AgentData); @@ -4947,22 +5008,6 @@ void LLAppViewer::sendLogoutRequest()  		{  			LLVoiceClient::getInstance()->leaveChannel();  		} - -		//Set internal status variables and marker files -		gLogoutInProgress = TRUE; -		mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME); -		 -		LLAPRFile outfile ; -		mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_W); -		if (mLogoutMarkerFile.getFileHandle()) -		{ -			LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << mLogoutMarkerFileName << LL_ENDL; -			recordMarkerVersion(outfile); -		} -		else -		{ -			LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL; -		}		  	}  } @@ -5212,11 +5257,12 @@ void LLAppViewer::disconnectViewer()  void LLAppViewer::forceErrorLLError()  { -   	llerrs << "This is an llerror" << llendl; +   	llerrs << "This is a deliberate llerror" << llendl;  }  void LLAppViewer::forceErrorBreakpoint()  { +   	llwarns << "Forcing a deliberate breakpoint" << llendl;  #ifdef LL_WINDOWS      DebugBreak();  #endif @@ -5225,6 +5271,7 @@ void LLAppViewer::forceErrorBreakpoint()  void LLAppViewer::forceErrorBadMemoryAccess()  { +   	llwarns << "Forcing a deliberate bad memory access" << llendl;      S32* crash = NULL;      *crash = 0xDEADBEEF;        return; @@ -5232,6 +5279,7 @@ void LLAppViewer::forceErrorBadMemoryAccess()  void LLAppViewer::forceErrorInfiniteLoop()  { +   	llwarns << "Forcing a deliberate infinite loop" << llendl;      while(true)      {          ; @@ -5241,12 +5289,14 @@ void LLAppViewer::forceErrorInfiniteLoop()  void LLAppViewer::forceErrorSoftwareException()  { +   	llwarns << "Forcing a deliberate exception" << llendl;      // *FIX: Any way to insure it won't be handled?      throw;   }  void LLAppViewer::forceErrorDriverCrash()  { +   	llwarns << "Forcing a deliberate driver crash" << llendl;  	glDeleteTextures(1, NULL);  } diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index ad662d8ea1..68e9ebeff3 100755 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -186,7 +186,7 @@ public:  protected:  	virtual bool initWindow(); // Initialize the viewer's window. -	virtual void initLogging(); // Initialize log files, logging system +	virtual void initLoggingAndGetLastDuration(); // Initialize log files, logging system  	virtual void initConsole() {}; // Initialize OS level debugging console.  	virtual bool initHardwareTest() { return true; } // A false result indicates the app should quit.  	virtual bool initSLURLHandler(); @@ -218,11 +218,10 @@ private:  	void writeSystemInfo(); // Write system info to "debug_info.log" -	bool anotherInstanceRunning();  -	void initMarkerFile();  +	void processMarkerFiles();   	static void recordMarkerVersion(LLAPRFile& marker_file);  	bool markerIsSameVersion(const std::string& marker_name) const; -     +	      void idle();       void idleShutdown();  	// update avatar SLID and display name caches diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index 5f98fd0a34..b16bb573e1 100755 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -440,7 +440,7 @@ bool LLAppViewerLinux::beingDebugged()  #endif  } -void LLAppViewerLinux::initLogging() +void LLAppViewerLinux::initLoggingAndGetLastDuration()  {  	// Remove the last stack trace, if any  	// This file is no longer created, since the move to Google Breakpad @@ -449,7 +449,7 @@ void LLAppViewerLinux::initLogging()  		gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");  	LLFile::remove(old_stack_file); -	LLAppViewer::initLogging(); +	LLAppViewer::initLoggingAndGetLastDuration();  }  bool LLAppViewerLinux::initParseCommandLine(LLCommandLineParser& clp) diff --git a/indra/newview/llappviewerlinux.h b/indra/newview/llappviewerlinux.h index b30977acb3..fb77600c10 100755 --- a/indra/newview/llappviewerlinux.h +++ b/indra/newview/llappviewerlinux.h @@ -63,7 +63,7 @@ protected:  	virtual bool restoreErrorTrap();  	virtual void handleCrashReporting(bool reportFreeze); -	virtual void initLogging(); +	virtual void initLoggingAndGetLastDuration();  	virtual bool initParseCommandLine(LLCommandLineParser& clp);  	virtual bool initSLURLHandler(); diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index a113ab2508..b7cdcb058b 100755 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -491,7 +491,7 @@ bool LLAppViewerWin32::init()  	// (Don't send our data to Microsoft--at least until we are Logo approved and have a way  	// of getting the data back from them.)  	// -	llinfos << "Turning off Windows error reporting." << llendl; +	// llinfos << "Turning off Windows error reporting." << llendl;  	disableWinErrorReporting();  #ifndef LL_RELEASE_FOR_DOWNLOAD @@ -510,9 +510,9 @@ bool LLAppViewerWin32::cleanup()  	return result;  } -void LLAppViewerWin32::initLogging() +void LLAppViewerWin32::initLoggingAndGetLastDuration()  { -	LLAppViewer::initLogging(); +	LLAppViewer::initLoggingAndGetLastDuration();  }  void LLAppViewerWin32::initConsole() diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h index d95174dd1d..386bddd495 100755 --- a/indra/newview/llappviewerwin32.h +++ b/indra/newview/llappviewerwin32.h @@ -44,7 +44,7 @@ public:  	virtual bool cleanup();  protected: -	virtual void initLogging(); // Override to clean stack_trace info. +	virtual void initLoggingAndGetLastDuration(); // Override to clean stack_trace info.  	virtual void initConsole(); // Initialize OS level debugging console.  	virtual bool initHardwareTest(); // Win32 uses DX9 to test hardware.  	virtual bool initParseCommandLine(LLCommandLineParser& clp); diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 8587c7852b..628f7f7bfb 100755 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -336,7 +336,7 @@ LLFace*	LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep)  	{  		LLFastTimer t(FTM_ALLOCATE_FACE); -	face = new LLFace(this, mVObjp); +		face = new LLFace(this, mVObjp);  	}  	face->setTEOffset(mFaces.size()); @@ -354,6 +354,49 @@ LLFace*	LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep)  } +LLFace*	LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp) +{ +	LLFace *face; +	face = new LLFace(this, mVObjp); +	 +	face->setTEOffset(mFaces.size()); +	face->setTexture(texturep); +	face->setNormalMap(normalp); +	face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep)); +	 +	mFaces.push_back(face); +	 +	if (isState(UNLIT)) +	{ +		face->setState(LLFace::FULLBRIGHT); +	} +	 +	return face; +	 +} + +LLFace*	LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp) +{ +	LLFace *face; +	face = new LLFace(this, mVObjp); +	 +	face->setTEOffset(mFaces.size()); +	face->setTexture(texturep); +	face->setNormalMap(normalp); +	face->setSpecularMap(specularp); +	face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep)); +	 +	mFaces.push_back(face); +	 +	if (isState(UNLIT)) +	{ +		face->setState(LLFace::FULLBRIGHT); +	} +	 +	return face; +	 +} +  void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep)  {  	if (newFaces == (S32)mFaces.size()) @@ -507,7 +550,7 @@ void LLDrawable::makeStatic(BOOL warning_enabled)  		//drawable became static with active parent, not acceptable  		llassert(mParent.isNull() || !mParent->isActive() || !warning_enabled); -		 +  		LLViewerObject::const_child_list_t& child_list = mVObjp->getChildren();  		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();  			 iter != child_list.end(); iter++) @@ -699,7 +742,7 @@ BOOL LLDrawable::updateMove()  	{  		return FALSE;  	} - +	  	makeActive();  	return isState(MOVE_UNDAMPED) ? updateMoveUndamped() : updateMoveDamped(); diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index ebda188618..b7c5aeb5a8 100755 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -132,6 +132,8 @@ public:  	//void                removeFace(const S32 i); // SJB: Avoid using this, it's slow  	LLFace*				addFace(LLFacePool *poolp, LLViewerTexture *texturep);  	LLFace*				addFace(const LLTextureEntry *te, LLViewerTexture *texturep); +	LLFace*				addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp); +	LLFace*				addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp);  	void				deleteFaces(S32 offset, S32 count);  	void                setNumFaces(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep);  	void                setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep); diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 94dd927d26..04e31e6486 100755 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -35,6 +35,7 @@  #include "lldrawpoolalpha.h"  #include "lldrawpoolavatar.h"  #include "lldrawpoolbump.h" +#include "lldrawpoolmaterials.h"  #include "lldrawpoolground.h"  #include "lldrawpoolsimple.h"  #include "lldrawpoolsky.h" @@ -47,6 +48,7 @@  #include "llspatialpartition.h"  #include "llviewercamera.h"  #include "lldrawpoolwlsky.h" +#include "llglslshader.h"  S32 LLDrawPool::sNumDrawPools = 0; @@ -64,6 +66,12 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)  	case POOL_GRASS:  		poolp = new LLDrawPoolGrass();  		break; +	case POOL_ALPHA_MASK: +		poolp = new LLDrawPoolAlphaMask(); +		break; +	case POOL_FULLBRIGHT_ALPHA_MASK: +		poolp = new LLDrawPoolFullbrightAlphaMask(); +		break;  	case POOL_FULLBRIGHT:  		poolp = new LLDrawPoolFullbright();  		break; @@ -98,6 +106,9 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)  	case POOL_BUMP:  		poolp = new LLDrawPoolBump();  		break; +	case POOL_MATERIALS: +		poolp = new LLDrawPoolMaterials(); +		break;  	case POOL_WL_SKY:  		poolp = new LLDrawPoolWLSky();  		break; @@ -411,6 +422,27 @@ void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_text  	}  } +void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures) +{ +	for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)	 +	{ +		LLDrawInfo* pparams = *i; +		if (pparams)  +		{ +			if (LLGLSLShader::sCurBoundShaderPtr) +			{ +				LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff); +			} +			else +			{ +				gGL.setAlphaRejectSettings(LLRender::CF_GREATER, pparams->mAlphaMaskCutoff); +			} +			 +			pushBatch(*pparams, mask, texture, batch_textures); +		} +	} +} +  void LLRenderPass::applyModelMatrix(LLDrawInfo& params)  {  	if (params.mModelMatrix != gGLLastMatrix) diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index ab9bb9e611..3bde0d29be 100755 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -50,10 +50,13 @@ public:  		POOL_GROUND,  		POOL_FULLBRIGHT,  		POOL_BUMP, +		POOL_MATERIALS,  		POOL_TERRAIN,	  		POOL_SKY,  		POOL_WL_SKY,  		POOL_TREE, +		POOL_ALPHA_MASK, +		POOL_FULLBRIGHT_ALPHA_MASK,  		POOL_GRASS,  		POOL_INVISIBLE, // see below *  		POOL_AVATAR, @@ -133,6 +136,22 @@ public:  		PASS_SHINY,  		PASS_BUMP,  		PASS_POST_BUMP, +		PASS_MATERIAL, +		PASS_MATERIAL_ALPHA, +		PASS_MATERIAL_ALPHA_MASK, +		PASS_MATERIAL_ALPHA_EMISSIVE, +		PASS_SPECMAP, +		PASS_SPECMAP_BLEND, +		PASS_SPECMAP_MASK, +		PASS_SPECMAP_EMISSIVE, +		PASS_NORMMAP, +		PASS_NORMMAP_BLEND, +		PASS_NORMMAP_MASK, +		PASS_NORMMAP_EMISSIVE, +		PASS_NORMSPEC, +		PASS_NORMSPEC_BLEND, +		PASS_NORMSPEC_MASK, +		PASS_NORMSPEC_EMISSIVE,  		PASS_GLOW,  		PASS_ALPHA,  		PASS_ALPHA_MASK, @@ -151,6 +170,7 @@ public:  	static void applyModelMatrix(LLDrawInfo& params);  	virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE); +	virtual void pushMaskBatches(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); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 7020db917b..0fed6d1d17 100755 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -71,33 +71,6 @@ void LLDrawPoolAlpha::prerender()  	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);  } -S32 LLDrawPoolAlpha::getNumDeferredPasses() -{ -	return 1; -} - -void LLDrawPoolAlpha::beginDeferredPass(S32 pass) -{ -	 -} - -void LLDrawPoolAlpha::endDeferredPass(S32 pass) -{ -	 -} - -void LLDrawPoolAlpha::renderDeferred(S32 pass) -{ -	LLFastTimer t(FTM_RENDER_GRASS); -	gDeferredDiffuseAlphaMaskProgram.bind(); -	gDeferredDiffuseAlphaMaskProgram.setMinimumAlpha(0.33f); - -	//render alpha masked objects -	LLRenderPass::pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); -	gDeferredDiffuseAlphaMaskProgram.unbind();			 -} - -  S32 LLDrawPoolAlpha::getNumPostDeferredPasses()   {   	if (LLPipeline::sImpostorRender) @@ -121,8 +94,10 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)  	if (pass == 0)  	{  		simple_shader = &gDeferredAlphaProgram; -		fullbright_shader = &gObjectFullbrightAlphaMaskProgram; - +		fullbright_shader = &gObjectFullbrightProgram; +		fullbright_shader->bind(); +		fullbright_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);  +		fullbright_shader->unbind();  		//prime simple shader (loads shadow relevant uniforms)  		gPipeline.bindDeferredShader(*simple_shader);  	} @@ -133,8 +108,7 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)  		gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(),  							0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);	  		gPipeline.mDeferredDepth.bindTarget(); -		simple_shader = NULL; -		fullbright_shader = NULL; +		simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram;  		gObjectFullbrightAlphaMaskProgram.bind();  		gObjectFullbrightAlphaMaskProgram.setMinimumAlpha(0.33f);  	} @@ -150,7 +124,6 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)  void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)   {  -  	if (pass == 1)  	{  		gPipeline.mDeferredDepth.flush(); @@ -173,14 +146,14 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass)  	if (LLPipeline::sUnderWaterRender)  	{ -		simple_shader = &gObjectSimpleWaterAlphaMaskProgram; -		fullbright_shader = &gObjectFullbrightWaterAlphaMaskProgram; +		simple_shader = &gObjectSimpleWaterProgram; +		fullbright_shader = &gObjectFullbrightWaterProgram;  		emissive_shader = &gObjectEmissiveWaterProgram;  	}  	else  	{ -		simple_shader = &gObjectSimpleAlphaMaskProgram; -		fullbright_shader = &gObjectFullbrightAlphaMaskProgram; +		simple_shader = &gObjectSimpleProgram; +		fullbright_shader = &gObjectFullbrightProgram;  		emissive_shader = &gObjectEmissiveProgram;  	} @@ -219,42 +192,6 @@ void LLDrawPoolAlpha::render(S32 pass)  		gGL.setColorMask(true, true);  	} -	if (LLPipeline::sAutoMaskAlphaNonDeferred) -	{ -		mColorSFactor = LLRender::BF_ONE;  // } -		mColorDFactor = LLRender::BF_ZERO; // } these are like disabling blend on the color channels, but we're still blending on the alpha channel so that we can suppress glow -		mAlphaSFactor = LLRender::BF_ZERO; -		mAlphaDFactor = LLRender::BF_ZERO; // block (zero-out) glow where the alpha test succeeds -		gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); - -		if (mVertexShaderLevel > 0) -		{ -			if (!LLPipeline::sRenderDeferred || !deferred_render) -			{ -				simple_shader->bind(); -				simple_shader->setMinimumAlpha(0.33f); - -				pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); -			} -			if (fullbright_shader) -			{ -				fullbright_shader->bind(); -				fullbright_shader->setMinimumAlpha(0.33f); -			} -			pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); -			//LLGLSLShader::bindNoShader(); -		} -		else -		{ -			gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f); //OK -			gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); -			pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask()); -			gPipeline.enableLightsDynamic(); -			pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask()); -			gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK -		} -	} -  	LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ||   				(deferred_render && pass == 1) ? GL_TRUE : GL_FALSE); @@ -302,7 +239,7 @@ void LLDrawPoolAlpha::render(S32 pass)  	if (mVertexShaderLevel > 0)  	{ -		renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX); +		renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2);  	}  	else  	{ @@ -413,6 +350,12 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  				LLRenderPass::applyModelMatrix(params); +				LLMaterial* mat = NULL; + +				if (deferred_render && !LLPipeline::sUnderWaterRender) +				{ +					mat = params.mMaterial; +				}  				if (params.mFullbright)  				{ @@ -446,11 +389,30 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  					light_enabled = TRUE;  				} -				// 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)) +				if (deferred_render && mat) +				{ +					U32 mask = params.mShaderMask; + +					llassert(mask < LLMaterial::SHADER_COUNT); +					target_shader = &(gDeferredMaterialProgram[mask]); + +					if (current_shader != target_shader) +					{ +						gPipeline.bindDeferredShader(*target_shader); +					} +				} +				else if (!params.mFullbright)  				{ -					llassert(target_shader != NULL); +					target_shader = simple_shader; +				} +				else +				{ +					target_shader = fullbright_shader; +				} +				 +				if(use_shaders && (current_shader != target_shader)) +				{// If we need shaders, and we're not ALREADY using the proper shader, then bind it +				// (this way we won't rebind shaders unnecessarily).  					current_shader = target_shader;  					current_shader->bind();  				} @@ -460,6 +422,38 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  					current_shader = NULL;  				} +				if (use_shaders && mat) +				{ +					// We have a material.  Supply the appropriate data here. +					if (LLPipeline::sRenderDeferred) +					{ +						current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);						 +						current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity); +						current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f); + +						if (params.mNormalMap) +						{ +							params.mNormalMap->addTextureStats(params.mVSize); +							current_shader->bindTexture(LLShaderMgr::BUMP_MAP, params.mNormalMap); +						}  +						 +						if (params.mSpecularMap) +						{ +							params.mSpecularMap->addTextureStats(params.mVSize); +							current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap); +						}  +					} + +				} else if (LLPipeline::sRenderDeferred && current_shader && (current_shader == simple_shader)) +				{ +					current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);						 +					current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f);			 +					LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(params.mVSize); +					current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);						 +					LLViewerFetchedTexture::sWhiteImagep->addTextureStats(params.mVSize); +					current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); +				} +  				if (params.mGroup)  				{  					params.mGroup->rebuildMesh(); @@ -482,7 +476,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  					if (params.mTexture.notNull())  					{  						params.mTexture->addTextureStats(params.mVSize); +						if (use_shaders && mat) +						{ +							current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, params.mTexture); +						} +						else +						{  						gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ; +						} +						  						if (params.mTextureMatrix)  						{  							tex_setup = true; diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h index a4245e561d..43122218ed 100755 --- a/indra/newview/lldrawpoolalpha.h +++ b/indra/newview/lldrawpoolalpha.h @@ -50,11 +50,6 @@ public:  	LLDrawPoolAlpha(U32 type = LLDrawPool::POOL_ALPHA);  	/*virtual*/ ~LLDrawPoolAlpha(); -	/*virtual*/ S32 getNumDeferredPasses(); -	/*virtual*/ void beginDeferredPass(S32 pass); -	/*virtual*/ void endDeferredPass(S32 pass); -	/*virtual*/ void renderDeferred(S32 pass); -  	/*virtual*/ S32 getNumPostDeferredPasses();  	/*virtual*/ void beginPostDeferredPass(S32 pass);  	/*virtual*/ void endPostDeferredPass(S32 pass); @@ -70,7 +65,7 @@ public:  	void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);  	void renderAlpha(U32 mask);  	void renderAlphaHighlight(U32 mask); -	 +		  	static BOOL sShowDebugAlpha;  private: diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 67dbe6de8b..c3afe63bdd 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -62,6 +62,7 @@ S32 LLDrawPoolAvatar::sDiffuseChannel = 0;  static bool is_deferred_render = false; +static bool is_post_deferred_render = false;  extern BOOL gUseGLPick; @@ -183,6 +184,9 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass)  	case 4:  		beginDeferredRiggedBump();  		break; +	default: +		beginDeferredRiggedMaterial(pass-5); +		break;  	}  } @@ -215,6 +219,9 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass)  	case 4:  		endDeferredRiggedBump();  		break; +	default: +		endDeferredRiggedMaterial(pass-5); +		break;  	}  } @@ -225,7 +232,7 @@ void LLDrawPoolAvatar::renderDeferred(S32 pass)  S32 LLDrawPoolAvatar::getNumPostDeferredPasses()  { -	return 6; +	return 10;  }  void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass) @@ -247,9 +254,12 @@ void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass)  	case 4:  		beginRiggedFullbrightAlpha();  		break; -	case 5: +	case 9:  		beginRiggedGlow();  		break; +	default: +		beginDeferredRiggedMaterialAlpha(pass-5); +		break;  	}  } @@ -275,11 +285,34 @@ void LLDrawPoolAvatar::beginDeferredRiggedAlpha()  	gPipeline.enableLightsDynamic();  } +void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass) +{ +	switch (pass) +	{ +	case 0: pass = 1; break; +	case 1: pass = 5; break; +	case 2: pass = 9; break; +	default: pass = 13; break; +	} + +	pass += LLMaterial::SHADER_COUNT; + +	sVertexProgram = &gDeferredMaterialProgram[pass]; + +	gPipeline.bindDeferredShader(*sVertexProgram); +	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); +	normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP); +	specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP); +	gPipeline.enableLightsDynamic(); +} +  void LLDrawPoolAvatar::endDeferredRiggedAlpha()  {  	LLVertexBuffer::unbind();  	gPipeline.unbindDeferredShader(*sVertexProgram);  	sDiffuseChannel = 0; +	normal_channel = -1; +	specular_channel = -1;  	sVertexProgram = NULL;  } @@ -305,6 +338,9 @@ void LLDrawPoolAvatar::endPostDeferredPass(S32 pass)  	case 5:  		endRiggedGlow();  		break; +	default: +		endDeferredRiggedAlpha(); +		break;  	}  } @@ -328,17 +364,23 @@ void LLDrawPoolAvatar::renderPostDeferred(S32 pass)  		6, //rigged fullbright shiny  		7, //rigged alpha  		8, //rigged fullbright alpha -		9, //rigged glow +		9, //rigged material alpha 1 +		10,//rigged material alpha 2 +		11,//rigged material alpha 3 +		12,//rigged material alpha 4 +		13, //rigged glow  	}; -	pass = actual_pass[pass]; +	S32 p = actual_pass[pass];  	if (LLPipeline::sImpostorRender)  	{ //HACK for impostors so actual pass ends up being proper pass -		pass -= 2; +		p -= 2;  	} -	render(pass); +	is_post_deferred_render = true; +	render(p); +	is_post_deferred_render = false;  } @@ -425,12 +467,10 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)  	}  	else  	{ -		renderRigged(avatarp, RIGGED_SIMPLE); -		renderRigged(avatarp, RIGGED_ALPHA); -		renderRigged(avatarp, RIGGED_FULLBRIGHT); -		renderRigged(avatarp, RIGGED_FULLBRIGHT_SHINY); -		renderRigged(avatarp, RIGGED_SHINY); -		renderRigged(avatarp, RIGGED_FULLBRIGHT_ALPHA); +		for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i) +		{ +			renderRigged(avatarp, i); +		}  	}  } @@ -455,7 +495,7 @@ S32 LLDrawPoolAvatar::getNumDeferredPasses()  	}  	else  	{ -		return 5; +		return 21;  	}  } @@ -839,6 +879,8 @@ void LLDrawPoolAvatar::beginRiggedGlow()  	{  		sDiffuseChannel = 0;  		sVertexProgram->bind(); + +		sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, LLPipeline::sRenderDeferred ? 2.2f : 1.1f);  	}  } @@ -857,9 +899,16 @@ void LLDrawPoolAvatar::beginRiggedFullbright()  		}  		else  		{ +			if (LLPipeline::sRenderDeferred) +			{ +				sVertexProgram = &gDeferredSkinnedFullbrightProgram; +			} +			else +			{  			sVertexProgram = &gSkinnedObjectFullbrightProgram;  		}  	} +	}  	else  	{  		if (LLPipeline::sUnderWaterRender) @@ -876,6 +925,15 @@ void LLDrawPoolAvatar::beginRiggedFullbright()  	{  		sDiffuseChannel = 0;  		sVertexProgram->bind(); + +		if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred) +		{ +			sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); +		}  +		else  +		{ +			sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); +		}  	}  } @@ -942,9 +1000,16 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()  		}  		else  		{ +			if (LLPipeline::sRenderDeferred) +			{ +				sVertexProgram = &gDeferredSkinnedFullbrightShinyProgram; +			} +			else +			{  			sVertexProgram = &gSkinnedObjectFullbrightShinyProgram;  		}  	} +	}  	else  	{  		if (LLPipeline::sUnderWaterRender) @@ -957,11 +1022,19 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()  		}  	} -  	if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())  	{  		sVertexProgram->bind();  		LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false); + +		if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred) +		{ +			sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); +		}  +		else  +		{ +			sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); +		}  	}  } @@ -1010,6 +1083,42 @@ void LLDrawPoolAvatar::endDeferredRiggedBump()  	sVertexProgram = NULL;  } +void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass) +{ +	if (pass == 1 || +		pass == 5 || +		pass == 9 || +		pass == 13) +	{ //skip alpha passes +		return; +	} +	sVertexProgram = &gDeferredMaterialProgram[pass+LLMaterial::SHADER_COUNT]; +	sVertexProgram->bind(); +	normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP); +	specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP); +	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); +} + +void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass) +{ +	if (pass == 1 || +		pass == 5 || +		pass == 9 || +		pass == 13) +	{ +		return; +	} + +	LLVertexBuffer::unbind(); +	sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP); +	sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP); +	sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); +	sVertexProgram->unbind(); +	normal_channel = -1; +	sDiffuseChannel = 0; +	sVertexProgram = NULL; +} +  void LLDrawPoolAvatar::beginDeferredSkinned()  {  	sShaderLevel = mVertexShaderLevel; @@ -1167,6 +1276,22 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  		else  		{  			renderRiggedSimple(avatarp); + +			if (LLPipeline::sRenderDeferred) +			{ //render "simple" materials +				renderRigged(avatarp, RIGGED_MATERIAL); +				renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_MASK); +				renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE); +				renderRigged(avatarp, RIGGED_NORMMAP); +				renderRigged(avatarp, RIGGED_NORMMAP_MASK); +				renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE);	 +				renderRigged(avatarp, RIGGED_SPECMAP); +				renderRigged(avatarp, RIGGED_SPECMAP_MASK); +				renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE); +				renderRigged(avatarp, RIGGED_NORMSPEC); +				renderRigged(avatarp, RIGGED_NORMSPEC_MASK); +				renderRigged(avatarp, RIGGED_NORMSPEC_EMISSIVE); +			}  		}  		return;  	} @@ -1185,9 +1310,27 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  		return;  	} +	if (is_deferred_render && pass >= 5 && pass <= 21) +	{ +		S32 p = pass-5; + +		if (p != 1 && +			p != 5 && +			p != 9 && +			p != 13) +		{ +			renderDeferredRiggedMaterial(avatarp, p); +		} +		return; +	} + + + +  	if (pass == 5)  	{  		renderRiggedShinySimple(avatarp); +				  		return;  	} @@ -1197,11 +1340,29 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  		return;  	} -	if (pass >= 7 && pass < 9) +	if (pass >= 7 && pass < 13)  	{  		if (pass == 7)  		{  			renderRiggedAlpha(avatarp); + +			if (LLPipeline::sRenderDeferred && !is_post_deferred_render) +			{ //render transparent materials under water +				LLGLEnable blend(GL_BLEND); + +				gGL.setColorMask(true, true); +				gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, +								LLRender::BF_ONE_MINUS_SOURCE_ALPHA, +								LLRender::BF_ZERO, +								LLRender::BF_ONE_MINUS_SOURCE_ALPHA); + +				renderRigged(avatarp, RIGGED_MATERIAL_ALPHA); +				renderRigged(avatarp, RIGGED_SPECMAP_BLEND); +				renderRigged(avatarp, RIGGED_NORMMAP_BLEND); +				renderRigged(avatarp, RIGGED_NORMSPEC_BLEND); + +				gGL.setColorMask(true, false); +			}  			return;  		} @@ -1210,9 +1371,32 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  			renderRiggedFullbrightAlpha(avatarp);  			return;  		} + +		if (LLPipeline::sRenderDeferred && is_post_deferred_render) +		{ +			S32 p = 0; +			switch (pass) +			{ +			case 9: p = 1; break; +			case 10: p = 5; break; +			case 11: p = 9; break; +			case 12: p = 13; break;  	} -	if (pass == 9) +			{ +				LLGLEnable blend(GL_BLEND); +				renderDeferredRiggedMaterial(avatarp, p); +			} +			return; +		} +		else if (pass == 9) +		{ +			renderRiggedGlow(avatarp); +			return; +		} +	} + +	if (pass == 13)  	{  		renderRiggedGlow(avatarp); @@ -1474,9 +1658,11 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  		{  			if (sShaderLevel > 0)  			{ //upload matrix palette to shader -				LLMatrix4 mat[64]; +				LLMatrix4 mat[32]; -				for (U32 i = 0; i < skin->mJointNames.size(); ++i) +				U32 count = llmin((U32) skin->mJointNames.size(), (U32) 32); + +				for (U32 i = 0; i < count; ++i)  				{  					LLJoint* joint = avatar->getJoint(skin->mJointNames[i]);  					if (joint) @@ -1489,7 +1675,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  				stop_glerror();  				LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv("matrixPalette",  -					skin->mJointNames.size(), +					count,  					FALSE,  					(GLfloat*) mat[0].mMatrix); @@ -1510,11 +1696,60 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  				gGL.diffuseColor4f(0,0,0,face->getTextureEntry()->getGlow());  			}*/ +			const LLTextureEntry* te = face->getTextureEntry(); +			LLMaterial* mat = te->getMaterialParams().get(); + +			if (mat) +			{ +				gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture(LLRender::DIFFUSE_MAP)); +				gGL.getTexUnit(normal_channel)->bind(face->getTexture(LLRender::NORMAL_MAP)); +				gGL.getTexUnit(specular_channel)->bind(face->getTexture(LLRender::SPECULAR_MAP)); + +				LLColor4 col = mat->getSpecularLightColor(); +				F32 spec = mat->getSpecularLightExponent()/255.f; + +				F32 env = mat->getEnvironmentIntensity()/255.f; + +				if (mat->getSpecularID().isNull()) +				{ +					env = te->getShiny()*0.25f; +					col.set(env,env,env,0); +					spec = env; +				} +		 +				BOOL fullbright = te->getFullbright(); + +				sVertexProgram->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, fullbright ? 1.f : 0.f); +				sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec); +				sVertexProgram->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env); + +				if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) +				{ +					sVertexProgram->setMinimumAlpha(mat->getAlphaMaskCutoff()/255.f); +				} +				else +				{ +					sVertexProgram->setMinimumAlpha(0.f); +				} + +				for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) +				{ +					LLViewerTexture* tex = face->getTexture(i); +					if (tex) +					{ +						tex->addTextureStats(avatar->getPixelArea()); +					} +				} +			} +			else +			{  			gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture()); +				sVertexProgram->setMinimumAlpha(0.f);  			if (normal_channel > -1)  			{  				LLDrawPoolBump::bindBumpMap(face, normal_channel);  			} +			}  			if (face->mTextureMatrix)  			{ @@ -1545,6 +1780,11 @@ void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar)  	renderRigged(avatar, RIGGED_DEFERRED_BUMP);  } +void LLDrawPoolAvatar::renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass) +{ +	renderRigged(avatar, pass); +} +  static LLFastTimer::DeclareTimer FTM_RIGGED_VBO("Rigged VBO");  void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 69e3068858..7d0368a945 100755 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -75,7 +75,7 @@ public:  	/*virtual*/ void beginDeferredPass(S32 pass);  	/*virtual*/ void endDeferredPass(S32 pass);  	/*virtual*/ void renderDeferred(S32 pass); - +	  	/*virtual*/ S32 getNumPostDeferredPasses();  	/*virtual*/ void beginPostDeferredPass(S32 pass);  	/*virtual*/ void endPostDeferredPass(S32 pass); @@ -113,6 +113,8 @@ public:  	void beginRiggedFullbrightAlpha();  	void beginRiggedGlow();  	void beginDeferredRiggedAlpha(); +	void beginDeferredRiggedMaterial(S32 pass); +	void beginDeferredRiggedMaterialAlpha(S32 pass);  	void endRiggedSimple();  	void endRiggedFullbright(); @@ -122,6 +124,8 @@ public:  	void endRiggedFullbrightAlpha();  	void endRiggedGlow();  	void endDeferredRiggedAlpha(); +	void endDeferredRiggedMaterial(S32 pass); +	void endDeferredRiggedMaterialAlpha(S32 pass);  	void beginDeferredRiggedSimple();  	void beginDeferredRiggedBump(); @@ -146,10 +150,27 @@ public:  	void renderRiggedGlow(LLVOAvatar* avatar);  	void renderDeferredRiggedSimple(LLVOAvatar* avatar);  	void renderDeferredRiggedBump(LLVOAvatar* avatar); - +	void renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass); +	  	typedef enum  	{ -		RIGGED_SIMPLE = 0, +		RIGGED_MATERIAL=0, +		RIGGED_MATERIAL_ALPHA, +		RIGGED_MATERIAL_ALPHA_MASK, +		RIGGED_MATERIAL_ALPHA_EMISSIVE, +		RIGGED_SPECMAP, +		RIGGED_SPECMAP_BLEND, +		RIGGED_SPECMAP_MASK, +		RIGGED_SPECMAP_EMISSIVE, +		RIGGED_NORMMAP, +		RIGGED_NORMMAP_BLEND, +		RIGGED_NORMMAP_MASK, +		RIGGED_NORMMAP_EMISSIVE, +		RIGGED_NORMSPEC, +		RIGGED_NORMSPEC_BLEND, +		RIGGED_NORMSPEC_MASK, +		RIGGED_NORMSPEC_EMISSIVE, +		RIGGED_SIMPLE,  		RIGGED_FULLBRIGHT,  		RIGGED_SHINY,  		RIGGED_FULLBRIGHT_SHINY, @@ -164,6 +185,48 @@ public:  	typedef enum  	{ +		RIGGED_MATERIAL_MASK = +						LLVertexBuffer::MAP_VERTEX |  +						LLVertexBuffer::MAP_NORMAL |  +						LLVertexBuffer::MAP_TEXCOORD0 | +						LLVertexBuffer::MAP_COLOR | +						LLVertexBuffer::MAP_WEIGHT4, +		RIGGED_MATERIAL_ALPHA_VMASK = RIGGED_MATERIAL_MASK, +		RIGGED_MATERIAL_ALPHA_MASK_MASK = RIGGED_MATERIAL_MASK, +		RIGGED_MATERIAL_ALPHA_EMISSIVE_MASK = RIGGED_MATERIAL_MASK, +		RIGGED_SPECMAP_VMASK = +						LLVertexBuffer::MAP_VERTEX |  +						LLVertexBuffer::MAP_NORMAL |  +						LLVertexBuffer::MAP_TEXCOORD0 | +						LLVertexBuffer::MAP_TEXCOORD2 | +						LLVertexBuffer::MAP_COLOR | +						LLVertexBuffer::MAP_WEIGHT4, +		RIGGED_SPECMAP_BLEND_MASK = RIGGED_SPECMAP_VMASK, +		RIGGED_SPECMAP_MASK_MASK = RIGGED_SPECMAP_VMASK, +		RIGGED_SPECMAP_EMISSIVE_MASK = RIGGED_SPECMAP_VMASK, +		RIGGED_NORMMAP_VMASK = +						LLVertexBuffer::MAP_VERTEX |  +						LLVertexBuffer::MAP_NORMAL |  +						LLVertexBuffer::MAP_TANGENT |  +						LLVertexBuffer::MAP_TEXCOORD0 | +						LLVertexBuffer::MAP_TEXCOORD1 | +						LLVertexBuffer::MAP_COLOR | +						LLVertexBuffer::MAP_WEIGHT4, +		RIGGED_NORMMAP_BLEND_MASK = RIGGED_NORMMAP_VMASK, +		RIGGED_NORMMAP_MASK_MASK = RIGGED_NORMMAP_VMASK, +		RIGGED_NORMMAP_EMISSIVE_MASK = RIGGED_NORMMAP_VMASK, +		RIGGED_NORMSPEC_VMASK = +						LLVertexBuffer::MAP_VERTEX |  +						LLVertexBuffer::MAP_NORMAL |  +						LLVertexBuffer::MAP_TANGENT |  +						LLVertexBuffer::MAP_TEXCOORD0 | +						LLVertexBuffer::MAP_TEXCOORD1 | +						LLVertexBuffer::MAP_TEXCOORD2 | +						LLVertexBuffer::MAP_COLOR | +						LLVertexBuffer::MAP_WEIGHT4, +		RIGGED_NORMSPEC_BLEND_MASK = RIGGED_NORMSPEC_VMASK, +		RIGGED_NORMSPEC_MASK_MASK = RIGGED_NORMSPEC_VMASK, +		RIGGED_NORMSPEC_EMISSIVE_MASK = RIGGED_NORMSPEC_VMASK,  		RIGGED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX |   							 LLVertexBuffer::MAP_NORMAL |   							 LLVertexBuffer::MAP_TEXCOORD0 | @@ -184,7 +247,7 @@ public:  		RIGGED_DEFERRED_BUMP_MASK = LLVertexBuffer::MAP_VERTEX |   							 LLVertexBuffer::MAP_NORMAL |   							 LLVertexBuffer::MAP_TEXCOORD0 | -							 LLVertexBuffer::MAP_BINORMAL | +							 LLVertexBuffer::MAP_TANGENT |  							 LLVertexBuffer::MAP_COLOR |  							 LLVertexBuffer::MAP_WEIGHT4,  		RIGGED_DEFERRED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX |  diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index e8d43c8631..155e289c9d 100755 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -153,7 +153,7 @@ void LLStandardBumpmap::addstandard()  		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label;  		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage =   			LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id));	 -		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLGLTexture::BOOST_BUMP) ; +		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLGLTexture::LOCAL) ;  		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL );  		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->forceToSaveRawImage(0) ;  		LLStandardBumpmap::sStandardBumpmapCount++; @@ -449,9 +449,6 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&  	LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;  	if( cube_map )  	{ -		cube_map->disable(); -		cube_map->restoreMatrix(); -  		if (!invisible && shader_level > 1)  		{  			shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); @@ -464,6 +461,8 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&  				}  			}  		} +		cube_map->disable(); +		cube_map->restoreMatrix();  	}  	if (!LLGLSLShader::sNoFixedFunction) @@ -514,7 +513,14 @@ void LLDrawPoolBump::beginFullbrightShiny()  	}  	else  	{ -		shader = &gObjectFullbrightShinyProgram; +		if (LLPipeline::sRenderDeferred) +		{ +			shader = &gDeferredFullbrightShinyProgram; +		} +		else +		{ +			shader = &gObjectFullbrightShinyProgram; +		}  	}  	LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; @@ -850,7 +856,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass)  	LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);  	LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); -	U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR; +	U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR;  	for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)	  	{ @@ -915,6 +921,8 @@ void LLBumpImageList::init()  	llassert( mDarknessEntries.size() == 0 );  	LLStandardBumpmap::init(); + +	LLStandardBumpmap::restoreGL();  }  void LLBumpImageList::clear() diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp new file mode 100644 index 0000000000..08a36bddf1 --- /dev/null +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -0,0 +1,217 @@ +/**  + * @file lldrawpool.cpp + * @brief LLDrawPoolMaterials class implementation + * @author Jonathan "Geenz" Goodman + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "lldrawpoolmaterials.h" +#include "llviewershadermgr.h" +#include "pipeline.h" + +S32 diffuse_channel = -1; + +LLDrawPoolMaterials::LLDrawPoolMaterials() +:  LLRenderPass(LLDrawPool::POOL_MATERIALS) +{ +	 +} + +void LLDrawPoolMaterials::prerender() +{ +	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);  +} + +S32 LLDrawPoolMaterials::getNumDeferredPasses() +{ +	return 12; +} + +void LLDrawPoolMaterials::beginDeferredPass(S32 pass) +{ +	U32 shader_idx[] =  +	{ +		0, //LLRenderPass::PASS_MATERIAL, +		//1, //LLRenderPass::PASS_MATERIAL_ALPHA, +		2, //LLRenderPass::PASS_MATERIAL_ALPHA_MASK, +		3, //LLRenderPass::PASS_MATERIAL_ALPHA_GLOW, +		4, //LLRenderPass::PASS_SPECMAP, +		//5, //LLRenderPass::PASS_SPECMAP_BLEND, +		6, //LLRenderPass::PASS_SPECMAP_MASK, +		7, //LLRenderPass::PASS_SPECMAP_GLOW, +		8, //LLRenderPass::PASS_NORMMAP, +		//9, //LLRenderPass::PASS_NORMMAP_BLEND, +		10, //LLRenderPass::PASS_NORMMAP_MASK, +		11, //LLRenderPass::PASS_NORMMAP_GLOW, +		12, //LLRenderPass::PASS_NORMSPEC, +		//13, //LLRenderPass::PASS_NORMSPEC_BLEND, +		14, //LLRenderPass::PASS_NORMSPEC_MASK, +		15, //LLRenderPass::PASS_NORMSPEC_GLOW, +	}; +	 +	mShader = &(gDeferredMaterialProgram[shader_idx[pass]]); +	mShader->bind(); + +	diffuse_channel = mShader->enableTexture(LLShaderMgr::DIFFUSE_MAP); +		 +	LLFastTimer t(FTM_RENDER_MATERIALS); +} + +void LLDrawPoolMaterials::endDeferredPass(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_MATERIALS); + +	mShader->unbind(); + +	LLRenderPass::endRenderPass(pass); +} + +void LLDrawPoolMaterials::renderDeferred(S32 pass) +{ +	U32 type_list[] =  +	{ +		LLRenderPass::PASS_MATERIAL, +		//LLRenderPass::PASS_MATERIAL_ALPHA, +		LLRenderPass::PASS_MATERIAL_ALPHA_MASK, +		LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, +		LLRenderPass::PASS_SPECMAP, +		//LLRenderPass::PASS_SPECMAP_BLEND, +		LLRenderPass::PASS_SPECMAP_MASK, +		LLRenderPass::PASS_SPECMAP_EMISSIVE, +		LLRenderPass::PASS_NORMMAP, +		//LLRenderPass::PASS_NORMMAP_BLEND, +		LLRenderPass::PASS_NORMMAP_MASK, +		LLRenderPass::PASS_NORMMAP_EMISSIVE, +		LLRenderPass::PASS_NORMSPEC, +		//LLRenderPass::PASS_NORMSPEC_BLEND, +		LLRenderPass::PASS_NORMSPEC_MASK, +		LLRenderPass::PASS_NORMSPEC_EMISSIVE, +	}; + +	llassert(pass < sizeof(type_list)/sizeof(U32)); + +	U32 type = type_list[pass]; + +	U32 mask = mShader->mAttributeMask; + +	LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); +	LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); +	 +	for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) +	{ +		LLDrawInfo& params = **i; +		 +		mShader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]); +		mShader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity); +		 +		if (params.mNormalMap) +		{ +			params.mNormalMap->addTextureStats(params.mVSize); +			bindNormalMap(params.mNormalMap); +		} +		 +		if (params.mSpecularMap) +		{ +			params.mSpecularMap->addTextureStats(params.mVSize); +			bindSpecularMap(params.mSpecularMap); +		} +		 +		mShader->setMinimumAlpha(params.mAlphaMaskCutoff); +		mShader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f); + +		pushBatch(params, mask, TRUE); +	} +} + +void LLDrawPoolMaterials::bindSpecularMap(LLViewerTexture* tex) +{ +	mShader->bindTexture(LLShaderMgr::SPECULAR_MAP, tex); +} + +void LLDrawPoolMaterials::bindNormalMap(LLViewerTexture* tex) +{ +	mShader->bindTexture(LLShaderMgr::BUMP_MAP, tex); +} + +void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures) +{ +	applyModelMatrix(params); +	 +	bool tex_setup = false; +	 +	if (batch_textures && params.mTextureList.size() > 1) +	{ +		for (U32 i = 0; i < params.mTextureList.size(); ++i) +		{ +			if (params.mTextureList[i].notNull()) +			{ +				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.mTextureMatrix) +		{ +			//if (mShiny) +			{ +				gGL.getTexUnit(0)->activate(); +				gGL.matrixMode(LLRender::MM_TEXTURE); +			} +			 +			gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); +			gPipeline.mTextureMatrixOps++; +			 +			tex_setup = true; +		} +		 +		if (mVertexShaderLevel > 1 && 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(); +	} +	params.mVertexBuffer->setBuffer(mask); +	params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); +	gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); +	if (tex_setup) +	{ +		gGL.getTexUnit(0)->activate(); +		gGL.loadIdentity(); +		gGL.matrixMode(LLRender::MM_MODELVIEW); +	} +} diff --git a/indra/newview/lldrawpoolmaterials.h b/indra/newview/lldrawpoolmaterials.h new file mode 100644 index 0000000000..eae1aba87c --- /dev/null +++ b/indra/newview/lldrawpoolmaterials.h @@ -0,0 +1,75 @@ +/**  + * @file lldrawpoolmaterials.h + * @brief LLDrawPoolMaterials class definition + * @author Jonathan "Geenz" Goodman + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLDRAWPOOLMATERIALS_H +#define LL_LLDRAWPOOLMATERIALS_H + +#include "v4coloru.h" +#include "v2math.h" +#include "v3math.h" +#include "llvertexbuffer.h" +#include "lldrawpool.h" + +class LLViewerTexture; +class LLDrawInfo; +class LLGLSLShader; + +class LLDrawPoolMaterials : public LLRenderPass +{ +	LLGLSLShader *mShader; +public: +	LLDrawPoolMaterials(); +	 +	enum +	{ +		VERTEX_DATA_MASK =	LLVertexBuffer::MAP_VERTEX | +		LLVertexBuffer::MAP_NORMAL | +		LLVertexBuffer::MAP_TEXCOORD0 | +		LLVertexBuffer::MAP_TEXCOORD1 | +		LLVertexBuffer::MAP_TEXCOORD2 | +		LLVertexBuffer::MAP_COLOR | +		LLVertexBuffer::MAP_TANGENT +	}; +	 +	/*virtual*/ U32 getVertexDataMask() { return VERTEX_DATA_MASK; } +	 +	/*virtual*/ void render(S32 pass = 0) { } +	/*virtual*/ S32	 getNumPasses() {return 0;} +	/*virtual*/ void prerender(); +	 +	/*virtual*/ S32 getNumDeferredPasses(); +	/*virtual*/ void beginDeferredPass(S32 pass); +	/*virtual*/ void endDeferredPass(S32 pass); +	/*virtual*/ void renderDeferred(S32 pass); +	 +	void bindSpecularMap(LLViewerTexture* tex); +	void bindNormalMap(LLViewerTexture* tex); +	 +	/*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE); +}; + +#endif //LL_LLDRAWPOOLMATERIALS_H diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 6e0ea78af2..2cf9d833c6 100755 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -47,6 +47,7 @@ static LLFastTimer::DeclareTimer FTM_RENDER_GRASS_DEFERRED("Deferred Grass");  void LLDrawPoolGlow::beginPostDeferredPass(S32 pass)  {  	gDeferredEmissiveProgram.bind(); +	gDeferredEmissiveProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);  }  static LLFastTimer::DeclareTimer FTM_RENDER_GLOW_PUSH("Glow Push"); @@ -110,6 +111,7 @@ void LLDrawPoolGlow::render(S32 pass)  	LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;  	shader->bind(); +	shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f);  	LLGLDepthTest depth(GL_TRUE, GL_FALSE);  	gGL.setColorMask(false, true); @@ -198,7 +200,11 @@ void LLDrawPoolSimple::render(S32 pass)  			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); +				pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE);			 +				pushBatches(LLRenderPass::PASS_MATERIAL, mask, TRUE, TRUE); +				pushBatches(LLRenderPass::PASS_SPECMAP, mask, TRUE, TRUE); +				pushBatches(LLRenderPass::PASS_NORMMAP, mask, TRUE, TRUE); +				pushBatches(LLRenderPass::PASS_NORMSPEC, mask, TRUE, TRUE);		  			}  		}  		else @@ -210,6 +216,169 @@ void LLDrawPoolSimple::render(S32 pass)  	}  } + + + + + + + + + +static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_MASK("Alpha Mask"); + +LLDrawPoolAlphaMask::LLDrawPoolAlphaMask() : +	LLRenderPass(POOL_ALPHA_MASK) +{ +} + +void LLDrawPoolAlphaMask::prerender() +{ +	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); +} + +void LLDrawPoolAlphaMask::beginRenderPass(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_ALPHA_MASK); + +	if (LLPipeline::sUnderWaterRender) +	{ +		simple_shader = &gObjectSimpleWaterAlphaMaskProgram; +	} +	else +	{ +		simple_shader = &gObjectSimpleAlphaMaskProgram; +	} + +	if (mVertexShaderLevel > 0) +	{ +		simple_shader->bind(); +	} +	else  +	{ +		// don't use shaders! +		if (gGLManager.mHasShaderObjects) +		{ +			LLGLSLShader::bindNoShader(); +		}		 +	} +} + +void LLDrawPoolAlphaMask::endRenderPass(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_ALPHA_MASK); +	stop_glerror(); +	LLRenderPass::endRenderPass(pass); +	stop_glerror(); +	if (mVertexShaderLevel > 0) +	{ +		simple_shader->unbind(); +	} +} + +void LLDrawPoolAlphaMask::render(S32 pass) +{ +	LLGLDisable blend(GL_BLEND); +	LLFastTimer t(FTM_RENDER_ALPHA_MASK); +	 +	if (mVertexShaderLevel > 0) +	{ +		simple_shader->bind(); +		simple_shader->setMinimumAlpha(0.33f); + +		pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +		pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +		pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +		pushMaskBatches(LLRenderPass::PASS_NORMMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +		pushMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +	} +	else +	{ +		LLGLEnable test(GL_ALPHA_TEST); +		pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE); +		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK +	} +} + +LLDrawPoolFullbrightAlphaMask::LLDrawPoolFullbrightAlphaMask() : +	LLRenderPass(POOL_FULLBRIGHT_ALPHA_MASK) +{ +} + +void LLDrawPoolFullbrightAlphaMask::prerender() +{ +	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); +} + +void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_ALPHA_MASK); + +	if (LLPipeline::sUnderWaterRender) +	{ +		simple_shader = &gObjectFullbrightWaterAlphaMaskProgram; +	} +	else +	{ +		simple_shader = &gObjectFullbrightAlphaMaskProgram; +	} + +	if (mVertexShaderLevel > 0) +	{ +		simple_shader->bind(); +	} +	else  +	{ +		// don't use shaders! +		if (gGLManager.mHasShaderObjects) +		{ +			LLGLSLShader::bindNoShader(); +		}		 +	} +} + +void LLDrawPoolFullbrightAlphaMask::endRenderPass(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_ALPHA_MASK); +	stop_glerror(); +	LLRenderPass::endRenderPass(pass); +	stop_glerror(); +	if (mVertexShaderLevel > 0) +	{ +		simple_shader->unbind(); +	} +} + +void LLDrawPoolFullbrightAlphaMask::render(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_ALPHA_MASK); + +	if (mVertexShaderLevel > 0) +	{ +		if (simple_shader) +		{ +			simple_shader->bind(); +			simple_shader->setMinimumAlpha(0.33f); +			if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred) +			{ +				simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); +			} else { +				simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); +			} +		} +		pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +		//LLGLSLShader::bindNoShader(); +	} +	else +	{ +		LLGLEnable test(GL_ALPHA_TEST); +		gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); +		pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE); +		gPipeline.enableLightsDynamic(); +		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK +	} +} +  //===============================  //DEFERRED IMPLEMENTATION  //=============================== @@ -239,6 +408,28 @@ void LLDrawPoolSimple::renderDeferred(S32 pass)  	}  } +static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_MASK_DEFERRED("Deferred Alpha Mask"); + +void LLDrawPoolAlphaMask::beginDeferredPass(S32 pass) +{ +	 +} + +void LLDrawPoolAlphaMask::endDeferredPass(S32 pass) +{ +	 +} + +void LLDrawPoolAlphaMask::renderDeferred(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_ALPHA_MASK_DEFERRED); +	gDeferredDiffuseAlphaMaskProgram.bind(); +	gDeferredDiffuseAlphaMaskProgram.setMinimumAlpha(0.33f); +	pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +	gDeferredDiffuseAlphaMaskProgram.unbind();			 +} + +  // grass drawpool  LLDrawPoolGrass::LLDrawPoolGrass() :   LLRenderPass(POOL_GRASS) @@ -403,14 +594,24 @@ void LLDrawPoolFullbright::render(S32 pass)  	{  		fullbright_shader->bind();  		fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f); +		fullbright_shader->uniform1f(LLViewerShaderMgr::TEXTURE_GAMMA, 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); +		pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask, TRUE, TRUE); +		pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask, TRUE, TRUE); +		pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask, TRUE, TRUE); +		pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, 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); +		pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask); +		pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask); +		pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask); +		pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, fullbright_mask);  	}  	stop_glerror(); @@ -421,3 +622,32 @@ S32 LLDrawPoolFullbright::getNumPasses()  	return 1;  } + +void LLDrawPoolFullbrightAlphaMask::beginPostDeferredPass(S32 pass) +{ +	gObjectFullbrightAlphaMaskProgram.bind(); +	if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred) +	{ +		gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); +	}  +	else  +	{ +		gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); +	} +} + +void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_FULLBRIGHT); +	LLGLDisable blend(GL_BLEND); +	U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; +	pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, fullbright_mask, TRUE, TRUE); +} + +void LLDrawPoolFullbrightAlphaMask::endPostDeferredPass(S32 pass) +{ +	gObjectFullbrightAlphaMaskProgram.unbind(); +	LLRenderPass::endRenderPass(pass); +} + + diff --git a/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h index bd62bc7502..608ad9e1eb 100755 --- a/indra/newview/lldrawpoolsimple.h +++ b/indra/newview/lldrawpoolsimple.h @@ -84,6 +84,59 @@ public:  	/*virtual*/ void prerender();  }; +class LLDrawPoolAlphaMask : public LLRenderPass +{ +public: +	enum +	{ +		VERTEX_DATA_MASK =	LLVertexBuffer::MAP_VERTEX | +							LLVertexBuffer::MAP_NORMAL | +							LLVertexBuffer::MAP_TEXCOORD0 | +							LLVertexBuffer::MAP_COLOR +	}; +	virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } + +	LLDrawPoolAlphaMask(); + +	/*virtual*/ S32 getNumDeferredPasses() { return 1; } +	/*virtual*/ void beginDeferredPass(S32 pass); +	/*virtual*/ void endDeferredPass(S32 pass); +	/*virtual*/ void renderDeferred(S32 pass); + +	/*virtual*/ S32	 getNumPasses() { return 1; } +	/*virtual*/ void beginRenderPass(S32 pass); +	/*virtual*/ void endRenderPass(S32 pass); +	/*virtual*/ void render(S32 pass = 0); +	/*virtual*/ void prerender(); + +}; + +class LLDrawPoolFullbrightAlphaMask : public LLRenderPass +{ +public: +	enum +	{ +		VERTEX_DATA_MASK =	LLVertexBuffer::MAP_VERTEX | +							LLVertexBuffer::MAP_TEXCOORD0 | +							LLVertexBuffer::MAP_COLOR +	}; +	virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } + +	LLDrawPoolFullbrightAlphaMask(); +	 +	/*virtual*/ S32 getNumPostDeferredPasses() { return 1; } +	/*virtual*/ void beginPostDeferredPass(S32 pass); +	/*virtual*/ void endPostDeferredPass(S32 pass); +	/*virtual*/ void renderPostDeferred(S32 pass); + +	/*virtual*/ S32	 getNumPasses() { return 1; } +	/*virtual*/ void beginRenderPass(S32 pass); +	/*virtual*/ void endRenderPass(S32 pass); +	/*virtual*/ void render(S32 pass = 0); +	/*virtual*/ void prerender(); +}; + +  class LLDrawPoolFullbright : public LLRenderPass  {  public: diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp index e0f7223a8c..c1630318e8 100755 --- a/indra/newview/lleventpoll.cpp +++ b/indra/newview/lleventpoll.cpp @@ -213,7 +213,7 @@ namespace  		{  			llwarns << "LLEventPollResponder error <" << mCount   					<< "> [status:" << status << "]: " << content -					<< (mDone ? " -- done" : "") << llendl; +					<<	(mDone ? " -- done"	: "") << llendl;  			stop();  			// At this point we have given up and the viewer will not receive HTTP messages from the simulator. diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 98c75a64c7..94f06eb1d0 100755 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -51,7 +51,7 @@  #include "llviewerregion.h"  #include "llviewerwindow.h"  #include "llviewershadermgr.h" - +#include "llviewertexture.h"  #define LL_MAX_INDICES_COUNT 1000000 @@ -106,41 +106,6 @@ void planarProjection(LLVector2 &tc, const LLVector4a& normal,  	tc.mV[0] = 1.0f+((binormal.dot3(vec).getF32())*2 - 0.5f);  } -void sphericalProjection(LLVector2 &tc, const LLVector4a& normal, -						 const LLVector4a &mCenter, const LLVector4a& vec) -{	//BROKEN -	/*tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/3.14159f; -	 -	tc.mV[1] = acosf(vd.mNormal * LLVector3(0,0,1))/6.284f; -	if (vd.mNormal.mV[1] > 0) -	{ -		tc.mV[1] = 1.0f-tc.mV[1]; -	}*/ -} - -void cylindricalProjection(LLVector2 &tc, const LLVector4a& normal, const LLVector4a &mCenter, const LLVector4a& vec) -{	//BROKEN -	/*LLVector3 binormal; -	float d = vd.mNormal * LLVector3(1,0,0); -	if (d >= 0.5f || d <= -0.5f) -	{ -		binormal = LLVector3(0,1,0); -	} -	else{ -		binormal = LLVector3(1,0,0); -	} -	LLVector3 tangent = binormal % vd.mNormal; - -	tc.mV[1] = -((tangent*vec)*2 - 0.5f); - -	tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/6.284f; - -	if (vd.mNormal.mV[1] < 0) -	{ -		tc.mV[0] = 1.0f-tc.mV[0]; -	}*/ -} -  ////////////////////  //  // LLFace implementation @@ -167,8 +132,12 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)  	//special value to indicate uninitialized position  	mIndicesIndex	= 0xFFFFFFFF; -	mIndexInTex = 0; -	mTexture		= NULL; +	for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) +	{ +		mIndexInTex[i] = 0; +		mTexture[i] = NULL; +	} +  	mTEOffset		= -1;  	mTextureIndex = 255; @@ -185,8 +154,6 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)  	mImportanceToCamera = 0.f ;  	mBoundingSphereRadius = 0.0f ; -	mAtlasInfop = NULL ; -	mUsingAtlas  = FALSE ;  	mHasMedia = FALSE ;  } @@ -197,9 +164,12 @@ void LLFace::destroy()  		gPipeline.checkReferences(this);  	} -	if(mTexture.notNull()) +	for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)  	{ -		mTexture->removeFace(this) ; +		if(mTexture[i].notNull()) +		{ +			mTexture[i]->removeFace(i, this) ; +		}  	}  	if (isState(LLFace::PARTICLE)) @@ -239,7 +209,6 @@ void LLFace::destroy()  	}  	setDrawInfo(NULL); -	removeAtlas();  	mDrawablep = NULL;  	mVObjp = NULL; @@ -293,33 +262,57 @@ void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep)  	setTexture(texturep) ;  } -void LLFace::setTexture(LLViewerTexture* tex)  +void LLFace::setTexture(U32 ch, LLViewerTexture* tex)   { -	if(mTexture == tex) +	llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); + +	if(mTexture[ch] == tex)  	{  		return ;  	} -	if(mTexture.notNull()) +	if(mTexture[ch].notNull())  	{ -		mTexture->removeFace(this) ; -		removeAtlas() ; +		mTexture[ch]->removeFace(ch, this) ;  	}	  	if(tex)  	{ -		tex->addFace(this) ; +		tex->addFace(ch, this) ;  	} -	mTexture = tex ; +	mTexture[ch] = tex ; +} + +void LLFace::setTexture(LLViewerTexture* tex)  +{ +	setDiffuseMap(tex); +} + +void LLFace::setDiffuseMap(LLViewerTexture* tex) +{ +	setTexture(LLRender::DIFFUSE_MAP, tex); +} + +void LLFace::setNormalMap(LLViewerTexture* tex) +{ +	setTexture(LLRender::NORMAL_MAP, tex); +} + +void LLFace::setSpecularMap(LLViewerTexture* tex) +{ +	setTexture(LLRender::SPECULAR_MAP, tex);  }  void LLFace::dirtyTexture()  {  	LLDrawable* drawablep = getDrawable(); -	if (mVObjp.notNull() && mVObjp->getVolume() &&  -		mTexture.notNull() && mTexture->getComponents() == 4) +	if (mVObjp.notNull() && mVObjp->getVolume()) +	{ +		for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) +		{ +			if (mTexture[ch].notNull() && mTexture[ch]->getComponents() == 4)  	{ //dirty texture on an alpha object should be treated as an LoD update  		LLVOVolume* vobj = drawablep->getVOVolume();  		if (vobj) @@ -328,13 +321,17 @@ void LLFace::dirtyTexture()  		}  		gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);  	}		 +		} +	}  	gPipeline.markTextured(drawablep);  } -void LLFace::switchTexture(LLViewerTexture* new_texture) +void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture)  { -	if(mTexture == new_texture) +	llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); +	 +	if(mTexture[ch] == new_texture)  	{  		return ;  	} @@ -344,10 +341,17 @@ void LLFace::switchTexture(LLViewerTexture* new_texture)  		llerrs << "Can not switch to a null texture." << llendl;  		return;  	} -	new_texture->addTextureStats(mTexture->getMaxVirtualSize()) ; +	llassert(mTexture[ch].notNull()); + +	new_texture->addTextureStats(mTexture[ch]->getMaxVirtualSize()) ; + +	if (ch == LLRender::DIFFUSE_MAP) +	{  	getViewerObject()->changeTEImage(mTEOffset, new_texture) ; -	setTexture(new_texture) ;	 +	} + +	setTexture(ch, new_texture) ;	  	dirtyTexture();  } @@ -543,7 +547,9 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)  		}  		else  		{ -			mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); +			// cheaters sometimes prosper... +			// +			mVertexBuffer->setBuffer(mVertexBuffer->getTypeMask());  			mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);  		} @@ -811,6 +817,12 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  			size.mul(scale);  		} +		// Catch potential badness from normalization before it happens +		// +		llassert(mat_normal.mMatrix[0].isFinite3() && (mat_normal.mMatrix[0].dot3(mat_normal.mMatrix[0]).getF32() > F_APPROXIMATELY_ZERO)); +		llassert(mat_normal.mMatrix[1].isFinite3() && (mat_normal.mMatrix[1].dot3(mat_normal.mMatrix[1]).getF32() > F_APPROXIMATELY_ZERO)); +		llassert(mat_normal.mMatrix[2].isFinite3() && (mat_normal.mMatrix[2].dot3(mat_normal.mMatrix[2]).getF32() > F_APPROXIMATELY_ZERO)); +  		mat_normal.mMatrix[0].normalize3fast();  		mat_normal.mMatrix[1].normalize3fast();  		mat_normal.mMatrix[2].normalize3fast(); @@ -896,7 +908,7 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  // integrated with getGeometryVolume() for its texture coordinate  // generation - but i'll leave that to someone more familiar  // with the implications. -LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position, LLVector3 normal) +LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal)  {  	LLVector2 tc = surface_coord; @@ -916,7 +928,9 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position,  		LLVector4a& center = *(mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter);  		LLVector4a volume_position; -		volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(position).mV); +		LLVector3 v_position(position.getF32ptr()); + +		volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(v_position).mV);  		if (!mDrawablep->getVOVolume()->isVolumeGlobal())  		{ @@ -926,22 +940,13 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position,  		}  		LLVector4a volume_normal; -		volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(normal).mV); +		LLVector3 v_normal(normal.getF32ptr()); +		volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(v_normal).mV);  		volume_normal.normalize3fast(); -		switch (texgen) +		if (texgen == LLTextureEntry::TEX_GEN_PLANAR)  		{ -		case LLTextureEntry::TEX_GEN_PLANAR:  			planarProjection(tc, volume_normal, center, volume_position); -			break; -		case LLTextureEntry::TEX_GEN_SPHERICAL: -			sphericalProjection(tc, volume_normal, center, volume_position); -			break; -		case LLTextureEntry::TEX_GEN_CYLINDRICAL: -			cylindricalProjection(tc, volume_normal, center, volume_position); -			break; -		default: -			break;  		}		  	} @@ -969,7 +974,12 @@ void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_po  	const LLMatrix4& vol_mat = getWorldMatrix();  	const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset);  	const LLVector4a& normal4a = vf.mNormals[0]; -	const LLVector4a& binormal4a = vf.mBinormals[0]; +	const LLVector4a& tangent = vf.mTangents[0]; + +	LLVector4a binormal4a; +	binormal4a.setCross3(normal4a, tangent); +	binormal4a.mul(tangent.getF32ptr()[3]); +  	LLVector2 projected_binormal;  	planarProjection(projected_binormal, normal4a, *vf.mCenter, binormal4a);  	projected_binormal -= LLVector2(0.5f, 0.5f); // this normally happens in xform() @@ -1059,6 +1069,12 @@ bool LLFace::canRenderAsMask()  		return false;  	} +	LLMaterial* mat = te->getMaterialParams(); +	if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) +	{ +		return false; +	} +	  	if ((te->getColor().mV[3] == 1.0f) && // can't treat as mask if we have face alpha  		(te->getGlow() == 0.f) && // glowing masks are hard to implement - don't mask  		getTexture()->getIsAlphaMask()) // texture actually qualifies for masking (lazily recalculated but expensive) @@ -1091,7 +1107,7 @@ void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)  {  	LLFastTimer t(FTM_FACE_GEOM_VOLUME);  	U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | -				LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL; +				LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL;  	if (vf.mWeights)  	{ @@ -1104,11 +1120,11 @@ void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)  	buff->allocateBuffer(vf.mNumVertices, 0, true);  	LLStrider<LLVector4a> f_vert; -	LLStrider<LLVector3> f_binorm; +	LLStrider<LLVector4a> f_tangent;  	LLStrider<LLVector3> f_norm;  	LLStrider<LLVector2> f_tc; -	buff->getBinormalStrider(f_binorm); +	buff->getTangentStrider(f_tangent);  	buff->getVertexStrider(f_vert);  	buff->getNormalStrider(f_norm);  	buff->getTexCoord0Strider(f_tc); @@ -1116,7 +1132,7 @@ void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)  	for (U32 i = 0; i < vf.mNumVertices; ++i)  	{  		*f_vert++ = vf.mPositions[i]; -		(*f_binorm++).set(vf.mBinormals[i].getF32ptr()); +		*f_tangent++ = vf.mTangents[i];  		*f_tc++ = vf.mTexCoords[i];  		(*f_norm++).set(vf.mNormals[i].getF32ptr());  	} @@ -1158,7 +1174,7 @@ static LLFastTimer::DeclareTimer FTM_FACE_GEOM_TEXTURE("Texture");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_COLOR("Color");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_EMISSIVE("Emissive");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_WEIGHTS("Weights"); -static LLFastTimer::DeclareTimer FTM_FACE_GEOM_BINORMAL("Binormal"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_TANGENT("Binormal");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX("Index");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX_TAIL("Tail");  static LLFastTimer::DeclareTimer FTM_FACE_POSITION_STORE("Pos"); @@ -1219,11 +1235,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	}  	LLStrider<LLVector3> vert; -	LLStrider<LLVector2> tex_coords; +	LLStrider<LLVector2> tex_coords0; +	LLStrider<LLVector2> tex_coords1;  	LLStrider<LLVector2> tex_coords2;  	LLStrider<LLVector3> norm;  	LLStrider<LLColor4U> colors; -	LLStrider<LLVector3> binorm; +	LLStrider<LLVector3> tangent;  	LLStrider<U16> indicesp;  	LLStrider<LLVector4> wght; @@ -1245,33 +1262,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	bool rebuild_emissive = rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE);  	bool rebuild_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD);  	bool rebuild_normal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); -	bool rebuild_binormal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_BINORMAL); +	bool rebuild_tangent = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TANGENT);  	bool rebuild_weights = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_WEIGHT4);  	const LLTextureEntry *tep = mVObjp->getTE(f);  	const U8 bump_code = tep ? tep->getBumpmap() : 0; -	F32 tcoord_xoffset = 0.f ; -	F32 tcoord_yoffset = 0.f ; -	F32 tcoord_xscale = 1.f ; -	F32 tcoord_yscale = 1.f ; -	BOOL in_atlas = FALSE ; - -	if (rebuild_tcoord) -	{ -		in_atlas = isAtlasInUse() ; -		if(in_atlas) -		{ -			const LLVector2* tmp = getTexCoordOffset() ; -			tcoord_xoffset = tmp->mV[0] ;  -			tcoord_yoffset = tmp->mV[1] ; - -			tmp = getTexCoordScale() ; -			tcoord_xscale = tmp->mV[0] ;  -			tcoord_yscale = tmp->mV[1] ;	 -		} -	} -	  	BOOL is_static = mDrawablep->isStatic();  	BOOL is_global = is_static; @@ -1289,9 +1285,32 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	LLColor4U color = tep->getColor();  	if (rebuild_color) +	{ //decide if shiny goes in alpha channel of color +		if (tep &&  +			getPoolType() != LLDrawPool::POOL_ALPHA)  // <--- alpha channel MUST contain transparency, not shiny  	{ -		if (tep) +			LLMaterial* mat = tep->getMaterialParams().get(); +						 +			bool shiny_in_alpha = false; +			 +			if (LLPipeline::sRenderDeferred) +			{ //store shiny in alpha if we don't have a specular map +				if  (!mat || mat->getSpecularID().isNull()) +				{ +					shiny_in_alpha = true; +				} +			} +			else +			{ +				if (!mat || mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK) +				{ +					shiny_in_alpha = true; +				} +			} + +			if (shiny_in_alpha)  		{ +  			GLfloat alpha[4] =  			{  				0.00f, @@ -1300,8 +1319,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  				0.75f  			}; -			if (getPoolType() != LLDrawPool::POOL_ALPHA && (LLPipeline::sRenderDeferred || (LLPipeline::sRenderBump && tep->getShiny()))) -			{ +				llassert(tep->getShiny() <= 3);  				color.mV[3] = U8 (alpha[tep->getShiny()] * 255);  			}  		} @@ -1392,7 +1410,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices)  		{ -			mVObjp->getVolume()->genBinormals(f); +			mVObjp->getVolume()->genTangents(f);  			LLFace::cacheFaceInVRAM(vf);  			buff = (LLVertexBuffer*) vf.mVertexBuffer.get();  		}		 @@ -1477,15 +1495,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			glEndTransformFeedback();  		} -		if (rebuild_binormal) +		if (rebuild_tangent)  		{ -			LLFastTimer t(FTM_FACE_GEOM_BINORMAL); -			gTransformBinormalProgram.bind(); +			LLFastTimer t(FTM_FACE_GEOM_TANGENT); +			gTransformTangentProgram.bind(); -			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_BINORMAL, mGeomIndex, mGeomCount); +			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TANGENT, mGeomIndex, mGeomCount);  			glBeginTransformFeedback(GL_POINTS); -			buff->setBuffer(LLVertexBuffer::MAP_BINORMAL); +			buff->setBuffer(LLVertexBuffer::MAP_TANGENT);  			push_for_transform(buff, vf.mNumVertices, mGeomCount);  			glEndTransformFeedback();  		} @@ -1547,7 +1565,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			if (bump_code)  			{ -				mVObjp->getVolume()->genBinormals(f); +				mVObjp->getVolume()->genTangents(f);  				F32 offset_multiple;   				switch( bump_code )  				{ @@ -1556,11 +1574,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  					break;  					case BE_BRIGHTNESS:  					case BE_DARKNESS: -					if( mTexture.notNull() && mTexture->hasGLTexture()) +					if( mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->hasGLTexture())  					{  						// Offset by approximately one texel -						S32 cur_discard = mTexture->getDiscardLevel(); -						S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() ); +						S32 cur_discard = mTexture[LLRender::DIFFUSE_MAP]->getDiscardLevel(); +						S32 max_size = llmax( mTexture[LLRender::DIFFUSE_MAP]->getWidth(), mTexture[LLRender::DIFFUSE_MAP]->getHeight() );  						max_size <<= cur_discard;  						const F32 ARTIFICIAL_OFFSET = 2.f;  						offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size; @@ -1596,16 +1614,23 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			U8 texgen = getTextureEntry()->getTexGen();  			if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)  			{ //planar texgen needs binormals -				mVObjp->getVolume()->genBinormals(f); +				mVObjp->getVolume()->genTangents(f);  			}  			U8 tex_mode = 0; -			if (isState(TEXTURE_ANIM)) -			{ +			bool tex_anim = false; +  				LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;	  				tex_mode = vobj->mTexAnimMode; +			if (vobj->mTextureAnimp) +			{ //texture animation is in play, override specular and normal map tex coords with diffuse texcoords +				tex_anim = true; +			} + +			if (isState(TEXTURE_ANIM)) +			{  				if (!tex_mode)  				{  					clearState(TEXTURE_ANIM); @@ -1630,12 +1655,21 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			LLVector4a scalea;  			scalea.load3(scale.mV); +			LLMaterial* mat = tep->getMaterialParams().get(); +  			bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1); + +			if (mat && !do_bump) +			{ +				do_bump  = mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1) +					     || mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2); +			} +			  			bool do_tex_mat = tex_mode && mTextureMatrix; -			if (!in_atlas && !do_bump) -			{ //not in atlas or not bump mapped, might be able to do a cheap update -				mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount); +			if (!do_bump) +			{ //not bump mapped, might be able to do a cheap update +				mVertexBuffer->getTexCoord0Strider(tex_coords0, mGeomIndex, mGeomCount);  				if (texgen != LLTextureEntry::TEX_GEN_PLANAR)  				{ @@ -1646,12 +1680,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  						{  							LLFastTimer t(FTM_FACE_TEX_QUICK_NO_XFORM);  							S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF; -							LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, tc_size); +							LLVector4a::memcpyNonAliased16((F32*) tex_coords0.get(), (F32*) vf.mTexCoords, tc_size);  						}  						else  						{  							LLFastTimer t(FTM_FACE_TEX_QUICK_XFORM); -							F32* dst = (F32*) tex_coords.get(); +							F32* dst = (F32*) tex_coords0.get();  							LLVector4a* src = (LLVector4a*) vf.mTexCoords;  							LLVector4a trans; @@ -1686,7 +1720,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  						}  					}  					else -					{ //do tex mat, no texgen, no atlas, no bump +					{ //do tex mat, no texgen, no bump  						for (S32 i = 0; i < num_vertices; i++)  						{	  							LLVector2 tc(vf.mTexCoords[i]); @@ -1697,12 +1731,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  							tmp = tmp * *mTextureMatrix;  							tc.mV[0] = tmp.mV[0];  							tc.mV[1] = tmp.mV[1]; -							*tex_coords++ = tc;	 +							*tex_coords0++ = tc;	  						}  					}  				}  				else -				{ //no bump, no atlas, tex gen planar +				{ //no bump, tex gen planar  					LLFastTimer t(FTM_FACE_TEX_QUICK_PLANAR);  					if (do_tex_mat)  					{ @@ -1720,7 +1754,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  							tc.mV[0] = tmp.mV[0];  							tc.mV[1] = tmp.mV[1]; -							*tex_coords++ = tc;	 +							*tex_coords0++ = tc;	  						}  					}  					else @@ -1736,7 +1770,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  							xform(tc, cos_ang, sin_ang, os, ot, ms, mt); -							*tex_coords++ = tc;	 +							*tex_coords0++ = tc;	  						}  					}  				} @@ -1747,12 +1781,67 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  				}  			}  			else -			{ //either bump mapped or in atlas, just do the whole expensive loop +			{ //bump mapped or has material, just do the whole expensive loop  				LLFastTimer t(FTM_FACE_TEX_DEFAULT); -				mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, map_range);  				std::vector<LLVector2> bump_tc; +				if (mat && !mat->getNormalID().isNull()) +				{ //writing out normal and specular texture coordinates, not bump offsets +					do_bump = false; +				} + +				LLStrider<LLVector2> dst; + +				for (U32 ch = 0; ch < 3; ++ch) +				{ +					switch (ch) +					{ +						case 0:  +							mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount, map_range);  +							break; +						case 1: +							if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)) +							{ +								mVertexBuffer->getTexCoord1Strider(dst, mGeomIndex, mGeomCount, map_range); +								if (mat && !tex_anim) +								{ +									r  = mat->getNormalRotation(); +									mat->getNormalOffset(os, ot); +									mat->getNormalRepeat(ms, mt); + +									cos_ang = cos(r); +									sin_ang = sin(r); + +								} +							} +							else +							{ +								continue; +							} +							break; +						case 2: +							if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2)) +							{ +								mVertexBuffer->getTexCoord2Strider(dst, mGeomIndex, mGeomCount, map_range); +								if (mat && !tex_anim) +								{ +									r  = mat->getSpecularRotation(); +									mat->getSpecularOffset(os, ot); +									mat->getSpecularRepeat(ms, mt); + +									cos_ang = cos(r); +									sin_ang = sin(r); +								} +							} +							else +							{ +								continue; +							} +							break; +					} +					 +  				for (S32 i = 0; i < num_vertices; i++)  				{	  					LLVector2 tc(vf.mTexCoords[i]); @@ -1767,19 +1856,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  						vec.mul(scalea); -						switch (texgen) +							if (texgen == LLTextureEntry::TEX_GEN_PLANAR)  						{ -							case LLTextureEntry::TEX_GEN_PLANAR:  								planarProjection(tc, norm, center, vec); -								break; -							case LLTextureEntry::TEX_GEN_SPHERICAL: -								sphericalProjection(tc, norm, center, vec); -								break; -							case LLTextureEntry::TEX_GEN_CYLINDRICAL: -								cylindricalProjection(tc, norm, center, vec); -								break; -							default: -								break;  						}		  					} @@ -1795,116 +1874,33 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  						xform(tc, cos_ang, sin_ang, os, ot, ms, mt);  					} -					if(in_atlas) -					{ -						// -						//manually calculate tex-coord per vertex for varying address modes. -						//should be removed if shader can handle this. -						// - -						S32 int_part = 0 ; -						switch(mTexture->getAddressMode()) -						{ -						case LLTexUnit::TAM_CLAMP: -							if(tc.mV[0] < 0.f) -							{ -								tc.mV[0] = 0.f ; -							} -							else if(tc.mV[0] > 1.f) -							{ -								tc.mV[0] = 1.f; -							} - -							if(tc.mV[1] < 0.f) -							{ -								tc.mV[1] = 0.f ; -							} -							else if(tc.mV[1] > 1.f) -							{ -								tc.mV[1] = 1.f; -							} -							break; -						case LLTexUnit::TAM_MIRROR: -							if(tc.mV[0] < 0.f) -							{ -								tc.mV[0] = -tc.mV[0] ; -							} -							int_part = (S32)tc.mV[0] ; -							if(int_part & 1) //odd number -							{ -								tc.mV[0] = int_part + 1 - tc.mV[0] ; -							} -							else //even number -							{ -								tc.mV[0] -= int_part ; -							} - -							if(tc.mV[1] < 0.f) -							{ -								tc.mV[1] = -tc.mV[1] ; -							} -							int_part = (S32)tc.mV[1] ; -							if(int_part & 1) //odd number -							{ -								tc.mV[1] = int_part + 1 - tc.mV[1] ; -							} -							else //even number -							{ -								tc.mV[1] -= int_part ; -							} -							break; -						case LLTexUnit::TAM_WRAP: -							if(tc.mV[0] > 1.f) -								tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ; -							else if(tc.mV[0] < -1.f) -								tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ; - -							if(tc.mV[1] > 1.f) -								tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ; -							else if(tc.mV[1] < -1.f) -								tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ; - -							if(tc.mV[0] < 0.f) -							{ -								tc.mV[0] = 1.0f + tc.mV[0] ; -							} -							if(tc.mV[1] < 0.f) -							{ -								tc.mV[1] = 1.0f + tc.mV[1] ; -							} -							break; -						default: -							break; -						} -				 -						tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ; -						tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ; -					} -				 - -					*tex_coords++ = tc; +						*dst++ = tc;  					if (do_bump)  					{  						bump_tc.push_back(tc);  					}  				} +				}  				if (map_range)  				{  					mVertexBuffer->flush();  				} -				if (do_bump) +				if (!mat && do_bump)  				{ -					mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, map_range); +					mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount, map_range);  					for (S32 i = 0; i < num_vertices; i++)  					{ -						LLVector4a tangent; -						tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]); +						LLVector4a tangent = vf.mTangents[i]; + +						LLVector4a binorm; +						binorm.setCross3(vf.mNormals[i], tangent); +						binorm.mul(tangent.getF32ptr()[3]);  						LLMatrix4a tangent_to_object; -						tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]); +						tangent_to_object.setRows(tangent, binorm, vf.mNormals[i]);  						LLVector4a t;  						tangent_to_object.rotate(binormal_dir, t);  						LLVector4a binormal; @@ -1920,10 +1916,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  						}  						binormal.normalize3fast(); +  						LLVector2 tc = bump_tc[i];  						tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() ); -						*tex_coords2++ = tc; +						*tex_coords1++ = tc;  					}  					if (map_range) @@ -2006,7 +2003,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			LLFastTimer t(FTM_FACE_GEOM_NORMAL);  			mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);  			F32* normals = (F32*) norm.get(); -	  			for (S32 i = 0; i < num_vertices; i++)  			{	  				LLVector4a normal; @@ -2022,19 +2018,27 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			}  		} -		if (rebuild_binormal) +		if (rebuild_tangent)  		{ -			LLFastTimer t(FTM_FACE_GEOM_BINORMAL); -			mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range); -			F32* binormals = (F32*) binorm.get(); +			LLFastTimer t(FTM_FACE_GEOM_TANGENT); +			mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount, map_range); +			F32* tangents = (F32*) tangent.get(); +			 +			mVObjp->getVolume()->genTangents(f); +			 +			LLVector4Logical mask; +			mask.clear(); +			mask.setElement<3>();  			for (S32 i = 0; i < num_vertices; i++)  			{	 -				LLVector4a binormal; -				mat_normal.rotate(vf.mBinormals[i], binormal); -				binormal.normalize3fast(); -				binormal.store4a(binormals); -				binormals += 4; +				LLVector4a tangent_out; +				mat_normal.rotate(vf.mTangents[i], tangent_out); +				tangent_out.normalize3fast(); +				tangent_out.setSelectWithMask(mask, vf.mTangents[i], tangent_out); +				tangent_out.store4a(tangents); +				 +				tangents += 4;  			}  			if (map_range) @@ -2097,10 +2101,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			LLVector4a src; -			U32 glow32 = glow | -						 (glow << 8) | -						 (glow << 16) | -						 (glow << 24); +			LLColor4U glow4u = LLColor4U(0,0,0,glow); + +			U32 glow32 = glow4u.mAll;  			U32 vec[4];  			vec[0] = vec[1] = vec[2] = vec[3] = glow32; @@ -2153,9 +2156,9 @@ BOOL LLFace::hasMedia() const  	{  		return TRUE ;  	} -	if(mTexture.notNull())  +	if(mTexture[LLRender::DIFFUSE_MAP].notNull())   	{ -		return mTexture->hasParcelMedia() ;  //if has a parcel media +		return mTexture[LLRender::DIFFUSE_MAP]->hasParcelMedia() ;  //if has a parcel media  	}  	return FALSE ; //no media. @@ -2207,7 +2210,7 @@ F32 LLFace::getTextureVirtualSize()  	face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area) ;  	if(face_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.  	{ -		if(mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture.notNull() && mTexture->isLargeImage()) +		if(mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->isLargeImage())  		{		  			face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius );  		}	 @@ -2572,159 +2575,13 @@ LLVector3 LLFace::getPositionAgent() const  	}  } -// -//atlas -// -void LLFace::removeAtlas() -{ -	setAtlasInUse(FALSE) ; -	mAtlasInfop = NULL ;	 -} - -const LLTextureAtlas* LLFace::getAtlas()const  -{ -	if(mAtlasInfop) -	{ -		return mAtlasInfop->getAtlas() ; -	} -	return NULL ; -} - -const LLVector2* LLFace::getTexCoordOffset()const  +LLViewerTexture* LLFace::getTexture(U32 ch) const  { -	if(isAtlasInUse()) -	{ -		return mAtlasInfop->getTexCoordOffset() ; -	} -	return NULL ; -} -const LLVector2* LLFace::getTexCoordScale() const  -{ -	if(isAtlasInUse()) -	{ -		return mAtlasInfop->getTexCoordScale() ; -	} -	return NULL ; -} +	llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); -BOOL LLFace::isAtlasInUse()const -{ -	return mUsingAtlas ; +	return mTexture[ch] ;  } -BOOL LLFace::canUseAtlas()const -{ -	//no drawable or no spatial group, do not use atlas -	if(!mDrawablep || !mDrawablep->getSpatialGroup()) -	{ -		return FALSE ; -	} - -	//if bump face, do not use atlas -	if(getTextureEntry() && getTextureEntry()->getBumpmap()) -	{ -		return FALSE ; -	} - -	//if animated texture, do not use atlas -	if(isState(TEXTURE_ANIM)) -	{ -		return FALSE ; -	} - -	return TRUE ; -} - -void LLFace::setAtlasInUse(BOOL flag) -{ -	//no valid atlas to use. -	if(flag && (!mAtlasInfop || !mAtlasInfop->isValid())) -	{ -		flag = FALSE ; -	} - -	if(!flag && !mUsingAtlas) -	{ -		return ; -	} - -	// -	//at this stage (flag || mUsingAtlas) is always true. -	// - -	//rebuild the tex coords -	if(mDrawablep) -	{ -		gPipeline.markRebuild(mDrawablep, LLDrawable::REBUILD_TCOORD); -		mUsingAtlas = flag ; -	} -	else -	{ -		mUsingAtlas = FALSE ; -	} -} - -LLTextureAtlasSlot* LLFace::getAtlasInfo() -{ -	return mAtlasInfop ; -} - -void LLFace::setAtlasInfo(LLTextureAtlasSlot* atlasp) -{	 -	if(mAtlasInfop != atlasp) -	{ -		if(mAtlasInfop) -		{ -			//llerrs << "Atlas slot changed!" << llendl ; -		} -		mAtlasInfop = atlasp ; -	} -} - -LLViewerTexture* LLFace::getTexture() const -{ -	if(isAtlasInUse()) -	{ -		return (LLViewerTexture*)mAtlasInfop->getAtlas() ; -	} - -	return mTexture ; -} - -//switch to atlas or switch back to gl texture  -//return TRUE if using atlas. -BOOL LLFace::switchTexture() -{ -	//no valid atlas or texture -	if(!mAtlasInfop || !mAtlasInfop->isValid() || !mTexture) -	{ -		return FALSE ; -	} -	 -	if(mTexture->getTexelsInAtlas() >= (U32)mVSize ||  -		mTexture->getTexelsInAtlas() >= mTexture->getTexelsInGLTexture()) -	{ -		//switch to use atlas -		//atlas resolution is qualified, use it.		 -		if(!mUsingAtlas) -		{ -			setAtlasInUse(TRUE) ; -		} -	} -	else //if atlas not qualified. -	{ -		//switch back to GL texture -		if(mUsingAtlas && mTexture->isGLTextureCreated() &&  -			mTexture->getDiscardLevel() < mTexture->getDiscardLevelInAtlas()) -		{ -			setAtlasInUse(FALSE) ; -		} -	} - -	return mUsingAtlas ; -} - -  void LLFace::setVertexBuffer(LLVertexBuffer* buffer)  {  	mVertexBuffer = buffer; @@ -2740,6 +2597,22 @@ void LLFace::clearVertexBuffer()  U32 LLFace::getRiggedDataMask(U32 type)  {  	static const U32 rigged_data_mask[] = { +		LLDrawPoolAvatar::RIGGED_MATERIAL_MASK, +		LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_VMASK, +		LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_MASK_MASK, +		LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_EMISSIVE_MASK, +		LLDrawPoolAvatar::RIGGED_SPECMAP_VMASK, +		LLDrawPoolAvatar::RIGGED_SPECMAP_BLEND_MASK, +		LLDrawPoolAvatar::RIGGED_SPECMAP_MASK_MASK, +		LLDrawPoolAvatar::RIGGED_SPECMAP_EMISSIVE_MASK, +		LLDrawPoolAvatar::RIGGED_NORMMAP_VMASK, +		LLDrawPoolAvatar::RIGGED_NORMMAP_BLEND_MASK, +		LLDrawPoolAvatar::RIGGED_NORMMAP_MASK_MASK, +		LLDrawPoolAvatar::RIGGED_NORMMAP_EMISSIVE_MASK, +		LLDrawPoolAvatar::RIGGED_NORMSPEC_VMASK, +		LLDrawPoolAvatar::RIGGED_NORMSPEC_BLEND_MASK, +		LLDrawPoolAvatar::RIGGED_NORMSPEC_MASK_MASK, +		LLDrawPoolAvatar::RIGGED_NORMSPEC_EMISSIVE_MASK,  		LLDrawPoolAvatar::RIGGED_SIMPLE_MASK,  		LLDrawPoolAvatar::RIGGED_FULLBRIGHT_MASK,  		LLDrawPoolAvatar::RIGGED_SHINY_MASK, diff --git a/indra/newview/llface.h b/indra/newview/llface.h index dda4bc9b3c..c4832b67cd 100755 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -39,12 +39,14 @@  #include "llvertexbuffer.h"  #include "llviewertexture.h"  #include "lldrawable.h" -#include "lltextureatlasmanager.h"  class LLFacePool;  class LLVolume;  class LLViewerTexture;  class LLTextureEntry; +class LLVertexProgram; +class LLViewerTexture; +class LLGeometryManager;  class LLTextureAtlasSlot;  class LLDrawInfo; @@ -106,13 +108,17 @@ public:  	U16				getGeomStart()		const	{ return mGeomIndex; }		// index into draw pool  	void			setTextureIndex(U8 index);  	U8				getTextureIndex() const		{ return mTextureIndex; } +	void			setTexture(U32 ch, LLViewerTexture* tex);  	void			setTexture(LLViewerTexture* tex) ; -	void            switchTexture(LLViewerTexture* new_texture); +	void			setDiffuseMap(LLViewerTexture* tex); +	void			setNormalMap(LLViewerTexture* tex); +	void			setSpecularMap(LLViewerTexture* tex); +	void            switchTexture(U32 ch, LLViewerTexture* new_texture);  	void            dirtyTexture();  	LLXformMatrix*	getXform()			const	{ return mXform; }  	BOOL			hasGeometry()		const	{ return mGeomCount > 0; }  	LLVector3		getPositionAgent()	const; -	LLVector2       surfaceToTexture(LLVector2 surface_coord, LLVector3 position, LLVector3 normal); +	LLVector2       surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal);  	void 			getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const;  	bool			calcAlignedPlanarTE(const LLFace* align_to, LLVector2* st_offset,  										LLVector2* st_scale, F32* st_rot) const; @@ -126,8 +132,8 @@ public:  	F32				getVirtualSize() const { return mVSize; }  	F32				getPixelArea() const { return mPixelArea; } -	S32             getIndexInTex() const {return mIndexInTex ;} -	void            setIndexInTex(S32 index) { mIndexInTex = index ;} +	S32             getIndexInTex(U32 ch) const {llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); return mIndexInTex[ch];} +	void            setIndexInTex(U32 ch, S32 index) { llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);  mIndexInTex[ch] = index ;}  	void			renderSetColor() const;  	S32				renderElements(const U16 *index_array) const; @@ -145,7 +151,7 @@ public:  	S32				getLOD()			const	{ return mVObjp.notNull() ? mVObjp->getLOD() : 0; }  	void			setPoolType(U32 type)		{ mPoolType = type; }  	S32				getTEOffset()				{ return mTEOffset; } -	LLViewerTexture*	getTexture() const; +	LLViewerTexture*	getTexture(U32 ch = LLRender::DIFFUSE_MAP) const;  	void			setViewerObject(LLViewerObject* object);  	void			setPool(LLFacePool *pool, LLViewerTexture *texturep); @@ -219,16 +225,6 @@ public:  	void        setHasMedia(bool has_media)  { mHasMedia = has_media ;}  	BOOL        hasMedia() const ; -	//for atlas -	LLTextureAtlasSlot*   getAtlasInfo() ; -	void                  setAtlasInUse(BOOL flag); -	void                  setAtlasInfo(LLTextureAtlasSlot* atlasp); -	BOOL                  isAtlasInUse()const; -	BOOL                  canUseAtlas() const; -	const LLVector2*      getTexCoordScale() const ; -	const LLVector2*      getTexCoordOffset()const; -	const LLTextureAtlas* getAtlas()const ; -	void                  removeAtlas() ;  	BOOL                  switchTexture() ;  	//vertex buffer tracking @@ -258,11 +254,13 @@ public:  	LLVector2		mTexExtents[2];  	F32				mDistance; -	F32				mLastUpdateTime; -	F32				mLastSkinTime; -	F32				mLastMoveTime; -	LLMatrix4*		mTextureMatrix; -	LLDrawInfo*		mDrawInfo; +	F32			mLastUpdateTime; +	F32			mLastSkinTime; +	F32			mLastMoveTime; +	LLMatrix4*	mTextureMatrix; +	LLMatrix4*	mSpecMapMatrix; +	LLMatrix4*	mNormalMapMatrix; +	LLDrawInfo* mDrawInfo;  private:  	LLPointer<LLVertexBuffer> mVertexBuffer; @@ -277,10 +275,12 @@ private:  	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 ; +	S32         mIndexInTex[LLRender::NUM_TEXTURE_CHANNELS];  	LLXformMatrix* mXform; -	LLPointer<LLViewerTexture> mTexture; + +	LLPointer<LLViewerTexture> mTexture[LLRender::NUM_TEXTURE_CHANNELS]; +	  	LLPointer<LLDrawable> mDrawablep;  	LLPointer<LLViewerObject> mVObjp;  	S32			mTEOffset; @@ -298,9 +298,6 @@ private:  	F32         mBoundingSphereRadius ;  	bool        mHasMedia ; -	//atlas -	LLPointer<LLTextureAtlasSlot> mAtlasInfop ; -	BOOL                          mUsingAtlas ;  protected:  	static BOOL	sSafeRenderSelect; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index ec307b841e..d3a97fde0e 100755 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -99,7 +99,7 @@ LLFastTimerView::LLFastTimerView(const LLSD& key)  :	LLFloater(key),  	mHoverTimer(NULL),  	mDisplayMode(0), -	mDisplayType(TIME), +	mDisplayType(DISPLAY_TIME),  	mScrollIndex(0),  	mHoverID(NULL),  	mHoverBarIndex(-1), @@ -274,7 +274,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)  			{  				hover_bar = &bar;  				if (bar.mTimeBlock->getTreeNode().mCollapsed) -				{ +		{  					// stop on first collapsed timeblock, since we can't select any children  					break;  				} @@ -282,14 +282,14 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)  		}  		if (hover_bar) -		{ +			{  			mHoverID = hover_bar->mTimeBlock;  			if (mHoverTimer != mHoverID) -			{ -				// could be that existing tooltip is for a parent and is thus -				// covering region for this new timer, go ahead and unblock  -				// so we can create a new tooltip -				LLToolTipMgr::instance().unblockToolTips(); +				{ +					// could be that existing tooltip is for a parent and is thus +					// covering region for this new timer, go ahead and unblock  +					// so we can create a new tooltip +					LLToolTipMgr::instance().unblockToolTips();  				mHoverTimer = mHoverID;  				mToolTipRect.set(mBarRect.mLeft + (hover_bar->mSelfStart / mTotalTimeDisplay) * mBarRect.getWidth(),  								row.mTop, @@ -392,7 +392,7 @@ void LLFastTimerView::draw()  	mDisplayMode = llclamp(getChild<LLComboBox>("time_scale_combo")->getCurrentIndex(), 0, 3);  	mDisplayType = (EDisplayType)llclamp(getChild<LLComboBox>("metric_combo")->getCurrentIndex(), 0, 2); - +		  	generateUniqueColors();  	LLView::drawChildren(); @@ -408,12 +408,12 @@ void LLFastTimerView::draw()  	legend_panel->localRectToOtherView(legend_panel->getLocalRect(), &mLegendRect, this);  	// Draw the window background -	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  	gl_rect_2d(getLocalRect(), LLColor4(0.f, 0.f, 0.f, 0.25f)); -	 +  	drawHelp(getRect().getHeight() - MARGIN);  	drawLegend(); - +			  	//mBarRect.mLeft = MARGIN + LEGEND_WIDTH + 8;  	//mBarRect.mTop = y;  	//mBarRect.mRight = getRect().getWidth() - MARGIN; @@ -423,26 +423,26 @@ void LLFastTimerView::draw()  	drawLineGraph();  	printLineStats();  	LLView::draw(); -		 +  	mAllTimeMax = llmax(mAllTimeMax, mRecording.getLastRecording().getSum(FTM_FRAME));  	mHoverID = NULL;  	mHoverBarIndex = -1; -} +					}  void LLFastTimerView::onOpen(const LLSD& key) -{ +				{  	setPauseState(false);  	mRecording.reset();  	mRecording.appendPeriodicRecording(LLTrace::get_frame_recording());  	for(std::deque<TimerBarRow>::iterator it = mTimerBarRows.begin(), end_it = mTimerBarRows.end();  		it != end_it;  -		++it) -	{ +				++it) +			{  		delete []it->mBars;  		it->mBars = NULL; -	} -} - +					} +					} +										  void saveChart(const std::string& label, const char* suffix, LLImageRaw* scratch)  { @@ -1113,20 +1113,20 @@ void LLFastTimerView::drawLineGraph()  			F32 x = mGraphRect.mRight - j * (F32)(mGraphRect.getWidth())/(mRecording.getNumRecordedPeriods()-1);  			F32 y;  			switch(mDisplayType) -			{ -			case TIME: +{ +			case DISPLAY_TIME:  				y = mGraphRect.mBottom + time.value() * time_scale_factor;  				break; -			case CALLS: +			case DISPLAY_CALLS:  				y = mGraphRect.mBottom + (F32)calls * call_scale_factor;  				break; -			case HZ: +			case DISPLAY_HZ:  				y = mGraphRect.mBottom + (1.f / time.value()) * hz_scale_factor;  				break;  			}  			gGL.vertex2f(x,y);  			gGL.vertex2f(x,mGraphRect.mBottom); -		} +}  		gGL.end();  		if (mHoverID == idp) @@ -1178,13 +1178,13 @@ void LLFastTimerView::drawLineGraph()  	std::string axis_label;  	switch(mDisplayType)  	{ -	case TIME: +	case DISPLAY_TIME:  		axis_label = llformat("%4.2f ms", LLUnit<F32, LLUnits::Milliseconds>(max_time).value());  		break; -	case CALLS: +	case DISPLAY_CALLS:  		axis_label = llformat("%d calls", (int)max_calls);  		break; -	case HZ: +	case DISPLAY_HZ:  		axis_label = llformat("%4.2f Hz", max_time.value() ? 1.f / max_time.value() : 0.f);  		break;  	} @@ -1247,13 +1247,13 @@ void LLFastTimerView::drawLegend()  			std::string timer_label;  			switch(mDisplayType)  			{ -			case TIME: +			case DISPLAY_TIME:  				timer_label = llformat("%s [%.1f]",idp->getName().c_str(),ms.value());  				break; -			case CALLS: +			case DISPLAY_CALLS:  				timer_label = llformat("%s (%d)",idp->getName().c_str(),calls);  				break; -			case HZ: +			case DISPLAY_HZ:  				timer_label = llformat("%.1f", ms.value() ? (1.f / ms.value()) : 0.f);  				break;  			} diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h index d931f25a7e..9d88bb2d3f 100755 --- a/indra/newview/llfasttimerview.h +++ b/indra/newview/llfasttimerview.h @@ -103,6 +103,11 @@ private:  	struct TimerBarRow  	{ +		TimerBarRow()  +		:	mBottom(0), +			mTop(0), +			mBars(NULL) +		{}  		S32			mBottom,  					mTop;  		TimerBar*	mBars; @@ -118,9 +123,9 @@ private:  	enum EDisplayType  	{ -		TIME, -		CALLS, -		HZ +		DISPLAY_TIME, +		DISPLAY_CALLS, +		DISPLAY_HZ  	}								mDisplayType;  	bool							mPauseHistory;  	LLUnit<F64, LLUnits::Seconds>	mAllTimeMax, diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 83193b2e14..caad0afec0 100755 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -339,10 +339,10 @@ void LLVolumeImplFlexible::doIdleUpdate()  	if (drawablep)  	{  		//LLFastTimer ftm(FTM_FLEXIBLE_UPDATE); -		 +  		//ensure drawable is active  		drawablep->makeActive(); -			 +  		if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))  		{  			bool visible = drawablep->isVisible(); diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 58817485fb..b40789db9c 100755 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -2021,7 +2021,7 @@ void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/)  	{  		LLMultiFloater::setMinimized(FALSE);  	} -	 +  	LLFloater::closeFloater(app_quitting);  } diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index 1b3318a730..6116f693e6 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -111,7 +111,7 @@ void LLFloaterIMSession::refresh()  void LLFloaterIMSession::onTearOffClicked()  {      LLFloaterIMSessionTab::onTearOffClicked(); -	 +      if(mIsP2PChat)      {          if(isTornOff()) @@ -333,7 +333,7 @@ void LLFloaterIMSession::initIMFloater()  BOOL LLFloaterIMSession::postBuild()  {  	BOOL result = LLFloaterIMSessionTab::postBuild(); -	 +  	mInputEditor->setMaxTextLength(1023);  	mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5));  	mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) ); @@ -360,7 +360,7 @@ BOOL LLFloaterIMSession::postBuild()  	return result;  } -	 +  void LLFloaterIMSession::onAddButtonClicked()  {      LLView * button = findChild<LLView>("toolbar_panel")->findChild<LLButton>("add_btn"); @@ -373,7 +373,7 @@ void LLFloaterIMSession::onAddButtonClicked()  	// Need to disable 'ok' button when selected users are already in conversation.  	picker->setOkBtnEnableCb(boost::bind(&LLFloaterIMSession::canAddSelectedToChat, this, _1)); - +	  	if (root_floater)  	{  		root_floater->addDependentFloater(picker); @@ -428,7 +428,7 @@ bool LLFloaterIMSession::canAddSelectedToChat(const uuid_vec_t& uuids)  			}  		}  	} -	 +  	return true;  } @@ -602,7 +602,7 @@ LLFloaterIMSession* LLFloaterIMSession::findInstance(const LLUUID& session_id)  	return conversation;  } -			 +  LLFloaterIMSession* LLFloaterIMSession::getInstance(const LLUUID& session_id)  {  	LLFloaterIMSession* conversation = @@ -782,7 +782,7 @@ void LLFloaterIMSession::sessionInitReplyReceived(const LLUUID& im_session_id)  		initIMSession(im_session_id);  		buildConversationViewParticipant();  	} -	 +  	initIMFloater();  	LLFloaterIMSessionTab::updateGearBtn();  	//*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB) diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 85fe901fde..49ddcc7d18 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -3882,14 +3882,14 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim  	for (LLModelLoader::scene::iterator iter = mBaseScene.begin(), endIter = mBaseScene.end(); iter != endIter; ++iter)  	{  		for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance) -	{ +		{  			LLModel* mdl = instance->mModel;  			if (mdl) -		{ +			{  				instanced_triangle_count += mdl->getNumTriangles();  			}  		} -		} +	}  	//get the triangle count for the non-instanced set of models  	for (U32 i = 0; i < mBaseModel.size(); ++i) @@ -4230,28 +4230,28 @@ void LLModelPreview::updateStatusMessages()  				if (model)  				{  					 //for each model in the lod -			S32 cur_tris = 0; -			S32 cur_verts = 0; +					S32 cur_tris = 0; +					S32 cur_verts = 0;  					S32 cur_submeshes = model->getNumVolumeFaces(); -			for (S32 j = 0; j < cur_submeshes; ++j) -			{ //for each submesh (face), add triangles and vertices to current total +					for (S32 j = 0; j < cur_submeshes; ++j) +					{ //for each submesh (face), add triangles and vertices to current total  						const LLVolumeFace& face = model->getVolumeFace(j); -				cur_tris += face.mNumIndices/3; -				cur_verts += face.mNumVertices; -			} +						cur_tris += face.mNumIndices/3; +						cur_verts += face.mNumVertices; +					} -			//add this model to the lod total -			total_tris[lod] += cur_tris; -			total_verts[lod] += cur_verts; -			total_submeshes[lod] += cur_submeshes; +					//add this model to the lod total +					total_tris[lod] += cur_tris; +					total_verts[lod] += cur_verts; +					total_submeshes[lod] += cur_submeshes; -			//store this model's counts to asset data -			tris[lod].push_back(cur_tris); -			verts[lod].push_back(cur_verts); -			submeshes[lod].push_back(cur_submeshes); -		} -	} +					//store this model's counts to asset data +					tris[lod].push_back(cur_tris); +					verts[lod].push_back(cur_verts); +					submeshes[lod].push_back(cur_submeshes); +				} +			}  		}  	} @@ -4440,29 +4440,29 @@ void LLModelPreview::updateStatusMessages()  			LLModel* model = instance->mModel;  			if (model)  			{ -		S32 cur_submeshes = model->getNumVolumeFaces(); +				S32 cur_submeshes = model->getNumVolumeFaces(); -		LLModel::convex_hull_decomposition& decomp = model->mPhysics.mHull; +				LLModel::convex_hull_decomposition& decomp = model->mPhysics.mHull; -		if (!decomp.empty()) -		{ -			phys_hulls += decomp.size(); -			for (U32 i = 0; i < decomp.size(); ++i) -			{ -				phys_points += decomp[i].size(); -			} -		} -		else -		{ //choose physics shape OR decomposition, can't use both -			for (S32 j = 0; j < cur_submeshes; ++j) -			{ //for each submesh (face), add triangles and vertices to current total -				const LLVolumeFace& face = model->getVolumeFace(j); -				phys_tris += face.mNumIndices/3; +				if (!decomp.empty()) +				{ +					phys_hulls += decomp.size(); +					for (U32 i = 0; i < decomp.size(); ++i) +					{ +						phys_points += decomp[i].size(); +					} +				} +				else +				{ //choose physics shape OR decomposition, can't use both +					for (S32 j = 0; j < cur_submeshes; ++j) +					{ //for each submesh (face), add triangles and vertices to current total +						const LLVolumeFace& face = model->getVolumeFace(j); +						phys_tris += face.mNumIndices/3; +					} +				}  			}  		}  	} -		} -	}  	if (phys_tris > 0)  	{ diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index bbf88060c1..55b03986d0 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1089,8 +1089,9 @@ void LLFloaterPreference::refreshEnabledState()  	ctrl_reflections->setEnabled(reflections);  	// Bump & Shiny	 +	LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny");  	bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump"); -	getChild<LLCheckBoxCtrl>("BumpShiny")->setEnabled(bumpshiny ? TRUE : FALSE); +	bumpshiny_ctrl->setEnabled(bumpshiny ? TRUE : FALSE);  	radio_reflection_detail->setEnabled(reflections); @@ -1148,7 +1149,8 @@ void LLFloaterPreference::refreshEnabledState()  	//Deferred/SSAO/Shadows  	LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders"); -	BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&  +	BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && +						((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&  						shaders &&   						gGLManager.mHasFramebufferObject &&  						gSavedSettings.getBOOL("RenderAvatarVP") && @@ -1161,7 +1163,9 @@ void LLFloaterPreference::refreshEnabledState()  	LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail");  	enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE); -		 +	 +	ctrl_deferred->set(gSavedSettings.getBOOL("RenderDeferred")); +  	ctrl_ssao->setEnabled(enabled);  	ctrl_dof->setEnabled(enabled); @@ -2319,3 +2323,4 @@ void LLFloaterPreferenceProxy::onChangeSocksSettings()  	}  } + diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp index 5c6ce9d311..16ed3f990c 100755 --- a/indra/newview/llfriendcard.cpp +++ b/indra/newview/llfriendcard.cpp @@ -521,7 +521,7 @@ public:  	void fire(const LLUUID& inv_item_id)  	{  		LLViewerInventoryItem* item = gInventory.getItem(inv_item_id); -		 +  		if (item)  			LLFriendCardsManager::instance().extractAvatarID(item->getCreatorUUID());  	} diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp index 7e1025c41b..825c2b31be 100755 --- a/indra/newview/llhudicon.cpp +++ b/indra/newview/llhudicon.cpp @@ -202,7 +202,7 @@ void LLHUDIcon::render()  	renderIcon(FALSE);  } -BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3* intersection) +BOOL LLHUDIcon::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection)  {  	if (mHidden)  		return FALSE; @@ -275,23 +275,18 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& en  	LLVector4a upper_right;  	upper_right.setAdd(lower_right, y_scalea); -	LLVector4a enda; -	enda.load3(end.mV); -	LLVector4a starta; -	starta.load3(start.mV);  	LLVector4a dir; -	dir.setSub(enda, starta); +	dir.setSub(end, start);  	F32 a,b,t; -	if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, starta, dir, a,b,t) || -		LLTriangleRayIntersect(upper_left, lower_left, lower_right, starta, dir, a,b,t)) +	if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, start, dir, a,b,t) || +		LLTriangleRayIntersect(upper_left, lower_left, lower_right, start, dir, a,b,t))  	{  		if (intersection)  		{  			dir.mul(t); -			starta.add(dir); -			*intersection = LLVector3(starta.getF32ptr()); +			intersection->setAdd(start, dir);  		}  		return TRUE;  	} @@ -331,12 +326,12 @@ LLHUDIcon* LLHUDIcon::handlePick(S32 pick_id)  }  //static -LLHUDIcon* LLHUDIcon::lineSegmentIntersectAll(const LLVector3& start, const LLVector3& end, LLVector3* intersection) +LLHUDIcon* LLHUDIcon::lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection)  {  	icon_instance_t::iterator icon_it; -	LLVector3 local_end = end; -	LLVector3 position; +	LLVector4a local_end = end; +	LLVector4a position;  	LLHUDIcon* ret = NULL;  	for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it) diff --git a/indra/newview/llhudicon.h b/indra/newview/llhudicon.h index 2bbc9c839d..87455ec3f4 100755 --- a/indra/newview/llhudicon.h +++ b/indra/newview/llhudicon.h @@ -59,7 +59,7 @@ public:  	static S32 generatePickIDs(S32 start_id, S32 step_size);  	static LLHUDIcon* handlePick(S32 pick_id); -	static LLHUDIcon* lineSegmentIntersectAll(const LLVector3& start, const LLVector3& end, LLVector3* intersection); +	static LLHUDIcon* lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection);  	static void updateAll();  	static void cleanupDeadIcons(); @@ -70,7 +70,7 @@ public:  	BOOL getHidden() const { return mHidden; }  	void setHidden( BOOL hide ) { mHidden = hide; } -	BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3* intersection); +	BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection);  protected:  	LLHUDIcon(const U8 type); diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index f43b478f60..19a4165b49 100755 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -117,7 +117,7 @@ LLHUDNameTag::~LLHUDNameTag()  } -BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render) +BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a& intersection, BOOL debug_render)  {  	if (!mVisible || mHidden)  	{ @@ -200,15 +200,23 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3&  		bg_pos + height_vec,  	}; -	LLVector3 dir = end-start; +	LLVector4a dir; +	dir.setSub(end,start);  	F32 a, b, t; -	if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) || -		LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) ) +	LLVector4a v0,v1,v2,v3; +	v0.load3(v[0].mV); +	v1.load3(v[1].mV); +	v2.load3(v[2].mV); +	v3.load3(v[3].mV); + +	if (LLTriangleRayIntersect(v0, v1, v2, start, dir, a, b, t) || +		LLTriangleRayIntersect(v2, v3, v0, start, dir, a, b, t) )  	{  		if (t <= 1.f)  		{ -			intersection = start + dir*t; +			dir.mul(t); +			intersection.setAdd(start, dir);  			return TRUE;  		}  	} @@ -311,7 +319,7 @@ void LLHUDNameTag::renderText(BOOL for_select)  		label_top_rect.mBottom = label_top_rect.mTop - label_height;  		LLColor4 label_top_color = text_color;  		label_top_color.mV[VALPHA] = gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor; -		 +  		rect_top_image->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color);  	} diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h index 72647d5b26..38a4f18415 100755 --- a/indra/newview/llhudnametag.h +++ b/indra/newview/llhudnametag.h @@ -124,7 +124,7 @@ public:  	void setHidden( BOOL hide ) { mHidden = hide; }  	void shift(const LLVector3& offset); -	BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render = FALSE); +	BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a& intersection, BOOL debug_render = FALSE);  	static void shiftAll(const LLVector3& offset);  	static void addPickable(std::set<LLViewerObject*> &pick_list); diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index c62871236b..7e18d37fe1 100755 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -1052,7 +1052,7 @@ const std::string LLIMModel::getName(const LLUUID& session_id) const  {  	LLIMSession* session = findIMSession(session_id); -	if (!session)  +	if (!session)  	{  		llwarns << "session " << session_id << "does not exist " << llendl;  		return LLTrans::getString("no_session_message"); @@ -1562,7 +1562,7 @@ public:  	}  	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content) -	{		 +	{  		llwarns << "LLViewerChatterBoxInvitationAcceptResponder error [status:"  				<< statusNum << "]: " << content << llendl;  		//throw something back to the viewer here? @@ -2685,7 +2685,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess  		LLChat chat(message);  		chat.mSourceType = CHAT_SOURCE_SYSTEM; -		 +  		LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");  		if (nearby_chat)  		{ diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index ce9f17663c..9c6db3676f 100755 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -67,7 +67,7 @@ public:  	// Inspector will be positioned relative to current mouse position  	LLInspectAvatar(const LLSD& avatar_id);  	virtual ~LLInspectAvatar(); -	 +  	/*virtual*/ BOOL postBuild(void);  	// Because floater is single instance, need to re-parse data on each spawn @@ -83,7 +83,7 @@ private:  	// Make network requests for all the data to display in this view.  	// Used on construction and if avatar id changes.  	void requestUpdate(); -	 +  	// Set the volume slider to this user's current client-side volume setting,  	// hiding/disabling if the user is not nearby.  	void updateVolumeSlider(); @@ -221,7 +221,7 @@ void LLInspectAvatar::onOpen(const LLSD& data)  	requestUpdate();  	updateVolumeSlider(); -}	 +}  void LLInspectAvatar::requestUpdate()  { diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index d05bdd0a6d..c8ee8135a6 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -3223,7 +3223,7 @@ void LLFolderBridge::pasteFromClipboard()  						LLViewerInventoryCategory* vicat = (LLViewerInventoryCategory *) model->getCategory(item_id);  						llassert(vicat);  						if (vicat) -						{ +						{                                     //changeCategoryParent() implicity calls dirtyFilter  							changeCategoryParent(model, vicat, parent_id, FALSE);  						} diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index f2b39e7186..d88e0c3192 100755 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -686,23 +686,23 @@ void LLInventoryModelBackgroundFetch::bulkFetch()  	{  		if (folder_count)  		{ -			std::string url = region->getCapability("FetchInventoryDescendents2");   			 +			std::string url = region->getCapability("FetchInventoryDescendents2");     			if ( !url.empty() )  			{ -				mFetchCount++; -				if (folder_request_body["folders"].size()) -				{ -					LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats); -					LLHTTPClient::post(url, folder_request_body, fetcher, 300.0); -				} -				if (folder_request_body_lib["folders"].size()) -				{ -					std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2"); +			mFetchCount++; +			if (folder_request_body["folders"].size()) +			{ +				LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats); +				LLHTTPClient::post(url, folder_request_body, fetcher, 300.0); +			} +			if (folder_request_body_lib["folders"].size()) +			{ +				std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2"); -					LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats); -					LLHTTPClient::post(url_lib, folder_request_body_lib, fetcher, 300.0); -				} -			}					 +				LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats); +				LLHTTPClient::post(url_lib, folder_request_body_lib, fetcher, 300.0); +			} +		}  		}  		if (item_count)  		{ diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index bd3c70b7f5..4fdb05bc82 100755 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -734,7 +734,7 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge  	params.listener = bridge;  	params.rect = LLRect (0, 0, 0, 0);  	params.tool_tip = params.name; -	 +  	params.font_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultColor));  	params.font_highlight_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultHighlightColor)); diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 33143b4671..8b088da12e 100755 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -59,6 +59,8 @@  #include "lltexlayerparams.h"  #include "llvovolume.h"  #include "llnotificationsutil.h" +#include "pipeline.h" +#include "llmaterialmgr.h"  /*=======================================*/  /*  Formal declarations, constants, etc. */ @@ -340,7 +342,12 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)  		return;  	} -	updateUserPrims(old_id, new_id); +	// processing updates per channel; makes the process scalable. +	// the only actual difference is in SetTE* call i.e. SetTETexture, SetTENormal, etc. +	updateUserPrims(old_id, new_id, LLRender::DIFFUSE_MAP); +	updateUserPrims(old_id, new_id, LLRender::NORMAL_MAP); +	updateUserPrims(old_id, new_id, LLRender::SPECULAR_MAP); +	  	updateUserSculpts(old_id, new_id); // isn't there supposed to be an IMG_DEFAULT_SCULPT or something?  	// default safeguard image for layers @@ -368,15 +375,15 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)  // this function sorts the faces from a getFaceList[getNumFaces] into a list of objects  // in order to prevent multiple sendTEUpdate calls per object during updateUserPrims -std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id) +std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id, U32 channel)  {  	std::vector<LLViewerObject*> obj_list;  	LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id); -	for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(); face_iterator++) +	for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(channel); face_iterator++)  	{  		// getting an object from a face -		LLFace* face_to_object = (*old_texture->getFaceList())[face_iterator]; +		LLFace* face_to_object = (*old_texture->getFaceList(channel))[face_iterator];  		if(face_to_object)  		{ @@ -417,9 +424,9 @@ std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id)  	return obj_list;  } -void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id) +void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel)  { -	std::vector<LLViewerObject*> objectlist = prepUpdateObjects(old_id); +	std::vector<LLViewerObject*> objectlist = prepUpdateObjects(old_id, channel);  	for(std::vector<LLViewerObject*>::iterator object_iterator = objectlist.begin();  		object_iterator != objectlist.end(); object_iterator++) @@ -428,7 +435,8 @@ void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id)  		if(object)  		{ -			bool update_obj = false; +			bool update_tex = false; +			bool update_mat = false;  			S32 num_faces = object->getNumFaces();  			for (U8 face_iter = 0; face_iter < num_faces; face_iter++) @@ -436,20 +444,51 @@ void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id)  				if (object->mDrawable)  				{  					LLFace* face = object->mDrawable->getFace(face_iter); -					if (face && face->getTexture() && face->getTexture()->getID() == old_id) +					if (face && face->getTexture(channel) && face->getTexture(channel)->getID() == old_id) +					{ +						// these things differ per channel, unless there already is a universal +						// texture setting function to setTE that takes channel as a param? +						// p.s.: switch for now, might become if - if an extra test is needed to verify before touching normalmap/specmap +						switch(channel) +						{ +							case LLRender::DIFFUSE_MAP:  					{ -						object->setTEImage(face_iter, LLViewerTextureManager::getFetchedTexture( -							new_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); +                                object->setTETexture(face_iter, new_id); +                                update_tex = true; +								break; +							} + +							case LLRender::NORMAL_MAP: +							{ +								object->setTENormalMap(face_iter, new_id); +								update_mat = true; +								update_tex = true; +                                break; +							} + +							case LLRender::SPECULAR_MAP: +							{ +								object->setTESpecularMap(face_iter, new_id); +                                update_mat = true; +								update_tex = true; +                                break; +							} +						} +						// end switch -						update_obj = true;  					}  				}  			} -			if (update_obj) +			if (update_tex)  			{  				object->sendTEUpdate();  			} + +			if (update_mat) +			{ +                object->mDrawable->getVOVolume()->faceMappingChanged(); +			}  		}  	} diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h index b404345799..47c077dcab 100755 --- a/indra/newview/lllocalbitmaps.h +++ b/indra/newview/lllocalbitmaps.h @@ -62,8 +62,8 @@ class LLLocalBitmap  	private: /* self update private section */  		bool decodeBitmap(LLPointer<LLImageRaw> raw);  		void replaceIDs(LLUUID old_id, LLUUID new_id); -		std::vector<LLViewerObject*> prepUpdateObjects(LLUUID old_id); -		void updateUserPrims(LLUUID old_id, LLUUID new_id); +		std::vector<LLViewerObject*> prepUpdateObjects(LLUUID old_id, U32 channel); +		void updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel);  		void updateUserSculpts(LLUUID old_id, LLUUID new_id);  		void updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableType::EType type);  		LLAvatarAppearanceDefines::ETextureIndex getTexIndex(LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind); diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 977c50682f..f681c12747 100755 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -642,6 +642,8 @@ bool LLLoginInstance::handleLoginEvent(const LLSD& event)  void LLLoginInstance::handleLoginFailure(const LLSD& event)  { +	 +  	// Login has failed.   	// Figure out why and respond...  	LLSD response = event["data"]; @@ -654,10 +656,13 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)  	// to reconnect or to end the attempt in failure.  	if(reason_response == "tos")  	{ +		llinfos << "LLLoginInstance::handleLoginFailure ToS" << llendl; +  		LLSD data(LLSD::emptyMap());  		data["message"] = message_response;  		data["reply_pump"] = TOS_REPLY_PUMP; -		gViewerWindow->setShowProgress(FALSE); +		if (gViewerWindow) +			gViewerWindow->setShowProgress(FALSE);  		LLFloaterReg::showInstance("message_tos", data);  		LLEventPumps::instance().obtain(TOS_REPLY_PUMP)  			.listen(TOS_LISTENER_NAME, @@ -666,6 +671,8 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)  	}  	else if(reason_response == "critical")  	{ +		llinfos << "LLLoginInstance::handleLoginFailure Crit" << llendl; +  		LLSD data(LLSD::emptyMap());  		data["message"] = message_response;  		data["reply_pump"] = TOS_REPLY_PUMP; @@ -678,7 +685,9 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)  			data["certificate"] = response["certificate"];  		} -		gViewerWindow->setShowProgress(FALSE); +		if (gViewerWindow) +			gViewerWindow->setShowProgress(FALSE); +  		LLFloaterReg::showInstance("message_critical", data);  		LLEventPumps::instance().obtain(TOS_REPLY_PUMP)  			.listen(TOS_LISTENER_NAME, @@ -687,21 +696,28 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)  	}  	else if(reason_response == "update" || gSavedSettings.getBOOL("ForceMandatoryUpdate"))  	{ +		llinfos << "LLLoginInstance::handleLoginFailure update" << llendl; +  		gSavedSettings.setBOOL("ForceMandatoryUpdate", FALSE);  		updateApp(true, message_response);  	}  	else if(reason_response == "optional")  	{ +		llinfos << "LLLoginInstance::handleLoginFailure optional" << llendl; +  		updateApp(false, message_response);  	}  	else  	{	 +		llinfos << "LLLoginInstance::handleLoginFailure attemptComplete" << llendl;  		attemptComplete();  	}	  }  void LLLoginInstance::handleLoginSuccess(const LLSD& event)  { +	llinfos << "LLLoginInstance::handleLoginSuccess" << llendl; +  	if(gSavedSettings.getBOOL("ForceMandatoryUpdate"))  	{  		LLSD response = event["data"]; @@ -723,6 +739,8 @@ void LLLoginInstance::handleLoginSuccess(const LLSD& event)  void LLLoginInstance::handleDisconnect(const LLSD& event)  {      // placeholder + +	llinfos << "LLLoginInstance::handleDisconnect placeholder " << llendl;  }  void LLLoginInstance::handleIndeterminate(const LLSD& event) @@ -731,10 +749,13 @@ void LLLoginInstance::handleIndeterminate(const LLSD& event)  	// gave the viewer a new url and params to try.  	// The login module handles the retry, but it gives us the  	// server response so that we may show -	// the user some status. +	// the user some status.	 +  	LLSD message = event.get("data").get("message");  	if(message.isDefined())  	{ +		llinfos << "LLLoginInstance::handleIndeterminate " << message.asString() << llendl; +  		LLSD progress_update;  		progress_update["desc"] = message;  		LLEventPumps::getInstance()->obtain("LLProgressView").post(progress_update); @@ -745,12 +766,16 @@ bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key)  {  	if(accepted)  	{	 +		llinfos << "LLLoginInstance::handleTOSResponse: accepted" << llendl; +  		// Set the request data to true and retry login.  		mRequestData["params"][key] = true;   		reconnect();  	}  	else  	{ +		llinfos << "LLLoginInstance::handleTOSResponse: attemptComplete" << llendl; +  		attemptComplete();  	} diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp new file mode 100644 index 0000000000..16871adc4d --- /dev/null +++ b/indra/newview/llmaterialmgr.cpp @@ -0,0 +1,782 @@ +/** + * @file llmaterialmgr.cpp + * @brief Material manager + * + * $LicenseInfo:firstyear=2013&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llsdserialize.h" +#include "llsdutil.h" + +#include "llagent.h" +#include "llcallbacklist.h" +#include "llmaterialmgr.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "llworld.h" + +/** + * Materials cap parameters + */ + +#define MATERIALS_CAPABILITY_NAME                 "RenderMaterials" + +#define MATERIALS_CAP_ZIP_FIELD                   "Zipped" + +#define MATERIALS_CAP_FULL_PER_FACE_FIELD         "FullMaterialsPerFace" +#define MATERIALS_CAP_FACE_FIELD                  "Face" +#define MATERIALS_CAP_MATERIAL_FIELD              "Material" +#define MATERIALS_CAP_OBJECT_ID_FIELD             "ID" +#define MATERIALS_CAP_MATERIAL_ID_FIELD           "MaterialID" + +#define MATERIALS_GET_MAX_ENTRIES                 50 +#define MATERIALS_GET_TIMEOUT                     (60.f * 20) +#define MATERIALS_POST_MAX_ENTRIES                50 +#define MATERIALS_POST_TIMEOUT                    (60.f * 5) +#define MATERIALS_PUT_THROTTLE_SECS               1.f +#define MATERIALS_PUT_MAX_ENTRIES                 50 + +/** + * LLMaterialsResponder helper class + */ + +class LLMaterialsResponder : public LLHTTPClient::Responder +{ +public: +	typedef boost::function<void (bool, const LLSD&)> CallbackFunction; + +	LLMaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback); +	virtual ~LLMaterialsResponder(); + +	virtual void result(const LLSD& pContent); +	virtual void error(U32 pStatus, const std::string& pReason); + +private: +	std::string      mMethod; +	std::string      mCapabilityURL; +	CallbackFunction mCallback; +}; + +LLMaterialsResponder::LLMaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback) +	: LLHTTPClient::Responder() +	, mMethod(pMethod) +	, mCapabilityURL(pCapabilityURL) +	, mCallback(pCallback) +{ +} + +LLMaterialsResponder::~LLMaterialsResponder() +{ +} + +void LLMaterialsResponder::result(const LLSD& pContent) +{ +	LL_DEBUGS("Materials") << LL_ENDL; +	mCallback(true, pContent); +} + +void LLMaterialsResponder::error(U32 pStatus, const std::string& pReason) +{ +	LL_WARNS("Materials") +		<< "\n--------------------------------------------------------------------------\n" +		<< mMethod << " Error[" << pStatus << "] cannot access cap '" << MATERIALS_CAPABILITY_NAME +		<< "'\n  with url '" << mCapabilityURL	<< "' because " << pReason  +		<< "\n--------------------------------------------------------------------------" +		<< LL_ENDL; + +	LLSD emptyResult; +	mCallback(false, emptyResult); +} + +/** + * LLMaterialMgr class + */ + +LLMaterialMgr::LLMaterialMgr() +{ +	mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(LLMaterialID::null, LLMaterialPtr(NULL))); +	gIdleCallbacks.addFunction(&LLMaterialMgr::onIdle, NULL); +	LLWorld::instance().setRegionRemovedCallback(boost::bind(&LLMaterialMgr::onRegionRemoved, this, _1)); +} + +LLMaterialMgr::~LLMaterialMgr() +{ +	gIdleCallbacks.deleteFunction(&LLMaterialMgr::onIdle, NULL); +} + +bool LLMaterialMgr::isGetPending(const LLUUID& region_id, const LLMaterialID& material_id) const +{ +	get_pending_map_t::const_iterator itPending = mGetPending.find(pending_material_t(region_id, material_id)); +	return (mGetPending.end() != itPending) && (LLFrameTimer::getTotalSeconds() < itPending->second + MATERIALS_POST_TIMEOUT); +} + +void LLMaterialMgr::markGetPending(const LLUUID& region_id, const LLMaterialID& material_id) +{ +	get_pending_map_t::iterator itPending = mGetPending.find(pending_material_t(region_id, material_id)); +	if (mGetPending.end() == itPending) +	{ +		mGetPending.insert(std::pair<pending_material_t, F64>(pending_material_t(region_id, material_id), LLFrameTimer::getTotalSeconds())); +	} +	else +	{ +		itPending->second = LLFrameTimer::getTotalSeconds(); +	} +} + +const LLMaterialPtr LLMaterialMgr::get(const LLUUID& region_id, const LLMaterialID& material_id) +{ +	LL_DEBUGS("Materials") << "region " << region_id << " material id " << material_id << LL_ENDL; +	LLMaterialPtr material; +	material_map_t::const_iterator itMaterial = mMaterials.find(material_id); +	if (mMaterials.end() != itMaterial) +	{ +		material = itMaterial->second; +		LL_DEBUGS("Materials") << " found material " << LL_ENDL; +	} +	else +	{ +		if (!isGetPending(region_id, material_id)) +		{ +			LL_DEBUGS("Materials") << " material pending " << material_id << LL_ENDL; +			get_queue_t::iterator itQueue = mGetQueue.find(region_id); +			if (mGetQueue.end() == itQueue) +			{ +				LL_DEBUGS("Materials") << "mGetQueue add region " << region_id << " pending " << material_id << LL_ENDL; +				std::pair<get_queue_t::iterator, bool> ret = mGetQueue.insert(std::pair<LLUUID, material_queue_t>(region_id, material_queue_t())); +				itQueue = ret.first; +			} +			itQueue->second.insert(material_id); +			markGetPending(region_id, material_id); +		} +		LL_DEBUGS("Materials") << " returning empty material " << LL_ENDL; +		material = LLMaterialPtr(); +	} +	return material; +} + +boost::signals2::connection LLMaterialMgr::get(const LLUUID& region_id, const LLMaterialID& material_id, LLMaterialMgr::get_callback_t::slot_type cb) +{ +	boost::signals2::connection connection; +	 +	material_map_t::const_iterator itMaterial = mMaterials.find(material_id); +	if (itMaterial != mMaterials.end()) +	{ +		LL_DEBUGS("Materials") << "region " << region_id << " found materialid " << material_id << LL_ENDL; +		get_callback_t signal; +		signal.connect(cb); +		signal(material_id, itMaterial->second); +		connection = boost::signals2::connection(); +	} +	else +	{ +		if (!isGetPending(region_id, material_id)) +		{ +			get_queue_t::iterator itQueue = mGetQueue.find(region_id); +			if (mGetQueue.end() == itQueue) +			{ +				LL_DEBUGS("Materials") << "mGetQueue inserting region "<<region_id << LL_ENDL; +				std::pair<get_queue_t::iterator, bool> ret = mGetQueue.insert(std::pair<LLUUID, material_queue_t>(region_id, material_queue_t())); +				itQueue = ret.first; +			} +			LL_DEBUGS("Materials") << "adding material id " << material_id << LL_ENDL; +			itQueue->second.insert(material_id); +			markGetPending(region_id, material_id); +		} + +		get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id); +		if (itCallback == mGetCallbacks.end()) +		{ +			std::pair<get_callback_map_t::iterator, bool> ret = mGetCallbacks.insert(std::pair<LLMaterialID, get_callback_t*>(material_id, new get_callback_t())); +			itCallback = ret.first; +		} +		connection = itCallback->second->connect(cb);; +	} +	 +	return connection; +} + +boost::signals2::connection LLMaterialMgr::getTE(const LLUUID& region_id, const LLMaterialID& material_id, U32 te, LLMaterialMgr::get_callback_te_t::slot_type cb) +{ +	boost::signals2::connection connection; + +	material_map_t::const_iterator itMaterial = mMaterials.find(material_id); +	if (itMaterial != mMaterials.end()) +	{ +		LL_DEBUGS("Materials") << "region " << region_id << " found materialid " << material_id << LL_ENDL; +		get_callback_te_t signal; +		signal.connect(cb); +		signal(material_id, itMaterial->second, te); +		connection = boost::signals2::connection(); +	} +	else +	{ +		if (!isGetPending(region_id, material_id)) +		{ +			get_queue_t::iterator itQueue = mGetQueue.find(region_id); +			if (mGetQueue.end() == itQueue) +			{ +				LL_DEBUGS("Materials") << "mGetQueue inserting region "<<region_id << LL_ENDL; +				std::pair<get_queue_t::iterator, bool> ret = mGetQueue.insert(std::pair<LLUUID, material_queue_t>(region_id, material_queue_t())); +				itQueue = ret.first; +			} +			LL_DEBUGS("Materials") << "adding material id " << material_id << LL_ENDL; +			itQueue->second.insert(material_id); +			markGetPending(region_id, material_id); +		} + +		TEMaterialPair te_mat_pair; +		te_mat_pair.te = te; +		te_mat_pair.materialID = material_id; + +		get_callback_te_map_t::iterator itCallback = mGetTECallbacks.find(te_mat_pair); +		if (itCallback == mGetTECallbacks.end()) +		{ +			std::pair<get_callback_te_map_t::iterator, bool> ret = mGetTECallbacks.insert(std::pair<TEMaterialPair, get_callback_te_t*>(te_mat_pair, new get_callback_te_t())); +			itCallback = ret.first; +		} +		connection = itCallback->second->connect(cb); +	} + +	return connection; +} + +bool LLMaterialMgr::isGetAllPending(const LLUUID& region_id) const +{ +	getall_pending_map_t::const_iterator itPending = mGetAllPending.find(region_id); +	return (mGetAllPending.end() != itPending) && (LLFrameTimer::getTotalSeconds() < itPending->second + MATERIALS_GET_TIMEOUT); +} + +void LLMaterialMgr::getAll(const LLUUID& region_id) +{ +	if (!isGetAllPending(region_id)) +	{ +		LL_DEBUGS("Materials") << "queuing for region " << region_id << LL_ENDL; +		mGetAllQueue.insert(region_id); +	} +	else +	{ +		LL_DEBUGS("Materials") << "already pending for region " << region_id << LL_ENDL; +	} +} + +boost::signals2::connection LLMaterialMgr::getAll(const LLUUID& region_id, LLMaterialMgr::getall_callback_t::slot_type cb) +{ +	if (!isGetAllPending(region_id)) +	{ +		mGetAllQueue.insert(region_id); +	} + +	getall_callback_map_t::iterator itCallback = mGetAllCallbacks.find(region_id); +	if (mGetAllCallbacks.end() == itCallback) +	{ +		std::pair<getall_callback_map_t::iterator, bool> ret = mGetAllCallbacks.insert(std::pair<LLUUID, getall_callback_t*>(region_id, new getall_callback_t())); +		itCallback = ret.first; +	} +	return itCallback->second->connect(cb);; +} + +void LLMaterialMgr::put(const LLUUID& object_id, const U8 te, const LLMaterial& material) +{ +	put_queue_t::iterator itQueue = mPutQueue.find(object_id); +	if (mPutQueue.end() == itQueue) +	{ +		LL_DEBUGS("Materials") << "mPutQueue insert object " << object_id << LL_ENDL; +		mPutQueue.insert(std::pair<LLUUID, facematerial_map_t>(object_id, facematerial_map_t())); +		itQueue = mPutQueue.find(object_id); +	} + +	facematerial_map_t::iterator itFace = itQueue->second.find(te); +	if (itQueue->second.end() == itFace) +	{ +		itQueue->second.insert(std::pair<U8, LLMaterial>(te, material)); +	} +	else +	{ +		itFace->second = material; +	} +} + +void LLMaterialMgr::remove(const LLUUID& object_id, const U8 te) +{ +	put(object_id, te, LLMaterial::null); +} + +const LLMaterialPtr LLMaterialMgr::setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data) +{ +	LL_DEBUGS("Materials") << "region " << region_id << " material id " << material_id << LL_ENDL; +	material_map_t::const_iterator itMaterial = mMaterials.find(material_id); +	if (mMaterials.end() == itMaterial) +	{ +		LL_DEBUGS("Materials") << "new material" << LL_ENDL; +		LLMaterialPtr newMaterial(new LLMaterial(material_data)); +		std::pair<material_map_t::const_iterator, bool> ret = mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(material_id, newMaterial)); +		itMaterial = ret.first; +	} + +	TEMaterialPair te_mat_pair; +	te_mat_pair.materialID = material_id; + +	U32 i = 0; +	while (i < LLTEContents::MAX_TES) +	{ +		te_mat_pair.te = i++; +		get_callback_te_map_t::iterator itCallbackTE = mGetTECallbacks.find(te_mat_pair); +		if (itCallbackTE != mGetTECallbacks.end()) +		{ +			(*itCallbackTE->second)(material_id, itMaterial->second, te_mat_pair.te); +			delete itCallbackTE->second; +			mGetTECallbacks.erase(itCallbackTE); +		} +	} + +	get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id); +	if (itCallback != mGetCallbacks.end()) +	{ +		(*itCallback->second)(material_id, itMaterial->second); + +		delete itCallback->second; +		mGetCallbacks.erase(itCallback); +	} + +	mGetPending.erase(pending_material_t(region_id, material_id)); + +	return itMaterial->second; +} + +void LLMaterialMgr::onGetResponse(bool success, const LLSD& content, const LLUUID& region_id) +{ +	if (!success) +	{ +		// *TODO: is there any kind of error handling we can do here? +		LL_WARNS("Materials")<< "failed"<<LL_ENDL; +		return; +	} + +	llassert(content.isMap()); +	llassert(content.has(MATERIALS_CAP_ZIP_FIELD)); +	llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary()); + +	LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); +	std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size()); +	std::istringstream content_stream(content_string); + +	LLSD response_data; +	if (!unzip_llsd(response_data, content_stream, content_binary.size())) +	{ +		LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL; +		return; +	} + +	llassert(response_data.isArray()); +	LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL; +	for (LLSD::array_const_iterator itMaterial = response_data.beginArray(); itMaterial != response_data.endArray(); ++itMaterial) +	{ +		const LLSD& material_data = *itMaterial; +		llassert(material_data.isMap()); + +		llassert(material_data.has(MATERIALS_CAP_OBJECT_ID_FIELD)); +		llassert(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].isBinary()); +		LLMaterialID material_id(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].asBinary()); + +		llassert(material_data.has(MATERIALS_CAP_MATERIAL_FIELD)); +		llassert(material_data[MATERIALS_CAP_MATERIAL_FIELD].isMap()); +			 +		setMaterial(region_id, material_id, material_data[MATERIALS_CAP_MATERIAL_FIELD]); +	} +} + +void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LLUUID& region_id) +{ +	if (!success) +	{ +		// *TODO: is there any kind of error handling we can do here? +		LL_WARNS("Materials")<< "failed"<<LL_ENDL; +		return; +	} + +	llassert(content.isMap()); +	llassert(content.has(MATERIALS_CAP_ZIP_FIELD)); +	llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary()); + +	LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); +	std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size()); +	std::istringstream content_stream(content_string); + +	LLSD response_data; +	if (!unzip_llsd(response_data, content_stream, content_binary.size())) +	{ +		LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL; +		return; +	} + +	get_queue_t::iterator itQueue = mGetQueue.find(region_id); +	material_map_t materials; + +	llassert(response_data.isArray()); +	LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL; +	for (LLSD::array_const_iterator itMaterial = response_data.beginArray(); itMaterial != response_data.endArray(); ++itMaterial) +	{ +		const LLSD& material_data = *itMaterial; +		llassert(material_data.isMap()); + +		llassert(material_data.has(MATERIALS_CAP_OBJECT_ID_FIELD)); +		llassert(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].isBinary()); +		LLMaterialID material_id(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].asBinary()); +		if (mGetQueue.end() != itQueue) +		{ +			itQueue->second.erase(material_id); +		} + +		llassert(material_data.has(MATERIALS_CAP_MATERIAL_FIELD)); +		llassert(material_data[MATERIALS_CAP_MATERIAL_FIELD].isMap()); +		LLMaterialPtr material = setMaterial(region_id, material_id, material_data[MATERIALS_CAP_MATERIAL_FIELD]); +		 +		materials[material_id] = material; +	} + +	getall_callback_map_t::iterator itCallback = mGetAllCallbacks.find(region_id); +	if (itCallback != mGetAllCallbacks.end()) +	{ +		(*itCallback->second)(region_id, materials); + +		delete itCallback->second; +		mGetAllCallbacks.erase(itCallback); +	} + +	if ( (mGetQueue.end() != itQueue) && (itQueue->second.empty()) ) +	{ +		mGetQueue.erase(itQueue); +	} + +	LL_DEBUGS("Materials")<< "recording that getAll has been done for region id " << region_id << LL_ENDL;	 +	mGetAllRequested.insert(region_id); // prevents subsequent getAll requests for this region +	mGetAllPending.erase(region_id);	// Invalidates region_id +} + +void LLMaterialMgr::onPutResponse(bool success, const LLSD& content) +{ +	if (!success) +	{ +		// *TODO: is there any kind of error handling we can do here? +		LL_WARNS("Materials")<< "failed"<<LL_ENDL; +		return; +	} + +	llassert(content.isMap()); +	llassert(content.has(MATERIALS_CAP_ZIP_FIELD)); +	llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary()); + +	LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); +	std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size()); +	std::istringstream content_stream(content_string); + +	LLSD response_data; +	if (!unzip_llsd(response_data, content_stream, content_binary.size())) +	{ +		LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL; +		return; +	} +	else +	{ +		llassert(response_data.isArray()); +		LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL; +		for (LLSD::array_const_iterator faceIter = response_data.beginArray(); faceIter != response_data.endArray(); ++faceIter) +		{ +#           ifndef LL_RELEASE_FOR_DOWNLOAD +			const LLSD& face_data = *faceIter; // conditional to avoid unused variable warning +#           endif +			llassert(face_data.isMap()); + +			llassert(face_data.has(MATERIALS_CAP_OBJECT_ID_FIELD)); +			llassert(face_data[MATERIALS_CAP_OBJECT_ID_FIELD].isInteger()); +			// U32 local_id = face_data[MATERIALS_CAP_OBJECT_ID_FIELD].asInteger(); + +			llassert(face_data.has(MATERIALS_CAP_FACE_FIELD)); +			llassert(face_data[MATERIALS_CAP_FACE_FIELD].isInteger()); +			// S32 te = face_data[MATERIALS_CAP_FACE_FIELD].asInteger(); + +			llassert(face_data.has(MATERIALS_CAP_MATERIAL_ID_FIELD)); +			llassert(face_data[MATERIALS_CAP_MATERIAL_ID_FIELD].isBinary()); +			// LLMaterialID material_id(face_data[MATERIALS_CAP_MATERIAL_ID_FIELD].asBinary()); + +			// *TODO: do we really still need to process this? +		} +	} +} + +static LLFastTimer::DeclareTimer FTM_MATERIALS_IDLE("Materials"); + +void LLMaterialMgr::onIdle(void*) +{ +	LLFastTimer t(FTM_MATERIALS_IDLE); + +	LLMaterialMgr* instancep = LLMaterialMgr::getInstance(); + +	if (!instancep->mGetQueue.empty()) +	{ +		instancep->processGetQueue(); +	} + +	if (!instancep->mGetAllQueue.empty()) +	{ +		instancep->processGetAllQueue(); +	} + +	static LLFrameTimer mPutTimer; +	if ( (!instancep->mPutQueue.empty()) && (mPutTimer.hasExpired()) ) +	{ +		instancep->processPutQueue(); +		mPutTimer.resetWithExpiry(MATERIALS_PUT_THROTTLE_SECS); +	} +} + +void LLMaterialMgr::processGetQueue() +{ +	get_queue_t::iterator loopRegionQueue = mGetQueue.begin(); +	while (mGetQueue.end() != loopRegionQueue) +	{ +		get_queue_t::iterator itRegionQueue = loopRegionQueue++; + +		const LLUUID& region_id = itRegionQueue->first; +		if (isGetAllPending(region_id)) +		{ +			continue; +		} + +		const LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id); +		if (!regionp) +		{ +			LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL; +			mGetQueue.erase(itRegionQueue); +			continue; +		} +		else if (!regionp->capabilitiesReceived()) +		{ +			continue; +		} +		else if (mGetAllRequested.end() == mGetAllRequested.find(region_id)) +		{ +			LL_DEBUGS("Materials") << "calling getAll for " << regionp->getName() << LL_ENDL; +			getAll(region_id); +			continue; +		} + +		const std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME); +		if (capURL.empty()) +		{ +			LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME +				<< "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL; +			mGetQueue.erase(itRegionQueue); +			continue; +		} + +		LLSD materialsData = LLSD::emptyArray(); + +		material_queue_t& materials = itRegionQueue->second; +		material_queue_t::iterator loopMaterial = materials.begin(); +		while ( (materials.end() != loopMaterial) && (materialsData.size() <= MATERIALS_GET_MAX_ENTRIES) ) +		{ +			material_queue_t::iterator itMaterial = loopMaterial++; +			materialsData.append((*itMaterial).asLLSD()); +			materials.erase(itMaterial); +			markGetPending(region_id, *itMaterial); +		} +		if (materials.empty()) +		{ +			mGetQueue.erase(itRegionQueue); +		} +		 +		std::string materialString = zip_llsd(materialsData); + +		S32 materialSize = materialString.size(); +		if (materialSize <= 0) +		{ +			LL_ERRS("Materials") << "cannot zip LLSD binary content" << LL_ENDL; +			return; +		} + +		LLSD::Binary materialBinary; +		materialBinary.resize(materialSize); +		memcpy(materialBinary.data(), materialString.data(), materialSize); + +		LLSD postData = LLSD::emptyMap(); +		postData[MATERIALS_CAP_ZIP_FIELD] = materialBinary; + +		LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("POST", capURL, boost::bind(&LLMaterialMgr::onGetResponse, this, _1, _2, region_id)); +		LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '"<< capURL << " for " << materialsData.size() << " materials."  +			<< "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL; +		LLHTTPClient::post(capURL, postData, materialsResponder); +	} +} + +void LLMaterialMgr::processGetAllQueue() +{ +	getall_queue_t::iterator loopRegion = mGetAllQueue.begin(); +	while (mGetAllQueue.end() != loopRegion) +	{ +		getall_queue_t::iterator itRegion = loopRegion++; + +		const LLUUID& region_id = *itRegion; +		LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id); +		if (regionp == NULL) +		{ +			LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL; +			clearGetQueues(region_id);		// Invalidates region_id +			continue; +		} +		else if (!regionp->capabilitiesReceived()) +		{ +			continue; +		} + +		std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME); +		if (capURL.empty()) +		{ +			LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME +				<< "' is not defined on the current region '" << regionp->getName() << "'" << LL_ENDL; +			clearGetQueues(region_id);		// Invalidates region_id +			continue; +		} + +		LL_DEBUGS("Materials") << "GET all for region " << region_id << "url " << capURL << LL_ENDL; +		LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("GET", capURL, boost::bind(&LLMaterialMgr::onGetAllResponse, this, _1, _2, *itRegion)); +		LLHTTPClient::get(capURL, materialsResponder); +		mGetAllPending.insert(std::pair<LLUUID, F64>(region_id, LLFrameTimer::getTotalSeconds())); +		mGetAllQueue.erase(itRegion);	// Invalidates region_id +	} +} + +void LLMaterialMgr::processPutQueue() +{ +	typedef std::map<const LLViewerRegion*, LLSD> regionput_request_map; +	regionput_request_map requests; + +	put_queue_t::iterator loopQueue = mPutQueue.begin(); +	while (mPutQueue.end() != loopQueue) +	{ +		put_queue_t::iterator itQueue = loopQueue++; + +		const LLUUID& object_id = itQueue->first; +		const LLViewerObject* objectp = gObjectList.findObject(object_id); +		if ( (!objectp) || (!objectp->getRegion()) ) +		{ +			LL_WARNS("Materials") << "Object or object region is NULL" << LL_ENDL; + +			mPutQueue.erase(itQueue); +			continue; +		} + +		const LLViewerRegion* regionp = objectp->getRegion(); +		if (!regionp->capabilitiesReceived()) +		{ +			continue; +		} + +		LLSD& facesData = requests[regionp]; + +		facematerial_map_t& face_map = itQueue->second; +		facematerial_map_t::iterator itFace = face_map.begin(); +		while ( (face_map.end() != itFace) && (facesData.size() < MATERIALS_GET_MAX_ENTRIES) ) +		{ +			LLSD faceData = LLSD::emptyMap(); +			faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first); +			faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast<LLSD::Integer>(objectp->getLocalID()); +			if (!itFace->second.isNull()) +			{ +				faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD(); +			} +			facesData.append(faceData); +			face_map.erase(itFace++); +		} +		if (face_map.empty()) +		{ +			mPutQueue.erase(itQueue); +		} +	} + +	for (regionput_request_map::const_iterator itRequest = requests.begin(); itRequest != requests.end(); ++itRequest) +	{ +		std::string capURL = itRequest->first->getCapability(MATERIALS_CAPABILITY_NAME); +		if (capURL.empty()) +		{ +			LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME +				<< "' is not defined on region '" << itRequest->first->getName() << "'" << LL_ENDL; +			continue; +		} + +		LLSD materialsData = LLSD::emptyMap(); +		materialsData[MATERIALS_CAP_FULL_PER_FACE_FIELD] = itRequest->second; + +		std::string materialString = zip_llsd(materialsData); + +		S32 materialSize = materialString.size(); + +		if (materialSize > 0) +		{ +			LLSD::Binary materialBinary; +			materialBinary.resize(materialSize); +			memcpy(materialBinary.data(), materialString.data(), materialSize); + +			LLSD putData = LLSD::emptyMap(); +			putData[MATERIALS_CAP_ZIP_FIELD] = materialBinary; + +			LL_DEBUGS("Materials") << "put for " << itRequest->second.size() << " faces to region " << itRequest->first->getName() << LL_ENDL; +			LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("PUT", capURL, boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2)); +			LLHTTPClient::put(capURL, putData, materialsResponder); +		} +		else +		{ +			LL_ERRS("debugMaterials") << "cannot zip LLSD binary content" << LL_ENDL; +		} +	} +} + +void LLMaterialMgr::clearGetQueues(const LLUUID& region_id) +{ +	mGetQueue.erase(region_id); +	for (get_pending_map_t::iterator itPending = mGetPending.begin(); itPending != mGetPending.end();) +	{ +		if (region_id == itPending->first.first) +		{ +			mGetPending.erase(itPending++); +		} +		else +		{ +			++itPending; +		} +	} + +	mGetAllQueue.erase(region_id); +	mGetAllRequested.erase(region_id); +	mGetAllPending.erase(region_id); +	mGetAllCallbacks.erase(region_id); +} + +void LLMaterialMgr::onRegionRemoved(LLViewerRegion* regionp) +{ +	clearGetQueues(regionp->getRegionID()); +	// Put doesn't need clearing: objects that can't be found will clean up in processPutQueue() +} + diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h new file mode 100644 index 0000000000..e317a791ad --- /dev/null +++ b/indra/newview/llmaterialmgr.h @@ -0,0 +1,130 @@ +/** + * @file llmaterialmgr.h + * @brief Material manager + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLMATERIALMGR_H +#define LL_LLMATERIALMGR_H + +#include "llmaterial.h" +#include "llmaterialid.h" +#include "llsingleton.h" + +class LLViewerRegion; + +class LLMaterialMgr : public LLSingleton<LLMaterialMgr> +{ +	friend class LLSingleton<LLMaterialMgr>; +protected: +	LLMaterialMgr(); +	virtual ~LLMaterialMgr(); + +public: +	typedef std::map<LLMaterialID, LLMaterialPtr> material_map_t; + +	typedef boost::signals2::signal<void (const LLMaterialID&, const LLMaterialPtr)> get_callback_t; +	const LLMaterialPtr         get(const LLUUID& region_id, const LLMaterialID& material_id); +	boost::signals2::connection get(const LLUUID& region_id, const LLMaterialID& material_id, get_callback_t::slot_type cb); + +	typedef boost::signals2::signal<void (const LLMaterialID&, const LLMaterialPtr, U32 te)> get_callback_te_t; +	boost::signals2::connection getTE(const LLUUID& region_id, const LLMaterialID& material_id, U32 te, get_callback_te_t::slot_type cb); + +	typedef boost::signals2::signal<void (const LLUUID&, const material_map_t&)> getall_callback_t; +	void                        getAll(const LLUUID& region_id); +	boost::signals2::connection getAll(const LLUUID& region_id, getall_callback_t::slot_type cb); +	void put(const LLUUID& object_id, const U8 te, const LLMaterial& material); +	void remove(const LLUUID& object_id, const U8 te); + +protected: +	void clearGetQueues(const LLUUID& region_id); +	bool isGetPending(const LLUUID& region_id, const LLMaterialID& material_id) const; +	bool isGetAllPending(const LLUUID& region_id) const; +	void markGetPending(const LLUUID& region_id, const LLMaterialID& material_id); +	const LLMaterialPtr setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data); + +	static void onIdle(void*); +	void processGetQueue(); +	void onGetResponse(bool success, const LLSD& content, const LLUUID& region_id); +	void processGetAllQueue(); +	void onGetAllResponse(bool success, const LLSD& content, const LLUUID& region_id); +	void processPutQueue(); +	void onPutResponse(bool success, const LLSD& content); +	void onRegionRemoved(LLViewerRegion* regionp); + +protected: +	typedef std::set<LLMaterialID> material_queue_t; +	typedef std::map<LLUUID, material_queue_t> get_queue_t; +	get_queue_t        mGetQueue; +	typedef std::pair<const LLUUID, LLMaterialID> pending_material_t; +	typedef std::map<const pending_material_t, F64> get_pending_map_t; +	get_pending_map_t  mGetPending; +	typedef std::map<LLMaterialID, get_callback_t*> get_callback_map_t; +	get_callback_map_t mGetCallbacks; + +	// struct for TE-specific material ID query +	class TEMaterialPair +	{ +	public: + +		U32 te; +		LLMaterialID materialID; + +		bool operator==(const TEMaterialPair& b) const { return (materialID == b.materialID) && (te == b.te); } +	}; +	 +	friend inline bool operator<( +		const LLMaterialMgr::TEMaterialPair& lhs, +		const LLMaterialMgr::TEMaterialPair& rhs) +	{ +		return (lhs.te	< rhs.te) ? TRUE : +			(lhs.materialID < rhs.materialID); +	} + +	struct TEMaterialPairHasher +	{ +		enum { bucket_size = 8 }; +		size_t operator()(const TEMaterialPair& key_value) const { return *((size_t*)key_value.materialID.get());  } // cheesy, but effective +		bool   operator()(const TEMaterialPair& left, const TEMaterialPair& right) const { return left < right; } +	}; + +	typedef boost::unordered_map<TEMaterialPair, get_callback_te_t*, TEMaterialPairHasher> get_callback_te_map_t; +	get_callback_te_map_t mGetTECallbacks; + +	typedef std::set<LLUUID> getall_queue_t; +	getall_queue_t        mGetAllQueue; +	getall_queue_t        mGetAllRequested; +	typedef std::map<LLUUID, F64> getall_pending_map_t; +	getall_pending_map_t  mGetAllPending; +	typedef std::map<LLUUID, getall_callback_t*> getall_callback_map_t; +	getall_callback_map_t mGetAllCallbacks; + +	typedef std::map<U8, LLMaterial> facematerial_map_t; +	typedef std::map<LLUUID, facematerial_map_t> put_queue_t; +	put_queue_t mPutQueue; + +	material_map_t mMaterials; +}; + +#endif // LL_LLMATERIALMGR_H + diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h index 6533d55f2f..81acc31863 100755 --- a/indra/newview/llpaneleditwearable.h +++ b/indra/newview/llpaneleditwearable.h @@ -95,7 +95,7 @@ private:  	void				toggleTypeSpecificControls(LLWearableType::EType type);  	void				updateTypeSpecificControls(LLWearableType::EType type); -	// alpha mask checkboxes +	//alpha mask checkboxes  	void configureAlphaCheckbox(LLAvatarAppearanceDefines::ETextureIndex te, const std::string& name);  	void onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLAvatarAppearanceDefines::ETextureIndex te);  	void updateAlphaCheckboxes(); @@ -155,7 +155,7 @@ private:  	LLPanel *mPanelEyes;  	LLPanel *mPanelHair; -	// clothes +	//clothes  	LLPanel *mPanelShirt;  	LLPanel *mPanelPants;  	LLPanel *mPanelShoes; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index ef5b803f70..7ef427fa3e 100755 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -46,6 +46,7 @@  #include "lldrawpoolbump.h"  #include "llface.h"  #include "lllineeditor.h" +#include "llmaterialmgr.h"  #include "llmediaentry.h"  #include "llnotificationsutil.h"  #include "llresmgr.h" @@ -55,10 +56,12 @@  #include "lltexturectrl.h"  #include "lltextureentry.h"  #include "lltooldraganddrop.h" +#include "lltrans.h"  #include "llui.h"  #include "llviewercontrol.h"  #include "llviewermedia.h"  #include "llviewerobject.h" +#include "llviewerregion.h"  #include "llviewerstats.h"  #include "llvovolume.h"  #include "lluictrlfactory.h" @@ -66,6 +69,48 @@  #include "llviewertexturelist.h"  // +// Constant definitions for comboboxes +// Must match the commbobox definitions in panel_tools_texture.xml +// +const S32 MATMEDIA_MATERIAL = 0;	// Material +const S32 MATMEDIA_MEDIA = 1;		// Media +const S32 MATTYPE_DIFFUSE = 0;		// Diffuse material texture +const S32 MATTYPE_NORMAL = 1;		// Normal map +const S32 MATTYPE_SPECULAR = 2;		// Specular map +const S32 ALPHAMODE_NONE = 0;		// No alpha mask applied +const S32 ALPHAMODE_BLEND = 1;		// Alpha blending mode +const S32 ALPHAMODE_MASK = 2;		// Alpha masking mode +const S32 BUMPY_TEXTURE = 18;		// use supplied normal map +const S32 SHINY_TEXTURE = 4;		// use supplied specular map + +// +// "Use texture" label for normal/specular type comboboxes +// Filled in at initialization from translated strings +// +std::string USE_TEXTURE; + +// Things the UI provides... +// +LLUUID	LLPanelFace::getCurrentNormalMap()			{ return getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID();	} +LLUUID	LLPanelFace::getCurrentSpecularMap()		{ return getChild<LLTextureCtrl>("shinytexture control")->getImageAssetID();	} +U32		LLPanelFace::getCurrentShininess()			{ return getChild<LLComboBox>("combobox shininess")->getCurrentIndex();			} +U32		LLPanelFace::getCurrentBumpiness()			{ return getChild<LLComboBox>("combobox bumpiness")->getCurrentIndex();			} +U8			LLPanelFace::getCurrentDiffuseAlphaMode()	{ return (U8)getChild<LLComboBox>("combobox alphamode")->getCurrentIndex();	} +U8			LLPanelFace::getCurrentAlphaMaskCutoff()	{ return (U8)getChild<LLUICtrl>("maskcutoff")->getValue().asInteger();			} +U8			LLPanelFace::getCurrentEnvIntensity()		{ return (U8)getChild<LLUICtrl>("environment")->getValue().asInteger();			} +U8			LLPanelFace::getCurrentGlossiness()			{ return (U8)getChild<LLUICtrl>("glossiness")->getValue().asInteger();			} +F32		LLPanelFace::getCurrentBumpyRot()			{ return getChild<LLUICtrl>("bumpyRot")->getValue().asReal();						} +F32		LLPanelFace::getCurrentBumpyScaleU()		{ return getChild<LLUICtrl>("bumpyScaleU")->getValue().asReal();					} +F32		LLPanelFace::getCurrentBumpyScaleV()		{ return getChild<LLUICtrl>("bumpyScaleV")->getValue().asReal();					} +F32		LLPanelFace::getCurrentBumpyOffsetU()		{ return getChild<LLUICtrl>("bumpyOffsetU")->getValue().asReal();					} +F32		LLPanelFace::getCurrentBumpyOffsetV()		{ return getChild<LLUICtrl>("bumpyOffsetV")->getValue().asReal();					} +F32		LLPanelFace::getCurrentShinyRot()			{ return getChild<LLUICtrl>("shinyRot")->getValue().asReal();						} +F32		LLPanelFace::getCurrentShinyScaleU()		{ return getChild<LLUICtrl>("shinyScaleU")->getValue().asReal();					} +F32		LLPanelFace::getCurrentShinyScaleV()		{ return getChild<LLUICtrl>("shinyScaleV")->getValue().asReal();					} +F32		LLPanelFace::getCurrentShinyOffsetU()		{ return getChild<LLUICtrl>("shinyOffsetU")->getValue().asReal();					} +F32		LLPanelFace::getCurrentShinyOffsetV()		{ return getChild<LLUICtrl>("shinyOffsetV")->getValue().asReal();					} + +//  // Methods  // @@ -73,21 +118,40 @@ BOOL	LLPanelFace::postBuild()  {  	childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this);  	childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this); +	childSetCommitCallback("combobox alphamode",&LLPanelFace::onCommitAlphaMode,this);  	childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this); -	childSetCommitCallback("checkbox flip s",&LLPanelFace::onCommitTextureInfo, this);  	childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this); -	childSetCommitCallback("checkbox flip t",&LLPanelFace::onCommitTextureInfo, this);  	childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this); -	childSetAction("button apply",&LLPanelFace::onClickApply,this); +	childSetCommitCallback("rptctrl",&LLPanelFace::onCommitRepeatsPerMeter, this);  	childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this);  	childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this);  	childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this); + +	childSetCommitCallback("bumpyScaleU",&LLPanelFace::onCommitMaterialBumpyScaleX, this); +	childSetCommitCallback("bumpyScaleV",&LLPanelFace::onCommitMaterialBumpyScaleY, this); +	childSetCommitCallback("bumpyRot",&LLPanelFace::onCommitMaterialBumpyRot, this); +	childSetCommitCallback("bumpyOffsetU",&LLPanelFace::onCommitMaterialBumpyOffsetX, this); +	childSetCommitCallback("bumpyOffsetV",&LLPanelFace::onCommitMaterialBumpyOffsetY, this); +	childSetCommitCallback("shinyScaleU",&LLPanelFace::onCommitMaterialShinyScaleX, this); +	childSetCommitCallback("shinyScaleV",&LLPanelFace::onCommitMaterialShinyScaleY, this); +	childSetCommitCallback("shinyRot",&LLPanelFace::onCommitMaterialShinyRot, this); +	childSetCommitCallback("shinyOffsetU",&LLPanelFace::onCommitMaterialShinyOffsetX, this); +	childSetCommitCallback("shinyOffsetV",&LLPanelFace::onCommitMaterialShinyOffsetY, this); +	childSetCommitCallback("glossiness",&LLPanelFace::onCommitMaterialGloss, this); +	childSetCommitCallback("environment",&LLPanelFace::onCommitMaterialEnv, this); +	childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterialMaskCutoff, this); +  	childSetAction("button align",&LLPanelFace::onClickAutoFix,this);  	LLTextureCtrl*	mTextureCtrl; +	LLTextureCtrl*	mShinyTextureCtrl; +	LLTextureCtrl*	mBumpyTextureCtrl;  	LLColorSwatchCtrl*	mColorSwatch; +	LLColorSwatchCtrl*	mShinyColorSwatch;  	LLComboBox*		mComboTexGen; +	LLComboBox*		mComboMatMedia; +	LLComboBox*		mComboMatType;  	LLCheckBoxCtrl	*mCheckFullbright; @@ -97,6 +161,7 @@ BOOL	LLPanelFace::postBuild()  	LLSpinCtrl*     mCtrlGlow;  	setMouseOpaque(FALSE); +  	mTextureCtrl = getChild<LLTextureCtrl>("texture control");  	if(mTextureCtrl)  	{ @@ -106,12 +171,49 @@ BOOL	LLPanelFace::postBuild()  		mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) );  		mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));  		mTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1)); +		mTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) ); +  		mTextureCtrl->setFollowsTop();  		mTextureCtrl->setFollowsLeft();  		mTextureCtrl->setImmediateFilterPermMask(PERM_NONE);  		mTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);  	} +	mShinyTextureCtrl = getChild<LLTextureCtrl>("shinytexture control"); +	if(mShinyTextureCtrl) +	{ +		mShinyTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectSpecularTexture" ))); +		mShinyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitSpecularTexture, this, _2) ); +		mShinyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelSpecularTexture, this, _2) ); +		mShinyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectSpecularTexture, this, _2) ); +		mShinyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) ); +		 +		mShinyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2)); +		mShinyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1)); +		mShinyTextureCtrl->setFollowsTop(); +		mShinyTextureCtrl->setFollowsLeft(); +		mShinyTextureCtrl->setImmediateFilterPermMask(PERM_NONE); +		mShinyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); +	} + +	mBumpyTextureCtrl = getChild<LLTextureCtrl>("bumpytexture control"); +	if(mBumpyTextureCtrl) +	{ +		mBumpyTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectNormalTexture" ))); +		mBumpyTextureCtrl->setBlankImageAssetID(LLUUID( gSavedSettings.getString( "DefaultBlankNormalTexture" ))); +		mBumpyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitNormalTexture, this, _2) ); +		mBumpyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelNormalTexture, this, _2) ); +		mBumpyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectNormalTexture, this, _2) ); +		mBumpyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) ); + +		mBumpyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2)); +		mBumpyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1)); +		mBumpyTextureCtrl->setFollowsTop(); +		mBumpyTextureCtrl->setFollowsLeft(); +		mBumpyTextureCtrl->setImmediateFilterPermMask(PERM_NONE); +		mBumpyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); +	} +  	mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");  	if(mColorSwatch)  	{ @@ -123,6 +225,15 @@ BOOL	LLPanelFace::postBuild()  		mColorSwatch->setCanApplyImmediately(TRUE);  	} +	mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch"); +	if(mShinyColorSwatch) +	{ +		mShinyColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::onCommitShinyColor, this, _2)); +		mShinyColorSwatch->setFollowsTop(); +		mShinyColorSwatch->setFollowsLeft(); +		mShinyColorSwatch->setCanApplyImmediately(TRUE); +	} +  	mLabelColorTransp = getChild<LLTextBox>("color trans");  	if(mLabelColorTransp)  	{ @@ -152,6 +263,20 @@ BOOL	LLPanelFace::postBuild()  		mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP);	  	} +	mComboMatMedia = getChild<LLComboBox>("combobox matmedia"); +	if(mComboMatMedia) +	{ +		mComboMatMedia->setCommitCallback(LLPanelFace::onCommitMaterialsMedia,this); +		mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL); +	} + +	mComboMatType = getChild<LLComboBox>("combobox mattype"); +	if(mComboMatType) +	{ +		mComboMatType->setCommitCallback(LLPanelFace::onCommitMaterialType, this); +		mComboMatType->selectNthItem(MATTYPE_DIFFUSE); +	} +  	mCtrlGlow = getChild<LLSpinCtrl>("glow");  	if(mCtrlGlow)  	{ @@ -165,8 +290,10 @@ BOOL	LLPanelFace::postBuild()  }  LLPanelFace::LLPanelFace() -:	LLPanel() +:	LLPanel(), +	mIsAlpha(false)  { +	USE_TEXTURE = LLTrans::getString("use_texture");  } @@ -193,11 +320,31 @@ void LLPanelFace::sendTexture()  	}  } -void LLPanelFace::sendBump() +void LLPanelFace::sendBump(U32 bumpiness) +{	 +	LLTextureCtrl* bumpytexture_ctrl = getChild<LLTextureCtrl>("bumpytexture control"); +	if (bumpiness < BUMPY_TEXTURE)  {	 -	LLComboBox*	mComboBumpiness = getChild<LLComboBox>("combobox bumpiness"); -	if(!mComboBumpiness)return; -	U8 bump = (U8) mComboBumpiness->getCurrentIndex() & TEM_BUMP_MASK; +		LL_DEBUGS("Materials") << "clearing bumptexture control" << LL_ENDL;	 +		bumpytexture_ctrl->clear(); +		bumpytexture_ctrl->setImageAssetID(LLUUID());		 +	} + +	updateBumpyControls(bumpiness == BUMPY_TEXTURE, true); + +	LLUUID current_normal_map = bumpytexture_ctrl->getImageAssetID(); + +	U8 bump = (U8) bumpiness & TEM_BUMP_MASK; + +	// Clear legacy bump to None when using an actual normal map +	// +	if (!current_normal_map.isNull()) +		bump = 0; + +	// Set the normal map or reset it to null as appropriate +	// +	LLSelectedTEMaterial::setNormalID(this, current_normal_map); +  	LLSelectMgr::getInstance()->selectionSetBumpmap( bump );  } @@ -209,12 +356,28 @@ void LLPanelFace::sendTexGen()  	LLSelectMgr::getInstance()->selectionSetTexGen( tex_gen );  } -void LLPanelFace::sendShiny() +void LLPanelFace::sendShiny(U32 shininess) +{ +	LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control"); + +	if (shininess < SHINY_TEXTURE)  { -	LLComboBox*	mComboShininess = getChild<LLComboBox>("combobox shininess"); -	if(!mComboShininess)return; -	U8 shiny = (U8) mComboShininess->getCurrentIndex() & TEM_SHINY_MASK; +		texture_ctrl->clear(); +		texture_ctrl->setImageAssetID(LLUUID());		 +	} + +	LLUUID specmap = getCurrentSpecularMap(); + +	U8 shiny = (U8) shininess & TEM_SHINY_MASK; +	if (!specmap.isNull()) +		shiny = 0; + +	LLSelectedTEMaterial::setSpecularID(this, specmap); +  	LLSelectMgr::getInstance()->selectionSetShiny( shiny ); + +	updateShinyControls(!specmap.isNull(), true); +	  }  void LLPanelFace::sendFullbright() @@ -268,22 +431,16 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor  		LLSpinCtrl*	ctrlTexOffsetS = mPanel->getChild<LLSpinCtrl>("TexOffsetU");  		LLSpinCtrl*	ctrlTexOffsetT = mPanel->getChild<LLSpinCtrl>("TexOffsetV");  		LLSpinCtrl*	ctrlTexRotation = mPanel->getChild<LLSpinCtrl>("TexRot"); -		LLCheckBoxCtrl*	checkFlipScaleS = mPanel->getChild<LLCheckBoxCtrl>("checkbox flip s"); -		LLCheckBoxCtrl*	checkFlipScaleT = mPanel->getChild<LLCheckBoxCtrl>("checkbox flip t");  		LLComboBox*		comboTexGen = mPanel->getChild<LLComboBox>("combobox texgen");  		llassert(comboTexGen);  		llassert(object);  		if (ctrlTexScaleS)  		{ -			valid = !ctrlTexScaleS->getTentative() || !checkFlipScaleS->getTentative(); +			valid = !ctrlTexScaleS->getTentative(); // || !checkFlipScaleS->getTentative();  			if (valid)  			{  				value = ctrlTexScaleS->get(); -				if( checkFlipScaleS->get() ) -				{ -					value = -value; -				}  				if (comboTexGen &&  				    comboTexGen->getCurrentIndex() == 1)  				{ @@ -295,14 +452,14 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor  		if (ctrlTexScaleT)  		{ -			valid = !ctrlTexScaleT->getTentative() || !checkFlipScaleT->getTentative(); +			valid = !ctrlTexScaleT->getTentative(); // || !checkFlipScaleT->getTentative();  			if (valid)  			{  				value = ctrlTexScaleT->get(); -				if( checkFlipScaleT->get() ) -				{ -					value = -value; -				} +				//if( checkFlipScaleT->get() ) +				//{ +				//	value = -value; +				//}  				if (comboTexGen &&  				    comboTexGen->getCurrentIndex() == 1)  				{ @@ -458,16 +615,9 @@ void LLPanelFace::sendTextureInfo()  {  	if ((bool)childGetValue("checkbox planar align").asBoolean())  	{ -		struct f1 : public LLSelectedTEGetFunctor<LLFace *> -		{ -			LLFace* get(LLViewerObject* object, S32 te) -			{ -				return (object->mDrawable) ? object->mDrawable->getFace(te): NULL; -			} -		} get_last_face_func; -		LLFace* last_face; -		LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_last_face_func, last_face); - +		LLFace* last_face = NULL; +		bool identical_face =false; +		LLSelectedTE::getFace(last_face, identical_face);		  		LLPanelFaceSetAlignedTEFunctor setfunc(this, last_face);  		LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc);  	} @@ -483,6 +633,11 @@ void LLPanelFace::sendTextureInfo()  void LLPanelFace::getState()  { +	updateUI(); +} + +void LLPanelFace::updateUI() +{ //set state of UI to match state of texture entry(ies)  (calls setEnabled, setValue, etc, but NOT setVisible)  	LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();  	if( objectp @@ -492,81 +647,233 @@ void LLPanelFace::getState()  		BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced();  		// only turn on auto-adjust button if there is a media renderer and the media is loaded -		getChildView("textbox autofix")->setEnabled(editable);  		getChildView("button align")->setEnabled(editable); -		//if ( LLMediaEngine::getInstance()->getMediaRenderer () ) -		//	if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () ) -		//	{	 -		//		 -		//		//mLabelTexAutoFix->setEnabled ( editable ); -		//		 -		//		//mBtnAutoFix->setEnabled ( editable ); -		//	} -		getChildView("button apply")->setEnabled(editable); - -		bool identical; +		LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia"); +		if (combobox_matmedia) +		{ +			if (combobox_matmedia->getCurrentIndex() < MATMEDIA_MATERIAL) +			{ +				combobox_matmedia->selectNthItem(MATMEDIA_MATERIAL); +			} +		} +		else +		{ +			llwarns << "failed getChild for 'combobox matmedia'" << llendl; +		} +		getChildView("combobox matmedia")->setEnabled(editable); + +		LLComboBox* combobox_mattype = getChild<LLComboBox>("combobox mattype"); +		if (combobox_mattype) +		{ +			if (combobox_mattype->getCurrentIndex() < MATTYPE_DIFFUSE) +			{ +				combobox_mattype->selectNthItem(MATTYPE_DIFFUSE); +			} +		} +		else +		{ +			LL_WARNS("Materials") << "failed getChild for 'combobox mattype'" << LL_ENDL; +		} +		getChildView("combobox mattype")->setEnabled(editable); + +		updateVisibility(); + +		bool identical				= true;	// true because it is anded below +      bool identical_diffuse	= false; +      bool identical_norm		= false; +      bool identical_spec		= false; +  		LLTextureCtrl*	texture_ctrl = getChild<LLTextureCtrl>("texture control"); +		LLTextureCtrl*	shinytexture_ctrl = getChild<LLTextureCtrl>("shinytexture control"); +		LLTextureCtrl*	bumpytexture_ctrl = getChild<LLTextureCtrl>("bumpytexture control"); -		// Texture +		LLUUID id; +		LLUUID normmap_id; +		LLUUID specmap_id; +		 +		// Color swatch  		{ -			LLUUID id; -			struct f1 : public LLSelectedTEGetFunctor<LLUUID> +			getChildView("color label")->setEnabled(editable); +		} +		LLColorSwatchCtrl*	mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch"); + +		LLColor4 color					= LLColor4::white; +		bool		identical_color	= false; + +		if(mColorSwatch)  			{ -				LLUUID get(LLViewerObject* object, S32 te_index) +			LLSelectedTE::getColor(color, identical_color); + +			mColorSwatch->setOriginal(color); +			mColorSwatch->set(color, TRUE); + +			mColorSwatch->setValid(editable); +			mColorSwatch->setEnabled( editable ); +			mColorSwatch->setCanApplyImmediately( editable ); +		} + +		// Color transparency +		getChildView("color trans")->setEnabled(editable); + +		F32 transparency = (1.f - color.mV[VALPHA]) * 100.f; +		getChild<LLUICtrl>("ColorTrans")->setValue(editable ? transparency : 0); +		getChildView("ColorTrans")->setEnabled(editable); + +		// Specular map +		LLSelectedTEMaterial::getSpecularID(specmap_id, identical_spec); +		 +		U8 shiny = 0; +		bool identical_shiny = false; + +		// Shiny +		LLSelectedTE::getShiny(shiny, identical_shiny); +		identical = identical && identical_shiny; + +		shiny = specmap_id.isNull() ? shiny : SHINY_TEXTURE; + +		LLCtrlSelectionInterface* combobox_shininess = childGetSelectionInterface("combobox shininess"); +		if (combobox_shininess)  				{ -					LLUUID id; +			combobox_shininess->selectNthItem((S32)shiny); +		} + +		getChildView("label shininess")->setEnabled(editable); +		getChildView("combobox shininess")->setEnabled(editable); + +		getChildView("label glossiness")->setEnabled(editable);			 +		getChildView("glossiness")->setEnabled(editable); + +		getChildView("label environment")->setEnabled(editable); +		getChildView("environment")->setEnabled(editable); +		getChildView("label shinycolor")->setEnabled(editable); -					LLViewerTexture* image = object->getTEImage(te_index); -					if (image) id = image->getID(); +		getChild<LLUICtrl>("combobox shininess")->setTentative(!identical_spec); +		getChild<LLUICtrl>("glossiness")->setTentative(!identical_spec); +		getChild<LLUICtrl>("environment")->setTentative(!identical_spec);			 +		getChild<LLUICtrl>("shinycolorswatch")->setTentative(!identical_spec); -					if (!id.isNull() && LLViewerMedia::textureHasMedia(id)) +		LLColorSwatchCtrl*	mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch"); +		if(mShinyColorSwatch)  					{ -						LLTextureEntry *te = object->getTE(te_index); -						if (te) +			mShinyColorSwatch->setValid(editable); +			mShinyColorSwatch->setEnabled( editable ); +			mShinyColorSwatch->setCanApplyImmediately( editable ); +		} + +		U8 bumpy = 0; +		// Bumpy  						{ -							LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID()) : NULL ; -							if(!tex) +			bool identical_bumpy = false; +			LLSelectedTE::getBumpmap(bumpy,identical_bumpy); + +			LLUUID norm_map_id = getCurrentNormalMap(); +			LLCtrlSelectionInterface* combobox_bumpiness = childGetSelectionInterface("combobox bumpiness"); + +			bumpy = norm_map_id.isNull() ? bumpy : BUMPY_TEXTURE; + +			if (combobox_bumpiness)  							{ -								tex = LLViewerFetchedTexture::sDefaultImagep; +				combobox_bumpiness->selectNthItem((S32)bumpy);  							} -							if (tex) +			else  							{ -								id = tex->getID(); +				llwarns << "failed childGetSelectionInterface for 'combobox bumpiness'" << llendl;  							} + +			getChildView("combobox bumpiness")->setEnabled(editable); +			getChild<LLUICtrl>("combobox bumpiness")->setTentative(!identical_bumpy); +			getChildView("label bumpiness")->setEnabled(editable);  						} + +		// Texture +		{ +			LLSelectedTE::getTexId(id,identical_diffuse); + +			// Normal map +			LLSelectedTEMaterial::getNormalID(normmap_id, identical_norm); + +			mIsAlpha = FALSE; +			LLGLenum image_format = GL_RGB; +			bool identical_image_format = false; +			LLSelectedTE::getImageFormat(image_format, identical_image_format); +             +         mIsAlpha = FALSE; +         switch (image_format) +         { +               case GL_RGBA: +               case GL_ALPHA: +               { +                  mIsAlpha = TRUE; +               } +               break; + +               case GL_RGB: break; +               default: +               { +                  llwarns << "Unexpected tex format in LLPanelFace...resorting to no alpha" << llendl;  					} -					return id; +               break;  				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id );  			if(LLViewerMedia::textureHasMedia(id))  			{ -				getChildView("textbox autofix")->setEnabled(editable);  				getChildView("button align")->setEnabled(editable);  			} -			if (identical) +			// Diffuse Alpha Mode + +			// Init to the default that is appropriate for the alpha content of the asset +			// +			U8 alpha_mode = mIsAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + +			bool identical_alpha_mode = false; + +			// See if that's been overridden by a material setting for same... +			// +			LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(alpha_mode, identical_alpha_mode, mIsAlpha); + +			LLCtrlSelectionInterface* combobox_alphamode = childGetSelectionInterface("combobox alphamode"); +			if (combobox_alphamode)  			{ -				// All selected have the same texture +				//it is invalid to have any alpha mode other than blend if transparency is greater than zero ...  +				// Want masking? Want emissive? Tough! You get BLEND! +				alpha_mode = (transparency > 0.f) ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : alpha_mode; + +				// ... unless there is no alpha channel in the texture, in which case alpha mode MUST be none +				alpha_mode = mIsAlpha ? alpha_mode : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + +				combobox_alphamode->selectNthItem(alpha_mode); +			} +			else +			{ +				llwarns << "failed childGetSelectionInterface for 'combobox alphamode'" << llendl; +			} + +			updateAlphaControls(); +			  				if(texture_ctrl)  				{ +				if (identical_diffuse) +				{  					texture_ctrl->setTentative( FALSE );  					texture_ctrl->setEnabled( editable );  					texture_ctrl->setImageAssetID( id ); +					getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f); +					getChildView("label alphamode")->setEnabled(editable && mIsAlpha); +					getChildView("maskcutoff")->setEnabled(editable && mIsAlpha); +					getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha);  				} -			} -			else -			{ -				if(texture_ctrl) -				{ -					if( id.isNull() ) +				else if (id.isNull())  					{  						// None selected  						texture_ctrl->setTentative( FALSE );  						texture_ctrl->setEnabled( FALSE );  						texture_ctrl->setImageAssetID( LLUUID::null ); +					getChildView("combobox alphamode")->setEnabled( FALSE ); +					getChildView("label alphamode")->setEnabled( FALSE ); +					getChildView("maskcutoff")->setEnabled( FALSE); +					getChildView("label maskcutoff")->setEnabled( FALSE );  					}  					else  					{ @@ -574,327 +881,493 @@ void LLPanelFace::getState()  						texture_ctrl->setTentative( TRUE );  						texture_ctrl->setEnabled( editable );  						texture_ctrl->setImageAssetID( id ); +					getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f); +					getChildView("label alphamode")->setEnabled(editable && mIsAlpha); +					getChildView("maskcutoff")->setEnabled(editable && mIsAlpha); +					getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha); +				} +			} +             +         if (shinytexture_ctrl) +         { +				if (identical_spec && (shiny == SHINY_TEXTURE)) +				{ +					shinytexture_ctrl->setTentative( FALSE ); +					shinytexture_ctrl->setEnabled( editable ); +					shinytexture_ctrl->setImageAssetID( specmap_id );  					} +            else if (specmap_id.isNull()) +				{ +               shinytexture_ctrl->setTentative( FALSE ); +               shinytexture_ctrl->setEnabled( editable ); +					shinytexture_ctrl->setImageAssetID( LLUUID::null );  				} +            else +            { +					shinytexture_ctrl->setTentative( TRUE ); +					shinytexture_ctrl->setEnabled( editable ); +					shinytexture_ctrl->setImageAssetID( specmap_id );  			}  		} +         if (bumpytexture_ctrl) +         { +				if (identical_norm && (bumpy == BUMPY_TEXTURE)) +				{ +					bumpytexture_ctrl->setTentative( FALSE ); +					bumpytexture_ctrl->setEnabled( editable ); +					bumpytexture_ctrl->setImageAssetID( normmap_id ); +				} +				else if (normmap_id.isNull()) +				{ +					bumpytexture_ctrl->setTentative( FALSE ); +					bumpytexture_ctrl->setEnabled( editable ); +					bumpytexture_ctrl->setImageAssetID( LLUUID::null ); +				} +            else +            { +					bumpytexture_ctrl->setTentative( TRUE ); +					bumpytexture_ctrl->setEnabled( editable ); +					bumpytexture_ctrl->setImageAssetID( normmap_id ); +				} +			} +		}  		// planar align  		bool align_planar = false;  		bool identical_planar_aligned = false; -		bool is_planar = false;  		{  			LLCheckBoxCtrl*	cb_planar_align = getChild<LLCheckBoxCtrl>("checkbox planar align");  			align_planar = (cb_planar_align && cb_planar_align->get()); -			struct f1 : public LLSelectedTEGetFunctor<bool> -			{ -				bool get(LLViewerObject* object, S32 face) -				{ -					return (object->getTE(face)->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR); -				} -			} func; -			bool texgens_identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, is_planar ); -			bool enabled = (editable && texgens_identical && is_planar); +			bool enabled = (editable && isIdenticalPlanarTexgen());  			childSetValue("checkbox planar align", align_planar && enabled);  			childSetEnabled("checkbox planar align", enabled);  			if (align_planar && enabled)  			{ -				struct f2 : public LLSelectedTEGetFunctor<LLFace *> -				{ -					LLFace* get(LLViewerObject* object, S32 te) -					{ -						return (object->mDrawable) ? object->mDrawable->getFace(te): NULL; -					} -				} get_te_face_func; -				LLFace* last_face; -				LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, last_face); +				LLFace* last_face = NULL; +				bool identical_face = false; +				LLSelectedTE::getFace(last_face, identical_face); +  				LLPanelFaceGetIsAlignedTEFunctor get_is_aligend_func(last_face);  				// this will determine if the texture param controls are tentative:  				identical_planar_aligned = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&get_is_aligend_func);  			}  		} +		// Needs to be public and before tex scale settings below to properly reflect +		// behavior when in planar vs default texgen modes in the +		// NORSPEC-84 et al +		// +		LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT; +		bool identical_texgen = true;		 +		bool identical_planar_texgen = false; + +		{	 +			LLSelectedTE::getTexGen(selected_texgen, identical_texgen); +			identical_planar_texgen = (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)); +		} +  		// Texture scale  		{ -			F32 scale_s = 1.f; -			struct f2 : public LLSelectedTEGetFunctor<F32> -			{ -				F32 get(LLViewerObject* object, S32 face) -				{ -					return object->getTE(face)->mScaleS; -				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_s ); +			bool identical_diff_scale_s = false; +			bool identical_spec_scale_s = false; +			bool identical_norm_scale_s = false; +  			identical = align_planar ? identical_planar_aligned : identical; -			getChild<LLUICtrl>("TexScaleU")->setValue(editable ? llabs(scale_s) : 0); -			getChild<LLUICtrl>("TexScaleU")->setTentative(LLSD((BOOL)(!identical))); + +			F32 diff_scale_s = 1.f;			 +			F32 spec_scale_s = 1.f; +			F32 norm_scale_s = 1.f; + +			LLSelectedTE::getScaleS(						diff_scale_s, identical_diff_scale_s);			 +			LLSelectedTEMaterial::getSpecularRepeatX( spec_scale_s, identical_spec_scale_s); +			LLSelectedTEMaterial::getNormalRepeatX(	norm_scale_s, identical_norm_scale_s); + +			diff_scale_s = editable ? diff_scale_s : 1.0f; +			diff_scale_s *= identical_planar_texgen ? 2.0f : 1.0f; +			 +			norm_scale_s = editable ? norm_scale_s : 1.0f; +			norm_scale_s *= identical_planar_texgen ? 2.0f : 1.0f; + +			spec_scale_s = editable ? spec_scale_s : 1.0f; +			spec_scale_s *= identical_planar_texgen ? 2.0f : 1.0f; + +			getChild<LLUICtrl>("TexScaleU")->setValue(diff_scale_s); +			getChild<LLUICtrl>("shinyScaleU")->setValue(spec_scale_s); +			getChild<LLUICtrl>("bumpyScaleU")->setValue(norm_scale_s); +  			getChildView("TexScaleU")->setEnabled(editable); -			getChild<LLUICtrl>("checkbox flip s")->setValue(LLSD((BOOL)(scale_s < 0 ? TRUE : FALSE ))); -			getChild<LLUICtrl>("checkbox flip s")->setTentative(LLSD((BOOL)((!identical) ? TRUE : FALSE ))); -			getChildView("checkbox flip s")->setEnabled(editable); +			getChildView("shinyScaleU")->setEnabled(editable && specmap_id.notNull()); +			getChildView("bumpyScaleU")->setEnabled(editable && normmap_id.notNull()); + +			BOOL diff_scale_tentative = !(identical && identical_diff_scale_s); +			BOOL norm_scale_tentative = !(identical && identical_norm_scale_s); +			BOOL spec_scale_tentative = !(identical && identical_spec_scale_s); + +			getChild<LLUICtrl>("TexScaleU")->setTentative(  LLSD(diff_scale_tentative));			 +			getChild<LLUICtrl>("shinyScaleU")->setTentative(LLSD(spec_scale_tentative));			 +			getChild<LLUICtrl>("bumpyScaleU")->setTentative(LLSD(norm_scale_tentative));  		}  		{ -			F32 scale_t = 1.f; -			struct f3 : public LLSelectedTEGetFunctor<F32> -			{ -				F32 get(LLViewerObject* object, S32 face) -				{ -					return object->getTE(face)->mScaleT; -				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_t ); -			identical = align_planar ? identical_planar_aligned : identical; +			bool identical_diff_scale_t = false; +			bool identical_spec_scale_t = false; +			bool identical_norm_scale_t = false; + +			F32 diff_scale_t = 1.f;			 +			F32 spec_scale_t = 1.f; +			F32 norm_scale_t = 1.f; + +			LLSelectedTE::getScaleT(diff_scale_t, identical_diff_scale_t); +			LLSelectedTEMaterial::getSpecularRepeatY(spec_scale_t, identical_spec_scale_t); +			LLSelectedTEMaterial::getNormalRepeatY(norm_scale_t, identical_norm_scale_t); + +			diff_scale_t = editable ? diff_scale_t : 1.0f; +			diff_scale_t *= identical_planar_texgen ? 2.0f : 1.0f; + +			norm_scale_t = editable ? norm_scale_t : 1.0f; +			norm_scale_t *= identical_planar_texgen ? 2.0f : 1.0f; + +			spec_scale_t = editable ? spec_scale_t : 1.0f; +			spec_scale_t *= identical_planar_texgen ? 2.0f : 1.0f; + +			BOOL diff_scale_tentative = !identical_diff_scale_t; +			BOOL norm_scale_tentative = !identical_norm_scale_t; +			BOOL spec_scale_tentative = !identical_spec_scale_t; -			getChild<LLUICtrl>("TexScaleV")->setValue(llabs(editable ? llabs(scale_t) : 0)); -			getChild<LLUICtrl>("TexScaleV")->setTentative(LLSD((BOOL)(!identical)));  			getChildView("TexScaleV")->setEnabled(editable); -			getChild<LLUICtrl>("checkbox flip t")->setValue(LLSD((BOOL)(scale_t< 0 ? TRUE : FALSE ))); -			getChild<LLUICtrl>("checkbox flip t")->setTentative(LLSD((BOOL)((!identical) ? TRUE : FALSE ))); -			getChildView("checkbox flip t")->setEnabled(editable); +			getChildView("shinyScaleV")->setEnabled(editable && specmap_id.notNull()); +			getChildView("bumpyScaleV")->setEnabled(editable && normmap_id.notNull()); + +			getChild<LLUICtrl>("TexScaleV")->setValue(diff_scale_t); +			getChild<LLUICtrl>("shinyScaleV")->setValue(norm_scale_t); +			getChild<LLUICtrl>("bumpyScaleV")->setValue(spec_scale_t); + +			getChild<LLUICtrl>("TexScaleV")->setTentative(LLSD(diff_scale_tentative)); +			getChild<LLUICtrl>("shinyScaleV")->setTentative(LLSD(norm_scale_tentative)); +			getChild<LLUICtrl>("bumpyScaleV")->setTentative(LLSD(spec_scale_tentative));  		}  		// Texture offset  		{ -			getChildView("tex offset")->setEnabled(editable); -			F32 offset_s = 0.f; -			struct f4 : public LLSelectedTEGetFunctor<F32> -			{ -				F32 get(LLViewerObject* object, S32 face) -				{ -					return object->getTE(face)->mOffsetS; -				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_s ); -			identical = align_planar ? identical_planar_aligned : identical; -			getChild<LLUICtrl>("TexOffsetU")->setValue(editable ? offset_s : 0); -			getChild<LLUICtrl>("TexOffsetU")->setTentative(!identical); +			bool identical_diff_offset_s = false; +			bool identical_norm_offset_s = false; +			bool identical_spec_offset_s = false; + +			F32 diff_offset_s = 0.0f; +			F32 norm_offset_s = 0.0f; +			F32 spec_offset_s = 0.0f; + +			LLSelectedTE::getOffsetS(diff_offset_s, identical_diff_offset_s); +			LLSelectedTEMaterial::getNormalOffsetX(norm_offset_s, identical_norm_offset_s); +			LLSelectedTEMaterial::getSpecularOffsetX(spec_offset_s, identical_spec_offset_s); + +			BOOL diff_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_s); +			BOOL norm_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_s); +			BOOL spec_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_s); + +			getChild<LLUICtrl>("TexOffsetU")->setValue(  editable ? diff_offset_s : 0.0f); +			getChild<LLUICtrl>("bumpyOffsetU")->setValue(editable ? norm_offset_s : 0.0f); +			getChild<LLUICtrl>("shinyOffsetU")->setValue(editable ? spec_offset_s : 0.0f); + +			getChild<LLUICtrl>("TexOffsetU")->setTentative(LLSD(diff_offset_u_tentative)); +			getChild<LLUICtrl>("shinyOffsetU")->setTentative(LLSD(norm_offset_u_tentative)); +			getChild<LLUICtrl>("bumpyOffsetU")->setTentative(LLSD(spec_offset_u_tentative)); +  			getChildView("TexOffsetU")->setEnabled(editable); +			getChildView("shinyOffsetU")->setEnabled(editable && specmap_id.notNull()); +			getChildView("bumpyOffsetU")->setEnabled(editable && normmap_id.notNull());  		}  		{ -			F32 offset_t = 0.f; -			struct f5 : public LLSelectedTEGetFunctor<F32> -			{ -				F32 get(LLViewerObject* object, S32 face) -				{ -					return object->getTE(face)->mOffsetT; -				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_t ); -			identical = align_planar ? identical_planar_aligned : identical; -			getChild<LLUICtrl>("TexOffsetV")->setValue(editable ? offset_t : 0); -			getChild<LLUICtrl>("TexOffsetV")->setTentative(!identical); +			bool identical_diff_offset_t = false; +			bool identical_norm_offset_t = false; +			bool identical_spec_offset_t = false; + +			F32 diff_offset_t = 0.0f; +			F32 norm_offset_t = 0.0f; +			F32 spec_offset_t = 0.0f; + +			LLSelectedTE::getOffsetT(diff_offset_t, identical_diff_offset_t); +			LLSelectedTEMaterial::getNormalOffsetY(norm_offset_t, identical_norm_offset_t); +			LLSelectedTEMaterial::getSpecularOffsetY(spec_offset_t, identical_spec_offset_t); +			 +			BOOL diff_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_t); +			BOOL norm_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_t); +			BOOL spec_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_t); + +			getChild<LLUICtrl>("TexOffsetV")->setValue(  editable ? diff_offset_t : 0.0f); +			getChild<LLUICtrl>("bumpyOffsetV")->setValue(editable ? norm_offset_t : 0.0f); +			getChild<LLUICtrl>("shinyOffsetV")->setValue(editable ? spec_offset_t : 0.0f); + +			getChild<LLUICtrl>("TexOffsetV")->setTentative(LLSD(diff_offset_v_tentative)); +			getChild<LLUICtrl>("shinyOffsetV")->setTentative(LLSD(norm_offset_v_tentative)); +			getChild<LLUICtrl>("bumpyOffsetV")->setTentative(LLSD(spec_offset_v_tentative)); +  			getChildView("TexOffsetV")->setEnabled(editable); +			getChildView("shinyOffsetV")->setEnabled(editable && specmap_id.notNull()); +			getChildView("bumpyOffsetV")->setEnabled(editable && normmap_id.notNull());  		}  		// Texture rotation  		{ -			F32 rotation = 0.f; -			struct f6 : public LLSelectedTEGetFunctor<F32> -			{ -				F32 get(LLViewerObject* object, S32 face) -				{ -					return object->getTE(face)->mRotation; -				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, rotation ); -			identical = align_planar ? identical_planar_aligned : identical; -			getChild<LLUICtrl>("TexRot")->setValue(editable ? rotation * RAD_TO_DEG : 0); -			getChild<LLUICtrl>("TexRot")->setTentative(!identical); -			getChildView("TexRot")->setEnabled(editable); -		} +			bool identical_diff_rotation = false; +			bool identical_norm_rotation = false; +			bool identical_spec_rotation = false; -		// Color swatch -		LLColorSwatchCtrl*	mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch"); -		LLColor4 color = LLColor4::white; -		if(mColorSwatch) -		{ -			struct f7 : public LLSelectedTEGetFunctor<LLColor4> -			{ -				LLColor4 get(LLViewerObject* object, S32 face) -				{ -					return object->getTE(face)->getColor(); -				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, color ); +			F32 diff_rotation = 0.f; +			F32 norm_rotation = 0.f; +			F32 spec_rotation = 0.f; + +			LLSelectedTE::getRotation(diff_rotation,identical_diff_rotation); +			LLSelectedTEMaterial::getSpecularRotation(spec_rotation,identical_spec_rotation); +			LLSelectedTEMaterial::getNormalRotation(norm_rotation,identical_norm_rotation); + +			BOOL diff_rot_tentative = !(align_planar ? identical_planar_aligned : identical_diff_rotation); +			BOOL norm_rot_tentative = !(align_planar ? identical_planar_aligned : identical_norm_rotation); +			BOOL spec_rot_tentative = !(align_planar ? identical_planar_aligned : identical_spec_rotation); + +			F32 diff_rot_deg = diff_rotation * RAD_TO_DEG; +			F32 norm_rot_deg = norm_rotation * RAD_TO_DEG; +			F32 spec_rot_deg = spec_rotation * RAD_TO_DEG; -			mColorSwatch->setOriginal(color); -			mColorSwatch->set(color, TRUE); +			getChildView("TexRot")->setEnabled(editable); +			getChildView("shinyRot")->setEnabled(editable && specmap_id.notNull()); +			getChildView("bumpyRot")->setEnabled(editable && normmap_id.notNull()); -			mColorSwatch->setValid(editable); -			mColorSwatch->setEnabled( editable ); -			mColorSwatch->setCanApplyImmediately( editable ); -		} -		// Color transparency -		{ -			getChildView("color trans")->setEnabled(editable); -		} +			getChild<LLUICtrl>("TexRot")->setTentative(diff_rot_tentative); +			getChild<LLUICtrl>("shinyRot")->setTentative(LLSD(norm_rot_tentative)); +			getChild<LLUICtrl>("bumpyRot")->setTentative(LLSD(spec_rot_tentative)); -		F32 transparency = (1.f - color.mV[VALPHA]) * 100.f; -		{ -			getChild<LLUICtrl>("ColorTrans")->setValue(editable ? transparency : 0); -			getChildView("ColorTrans")->setEnabled(editable); +			getChild<LLUICtrl>("TexRot")->setValue(  editable ? diff_rot_deg : 0.0f);			 +			getChild<LLUICtrl>("shinyRot")->setValue(editable ? spec_rot_deg : 0.0f); +			getChild<LLUICtrl>("bumpyRot")->setValue(editable ? norm_rot_deg : 0.0f);  		}  		{  			F32 glow = 0.f; -			struct f8 : public LLSelectedTEGetFunctor<F32> -			{ -				F32 get(LLViewerObject* object, S32 face) -				{ -					return object->getTE(face)->getGlow(); -				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, glow ); - +			bool identical_glow = false; +			LLSelectedTE::getGlow(glow,identical_glow);  			getChild<LLUICtrl>("glow")->setValue(glow); +			getChild<LLUICtrl>("glow")->setTentative(!identical_glow);  			getChildView("glow")->setEnabled(editable); -			getChild<LLUICtrl>("glow")->setTentative(!identical);  			getChildView("glow label")->setEnabled(editable); -  		} -		// Bump  		{ -			F32 shinyf = 0.f; -			struct f9 : public LLSelectedTEGetFunctor<F32> +			LLCtrlSelectionInterface* combobox_texgen = childGetSelectionInterface("combobox texgen"); +			if (combobox_texgen)  			{ -				F32 get(LLViewerObject* object, S32 face) +				// Maps from enum to combobox entry index +				combobox_texgen->selectNthItem(((S32)selected_texgen) >> 1); +			} +			else  				{ -					return (F32)(object->getTE(face)->getShiny()); +				llwarns << "failed childGetSelectionInterface for 'combobox texgen'" << llendl;  				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, shinyf ); -			LLCtrlSelectionInterface* combobox_shininess = -			      childGetSelectionInterface("combobox shininess"); -			if (combobox_shininess) + +			getChildView("combobox texgen")->setEnabled(editable); +			getChild<LLUICtrl>("combobox texgen")->setTentative(!identical); +			getChildView("tex gen")->setEnabled(editable); + +			if (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)  			{ -				combobox_shininess->selectNthItem((S32)shinyf); +				// EXP-1507 (change label based on the mapping mode) +				getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per meter"));  			}  			else +			if (selected_texgen == LLTextureEntry::TEX_GEN_DEFAULT)  			{ -				llwarns << "failed childGetSelectionInterface for 'combobox shininess'" << llendl; +				getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per face")); +			}  			} -			getChildView("combobox shininess")->setEnabled(editable); -			getChild<LLUICtrl>("combobox shininess")->setTentative(!identical); -			getChildView("label shininess")->setEnabled(editable); + +		{ +			U8 fullbright_flag = 0; +			bool identical_fullbright = false; +			 +			LLSelectedTE::getFullbright(fullbright_flag,identical_fullbright); + +			getChild<LLUICtrl>("checkbox fullbright")->setValue((S32)(fullbright_flag != 0)); +			getChildView("checkbox fullbright")->setEnabled(editable); +			getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical_fullbright);  		} +		// Repeats per meter +		{ +			F32 repeats_diff = 1.f; +			F32 repeats_norm = 1.f; +			F32 repeats_spec = 1.f; + +			bool identical_diff_repeats = false; +			bool identical_norm_repeats = false; +			bool identical_spec_repeats = false; + +			LLSelectedTE::getMaxDiffuseRepeats(repeats_diff, identical_diff_repeats); +			LLSelectedTEMaterial::getMaxNormalRepeats(repeats_norm, identical_norm_repeats); +			LLSelectedTEMaterial::getMaxSpecularRepeats(repeats_spec, identical_spec_repeats);			 + +			LLComboBox*	mComboTexGen = getChild<LLComboBox>("combobox texgen"); +			if (mComboTexGen)  		{ -			F32 bumpf = 0.f; -			struct f10 : public LLSelectedTEGetFunctor<F32> +				S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0; +				BOOL enabled = editable && (index != 1); +				BOOL identical_repeats = true; +				F32  repeats = 1.0f; + +				U32 material_type = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? combobox_mattype->getCurrentIndex() : MATTYPE_DIFFUSE; +				switch (material_type)  			{ -				F32 get(LLViewerObject* object, S32 face) +					default: +					case MATTYPE_DIFFUSE:  				{ -					return (F32)(object->getTE(face)->getBumpmap()); +						enabled = editable && !id.isNull(); +						identical_repeats = identical_diff_repeats; +						repeats = repeats_diff;  				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, bumpf ); -			LLCtrlSelectionInterface* combobox_bumpiness = -			      childGetSelectionInterface("combobox bumpiness"); -			if (combobox_bumpiness) +					break; + +					case MATTYPE_SPECULAR:  			{ -				combobox_bumpiness->selectNthItem((S32)bumpf); +						enabled = (editable && ((shiny == SHINY_TEXTURE) && !specmap_id.isNull())); +						identical_repeats = identical_spec_repeats; +						repeats = repeats_spec;  			} -			else +					break; + +					case MATTYPE_NORMAL:  			{ -				llwarns << "failed childGetSelectionInterface for 'combobox bumpiness'" << llendl; +						enabled = (editable && ((bumpy == BUMPY_TEXTURE) && !normmap_id.isNull())); +						identical_repeats = identical_norm_repeats; +						repeats = repeats_norm; +					} +					break; +				} + +				BOOL repeats_tentative = !identical_repeats; + +				getChildView("rptctrl")->setEnabled(identical_planar_texgen ? FALSE : enabled); +				getChild<LLUICtrl>("rptctrl")->setValue(editable ? repeats : 1.0f); +				getChild<LLUICtrl>("rptctrl")->setTentative(LLSD(repeats_tentative));  			} -			getChildView("combobox bumpiness")->setEnabled(editable); -			getChild<LLUICtrl>("combobox bumpiness")->setTentative(!identical); -			getChildView("label bumpiness")->setEnabled(editable);  		} +		// Materials  		{ -			F32 genf = 0.f; -			struct f11 : public LLSelectedTEGetFunctor<F32> +			LLMaterialPtr material; +			LLSelectedTEMaterial::getCurrent(material, identical); + +			if (material && editable)  			{ -				F32 get(LLViewerObject* object, S32 face) +				LL_DEBUGS("Materials: OnMatererialsLoaded:") << material->asLLSD() << LL_ENDL; + +				// Alpha +				LLCtrlSelectionInterface* combobox_alphamode = +					childGetSelectionInterface("combobox alphamode"); +				if (combobox_alphamode)  				{ -					return (F32)(object->getTE(face)->getTexGen()); +					U32 alpha_mode = material->getDiffuseAlphaMode(); + +					if (transparency > 0.f) +					{ //it is invalid to have any alpha mode other than blend if transparency is greater than zero ...  +						alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; +					} + +					if (!mIsAlpha) +					{ // ... unless there is no alpha channel in the texture, in which case alpha mode MUST ebe none +						alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;  				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, genf ); -			S32 selected_texgen = ((S32) genf) >> TEM_TEX_GEN_SHIFT; -			LLCtrlSelectionInterface* combobox_texgen = -			      childGetSelectionInterface("combobox texgen"); -			if (combobox_texgen) -			{ -				combobox_texgen->selectNthItem(selected_texgen); + +					combobox_alphamode->selectNthItem(alpha_mode);  			}  			else  			{ -				llwarns << "failed childGetSelectionInterface for 'combobox texgen'" << llendl; +					llwarns << "failed childGetSelectionInterface for 'combobox alphamode'" << llendl;  			} -			getChildView("combobox texgen")->setEnabled(editable); -			getChild<LLUICtrl>("combobox texgen")->setTentative(!identical); -			getChildView("tex gen")->setEnabled(editable); +				getChild<LLUICtrl>("maskcutoff")->setValue(material->getAlphaMaskCutoff()); +				updateAlphaControls(); + +				identical_planar_texgen = isIdenticalPlanarTexgen(); + +				// Shiny (specular) +				F32 offset_x, offset_y, repeat_x, repeat_y, rot; +				LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control"); +				texture_ctrl->setImageAssetID(material->getSpecularID()); -			if (selected_texgen == 1) +				if (!material->getSpecularID().isNull() && (shiny == SHINY_TEXTURE))  			{ -				getChild<LLUICtrl>("TexScaleU")->setValue(2.0f * getChild<LLUICtrl>("TexScaleU")->getValue().asReal() ); -				getChild<LLUICtrl>("TexScaleV")->setValue(2.0f * getChild<LLUICtrl>("TexScaleV")->getValue().asReal() ); +					material->getSpecularOffset(offset_x,offset_y); +					material->getSpecularRepeat(repeat_x,repeat_y); -				// EXP-1507 (change label based on the mapping mode) -				getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per meter")); -			} -			else -			if (selected_texgen == 0)  // FIXME: should not be magic numbers +					if (identical_planar_texgen)  			{ -				getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per face")); +						repeat_x *= 2.0f; +						repeat_y *= 2.0f;  			} + +					rot = material->getSpecularRotation(); +					getChild<LLUICtrl>("shinyScaleU")->setValue(repeat_x); +					getChild<LLUICtrl>("shinyScaleV")->setValue(repeat_y); +					getChild<LLUICtrl>("shinyRot")->setValue(rot*RAD_TO_DEG); +					getChild<LLUICtrl>("shinyOffsetU")->setValue(offset_x); +					getChild<LLUICtrl>("shinyOffsetV")->setValue(offset_y); +					getChild<LLUICtrl>("glossiness")->setValue(material->getSpecularLightExponent()); +					getChild<LLUICtrl>("environment")->setValue(material->getEnvironmentIntensity()); + +					updateShinyControls(!material->getSpecularID().isNull(), true);  		} +				// Assert desired colorswatch color to match material AFTER updateShinyControls +				// to avoid getting overwritten with the default on some UI state changes. +				// +				if (!material->getSpecularID().isNull())  		{ -			F32 fullbrightf = 0.f; -			struct f12 : public LLSelectedTEGetFunctor<F32> -			{ -				F32 get(LLViewerObject* object, S32 face) -				{ -					return (F32)(object->getTE(face)->getFullbright()); +					getChild<LLColorSwatchCtrl>("shinycolorswatch")->setOriginal(material->getSpecularLightColor()); +					getChild<LLColorSwatchCtrl>("shinycolorswatch")->set(material->getSpecularLightColor(),TRUE);  				} -			} func; -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, fullbrightf ); -			getChild<LLUICtrl>("checkbox fullbright")->setValue((S32)fullbrightf); -			getChildView("checkbox fullbright")->setEnabled(editable); -			getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical); -		} +				// Update sel manager as to which channel we're editing so it can reflect the correct overlay UI +				// NORSPEC-103 +				LLRender::eTexIndex channel_to_edit = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? (LLRender::eTexIndex)combobox_mattype->getCurrentIndex() : LLRender::DIFFUSE_MAP; -		// Repeats per meter label +				if ( ((channel_to_edit == LLRender::NORMAL_MAP) && material->getNormalID().isNull()) +					||((channel_to_edit == LLRender::SPECULAR_MAP) && material->getSpecularID().isNull()))  		{ -			getChildView("rpt")->setEnabled(editable); +					channel_to_edit = LLRender::DIFFUSE_MAP;  		} -		// Repeats per meter +				LLSelectMgr::getInstance()->setTextureChannel(channel_to_edit); + +				// Bumpy (normal) +				texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control"); +				texture_ctrl->setImageAssetID(material->getNormalID()); + +				if (!material->getNormalID().isNull())  		{ -			F32 repeats = 1.f; -			struct f13 : public LLSelectedTEGetFunctor<F32> -			{ -				F32 get(LLViewerObject* object, S32 face) +					material->getNormalOffset(offset_x,offset_y); +					material->getNormalRepeat(repeat_x,repeat_y); + +					if (identical_planar_texgen)  				{ -					U32 s_axis = VX; -					U32 t_axis = VY; -					// BUG: Only repeats along S axis -					// BUG: Only works for boxes. -					LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); -					return object->getTE(face)->mScaleS / object->getScale().mV[s_axis]; +						repeat_x *= 2.0f; +						repeat_y *= 2.0f;  				} -			} func;			 -			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, repeats ); -			getChild<LLUICtrl>("rptctrl")->setValue(editable ? repeats : 0); -			getChild<LLUICtrl>("rptctrl")->setTentative(!identical); -			LLComboBox*	mComboTexGen = getChild<LLComboBox>("combobox texgen"); -			if (mComboTexGen) +					rot = material->getNormalRotation(); +					getChild<LLUICtrl>("bumpyScaleU")->setValue(repeat_x); +					getChild<LLUICtrl>("bumpyScaleV")->setValue(repeat_y); +					getChild<LLUICtrl>("bumpyRot")->setValue(rot*RAD_TO_DEG); +					getChild<LLUICtrl>("bumpyOffsetU")->setValue(offset_x); +					getChild<LLUICtrl>("bumpyOffsetV")->setValue(offset_y); + +					updateBumpyControls(!material->getNormalID().isNull(), true); +				} +			} +			else  			{ -				BOOL enabled = editable && (!mComboTexGen || mComboTexGen->getCurrentIndex() != 1); -				getChildView("rptctrl")->setEnabled(enabled); -				getChildView("button apply")->setEnabled(enabled); +				LLSelectMgr::getInstance()->setTextureChannel(LLRender::DIFFUSE_MAP);  			}  		} @@ -934,14 +1407,11 @@ void LLPanelFace::getState()  		getChildView("tex gen")->setEnabled(FALSE);  		getChildView("label shininess")->setEnabled(FALSE);  		getChildView("label bumpiness")->setEnabled(FALSE); - -		getChildView("textbox autofix")->setEnabled(FALSE); -  		getChildView("button align")->setEnabled(FALSE); -		getChildView("button apply")->setEnabled(FALSE);  		//getChildView("has media")->setEnabled(FALSE);  		//getChildView("media info set")->setEnabled(FALSE); +		updateVisibility();  		// Set variable values for numeric expressions  		LLCalc* calcp = LLCalc::getInstance(); @@ -958,6 +1428,7 @@ void LLPanelFace::getState()  void LLPanelFace::refresh()  { +	LL_DEBUGS("Materials") << LL_ENDL;  	getState();  } @@ -977,6 +1448,11 @@ void LLPanelFace::onCommitColor(const LLSD& data)  	sendColor();  } +void LLPanelFace::onCommitShinyColor(const LLSD& data) +{ +	LLSelectedTEMaterial::setSpecularLightColor(this, getChild<LLColorSwatchCtrl>("shinycolorswatch")->get()); +} +  void LLPanelFace::onCommitAlpha(const LLSD& data)  {  	sendAlpha(); @@ -994,10 +1470,121 @@ void LLPanelFace::onSelectColor(const LLSD& data)  }  // static +void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	// Force to default states to side-step problems with menu contents +	// and generally reflecting old state when switching tabs or objects +	// +	self->updateShinyControls(false,true); +	self->updateBumpyControls(false,true); +	self->updateUI(); +} + +// static +void LLPanelFace::updateVisibility() +{	 +	LLComboBox* combo_matmedia = getChild<LLComboBox>("combobox matmedia"); +	LLComboBox* combo_mattype = getChild<LLComboBox>("combobox mattype"); +	LLComboBox* combo_shininess = getChild<LLComboBox>("combobox shininess"); +	LLComboBox* combo_bumpiness = getChild<LLComboBox>("combobox bumpiness"); +	if (!combo_mattype || !combo_matmedia || !combo_shininess || !combo_bumpiness) +	{ +		LL_WARNS("Materials") << "Combo box not found...exiting." << LL_ENDL; +		return; +	} +	U32 materials_media = combo_matmedia->getCurrentIndex(); +	U32 material_type = combo_mattype->getCurrentIndex(); +	bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled(); +	bool show_texture = (show_media || ((material_type == MATTYPE_DIFFUSE) && combo_matmedia->getEnabled())); +	bool show_bumpiness = (!show_media) && (material_type == MATTYPE_NORMAL) && combo_matmedia->getEnabled(); +	bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled(); +	getChildView("combobox mattype")->setVisible(!show_media); +	getChildView("rptctrl")->setVisible(true); + +	// Media controls +	getChildView("media_info")->setVisible(show_media); +	getChildView("add_media")->setVisible(show_media); +	getChildView("delete_media")->setVisible(show_media); +	getChildView("button align")->setVisible(show_media); + +	// Diffuse texture controls +	getChildView("texture control")->setVisible(show_texture && !show_media); +	getChildView("label alphamode")->setVisible(show_texture && !show_media); +	getChildView("combobox alphamode")->setVisible(show_texture && !show_media); +	getChildView("label maskcutoff")->setVisible(false); +	getChildView("maskcutoff")->setVisible(false); +	if (show_texture && !show_media) +	{ +		updateAlphaControls(); +	} +	getChildView("TexScaleU")->setVisible(show_texture); +	getChildView("TexScaleV")->setVisible(show_texture); +	getChildView("TexRot")->setVisible(show_texture); +	getChildView("TexOffsetU")->setVisible(show_texture); +	getChildView("TexOffsetV")->setVisible(show_texture); + +	// Specular map controls +	getChildView("shinytexture control")->setVisible(show_shininess); +	getChildView("combobox shininess")->setVisible(show_shininess); +	getChildView("label shininess")->setVisible(show_shininess); +	getChildView("label glossiness")->setVisible(false); +	getChildView("glossiness")->setVisible(false); +	getChildView("label environment")->setVisible(false); +	getChildView("environment")->setVisible(false); +	getChildView("label shinycolor")->setVisible(false); +	getChildView("shinycolorswatch")->setVisible(false); +	if (show_shininess) +	{ +		updateShinyControls(); +	} +	getChildView("shinyScaleU")->setVisible(show_shininess); +	getChildView("shinyScaleV")->setVisible(show_shininess); +	getChildView("shinyRot")->setVisible(show_shininess); +	getChildView("shinyOffsetU")->setVisible(show_shininess); +	getChildView("shinyOffsetV")->setVisible(show_shininess); + +	// Normal map controls +	if (show_bumpiness) +	{ +		updateBumpyControls(); +	} +	getChildView("bumpytexture control")->setVisible(show_bumpiness); +	getChildView("combobox bumpiness")->setVisible(show_bumpiness); +	getChildView("label bumpiness")->setVisible(show_bumpiness); +	getChildView("bumpyScaleU")->setVisible(show_bumpiness); +	getChildView("bumpyScaleV")->setVisible(show_bumpiness); +	getChildView("bumpyRot")->setVisible(show_bumpiness); +	getChildView("bumpyOffsetU")->setVisible(show_bumpiness); +	getChildView("bumpyOffsetV")->setVisible(show_bumpiness); + + +} + +// static +void LLPanelFace::onCommitMaterialType(LLUICtrl* ctrl, void* userdata) +{ +    LLPanelFace* self = (LLPanelFace*) userdata; +	 // Force to default states to side-step problems with menu contents +	 // and generally reflecting old state when switching tabs or objects +	 // +	 self->updateShinyControls(false,true); +	 self->updateBumpyControls(false,true); +    self->updateUI(); +} + +// static  void LLPanelFace::onCommitBump(LLUICtrl* ctrl, void* userdata)  {  	LLPanelFace* self = (LLPanelFace*) userdata; -	self->sendBump(); + +	LLComboBox*	mComboBumpiness = self->getChild<LLComboBox>("combobox bumpiness"); +	if(!mComboBumpiness) +		return; + +	U32 bumpiness = mComboBumpiness->getCurrentIndex(); + +	self->sendBump(bumpiness);  }  // static @@ -1008,10 +1595,143 @@ void LLPanelFace::onCommitTexGen(LLUICtrl* ctrl, void* userdata)  }  // static +void LLPanelFace::updateShinyControls(bool is_setting_texture, bool mess_with_shiny_combobox) +{ +	LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control"); +	LLUUID shiny_texture_ID = texture_ctrl->getImageAssetID(); +	LL_DEBUGS("Materials") << "Shiny texture selected: " << shiny_texture_ID << LL_ENDL; +	LLComboBox* comboShiny = getChild<LLComboBox>("combobox shininess"); + +	if(mess_with_shiny_combobox) +	{ +		if (!comboShiny) +		{ +			return; +		} +		if (!shiny_texture_ID.isNull() && is_setting_texture) +		{ +			if (!comboShiny->itemExists(USE_TEXTURE)) +			{ +				comboShiny->add(USE_TEXTURE); +			} +			comboShiny->setSimple(USE_TEXTURE); +		} +		else +		{ +			if (comboShiny->itemExists(USE_TEXTURE)) +			{ +				comboShiny->remove(SHINY_TEXTURE); +				comboShiny->selectFirstItem(); +			} +		} +	} + +	LLComboBox* combo_matmedia = getChild<LLComboBox>("combobox matmedia"); +	LLComboBox* combo_mattype = getChild<LLComboBox>("combobox mattype"); +	U32 materials_media = combo_matmedia->getCurrentIndex(); +	U32 material_type = combo_mattype->getCurrentIndex(); +	bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled(); +	bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled(); +	U32 shiny_value = comboShiny->getCurrentIndex(); +	bool show_shinyctrls = (shiny_value == SHINY_TEXTURE) && show_shininess; // Use texture +	getChildView("label glossiness")->setVisible(show_shinyctrls); +	getChildView("glossiness")->setVisible(show_shinyctrls); +	getChildView("label environment")->setVisible(show_shinyctrls); +	getChildView("environment")->setVisible(show_shinyctrls); +	getChildView("label shinycolor")->setVisible(show_shinyctrls); +	getChildView("shinycolorswatch")->setVisible(show_shinyctrls); +} + +// static +void LLPanelFace::updateBumpyControls(bool is_setting_texture, bool mess_with_combobox) +{ +	LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control"); +	LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID(); +	LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL; +	LLComboBox* comboBumpy = getChild<LLComboBox>("combobox bumpiness"); +	if (!comboBumpy) +	{ +		return; +	} + +	if (mess_with_combobox) +	{ +		LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control"); +		LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID(); +		LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL; + +		if (!bumpy_texture_ID.isNull() && is_setting_texture) +		{ +			if (!comboBumpy->itemExists(USE_TEXTURE)) +			{ +				comboBumpy->add(USE_TEXTURE); +			} +			comboBumpy->setSimple(USE_TEXTURE); +		} +		else +		{ +			if (comboBumpy->itemExists(USE_TEXTURE)) +			{ +				comboBumpy->remove(BUMPY_TEXTURE); +				comboBumpy->selectFirstItem(); +			} +		} +	} +} + +// static  void LLPanelFace::onCommitShiny(LLUICtrl* ctrl, void* userdata)  {  	LLPanelFace* self = (LLPanelFace*) userdata; -	self->sendShiny(); + + +	LLComboBox*	mComboShininess = self->getChild<LLComboBox>("combobox shininess"); +	if(!mComboShininess) +		return; +	 +	U32 shininess = mComboShininess->getCurrentIndex(); + +	self->sendShiny(shininess); +} + +// static +void LLPanelFace::updateAlphaControls() +{ +	LLComboBox* comboAlphaMode = getChild<LLComboBox>("combobox alphamode"); +	if (!comboAlphaMode) +	{ +		return; +	} +	U32 alpha_value = comboAlphaMode->getCurrentIndex(); +	bool show_alphactrls = (alpha_value == ALPHAMODE_MASK); // Alpha masking +     +    LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia"); +    U32 mat_media = MATMEDIA_MATERIAL; +    if (combobox_matmedia) +    { +        mat_media = combobox_matmedia->getCurrentIndex(); +    } +     +    LLComboBox* combobox_mattype = getChild<LLComboBox>("combobox mattype"); +    U32 mat_type = MATTYPE_DIFFUSE; +    if (combobox_mattype) +    { +        mat_type = combobox_mattype->getCurrentIndex(); +    } + +    show_alphactrls = show_alphactrls && (mat_media == MATMEDIA_MATERIAL); +    show_alphactrls = show_alphactrls && (mat_type == MATTYPE_DIFFUSE); +     +	getChildView("label maskcutoff")->setVisible(show_alphactrls); +	getChildView("maskcutoff")->setVisible(show_alphactrls); +} + +// static +void LLPanelFace::onCommitAlphaMode(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	self->updateAlphaControls(); +	LLSelectedTEMaterial::setDiffuseAlphaMode(self,self->getCurrentDiffuseAlphaMode());  }  // static @@ -1061,8 +1781,211 @@ void LLPanelFace::onSelectTexture(const LLSD& data)  {  	LLSelectMgr::getInstance()->saveSelectedObjectTextures();  	sendTexture(); + +	LLGLenum image_format; +	bool identical_image_format = false; +	LLSelectedTE::getImageFormat(image_format, identical_image_format); +     +	LLCtrlSelectionInterface* combobox_alphamode = +		childGetSelectionInterface("combobox alphamode"); + +	U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; +	if (combobox_alphamode) +	{ +		switch (image_format) +		{ +		case GL_RGBA: +		case GL_ALPHA: +			{ +				alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; +			} +			break; + +		case GL_RGB: break; +		default: +			{ +				llwarns << "Unexpected tex format in LLPanelFace...resorting to no alpha" << llendl; +			} +			break; +		} + +		combobox_alphamode->selectNthItem(alpha_mode); +	} +	LLSelectedTEMaterial::setDiffuseAlphaMode(this, getCurrentDiffuseAlphaMode()); +} + +void LLPanelFace::onCloseTexturePicker(const LLSD& data) +{ +	LL_DEBUGS("Materials") << data << LL_ENDL; +	updateUI(); +} + +void LLPanelFace::onCommitSpecularTexture( const LLSD& data ) +{ +	LL_DEBUGS("Materials") << data << LL_ENDL; +	sendShiny(SHINY_TEXTURE); +} + +void LLPanelFace::onCommitNormalTexture( const LLSD& data ) +{ +	LL_DEBUGS("Materials") << data << LL_ENDL; +	LLUUID nmap_id = getCurrentNormalMap(); +	sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE);  } +void LLPanelFace::onCancelSpecularTexture(const LLSD& data) +{ +	U8 shiny = 0; +	bool identical_shiny = false; +	LLSelectedTE::getShiny(shiny, identical_shiny); +	LLUUID spec_map_id = getChild<LLTextureCtrl>("shinytexture control")->getImageAssetID(); +	shiny = spec_map_id.isNull() ? shiny : SHINY_TEXTURE; +	sendShiny(shiny); +} + +void LLPanelFace::onCancelNormalTexture(const LLSD& data) +{ +	U8 bumpy = 0; +	bool identical_bumpy = false; +	LLSelectedTE::getBumpmap(bumpy, identical_bumpy); +	sendBump(bumpy); +} + +void LLPanelFace::onSelectSpecularTexture(const LLSD& data) +{ +	LL_DEBUGS("Materials") << data << LL_ENDL; +	sendShiny(SHINY_TEXTURE); +} + +void LLPanelFace::onSelectNormalTexture(const LLSD& data) +{ +	LL_DEBUGS("Materials") << data << LL_ENDL; +	LLUUID nmap_id = getCurrentNormalMap(); +	sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE); +} + +//static +void LLPanelFace::onCommitMaterialBumpyOffsetX(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	LLSelectedTEMaterial::setNormalOffsetX(self,self->getCurrentBumpyOffsetU()); +} + +//static +void LLPanelFace::onCommitMaterialBumpyOffsetY(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	LLSelectedTEMaterial::setNormalOffsetY(self,self->getCurrentBumpyOffsetV()); +} + +//static +void LLPanelFace::onCommitMaterialShinyOffsetX(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	LLSelectedTEMaterial::setSpecularOffsetX(self,self->getCurrentShinyOffsetU()); +} + +//static +void LLPanelFace::onCommitMaterialShinyOffsetY(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	LLSelectedTEMaterial::setSpecularOffsetY(self,self->getCurrentShinyOffsetV()); +} + +//static +void LLPanelFace::onCommitMaterialBumpyScaleX(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	F32 bumpy_scale_u = self->getCurrentBumpyScaleU(); +	if (self->isIdenticalPlanarTexgen()) +	{ +		bumpy_scale_u *= 0.5f; +	} +	LLSelectedTEMaterial::setNormalRepeatX(self,bumpy_scale_u); +} + +//static +void LLPanelFace::onCommitMaterialBumpyScaleY(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	F32 bumpy_scale_v = self->getCurrentBumpyScaleV(); +	if (self->isIdenticalPlanarTexgen()) +	{ +		bumpy_scale_v *= 0.5f; +	} +	LLSelectedTEMaterial::setNormalRepeatY(self,bumpy_scale_v); +} + +//static +void LLPanelFace::onCommitMaterialShinyScaleX(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	F32 shiny_scale_u = self->getCurrentShinyScaleU(); +	if (self->isIdenticalPlanarTexgen()) +	{ +		shiny_scale_u *= 0.5f; +	} +	LLSelectedTEMaterial::setSpecularRepeatX(self,shiny_scale_u); +} + +//static +void LLPanelFace::onCommitMaterialShinyScaleY(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	F32 shiny_scale_v = self->getCurrentShinyScaleV(); +	if (self->isIdenticalPlanarTexgen()) +	{ +		shiny_scale_v *= 0.5f; +	} +	LLSelectedTEMaterial::setSpecularRepeatY(self,shiny_scale_v); +} + +//static +void LLPanelFace::onCommitMaterialBumpyRot(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	LLSelectedTEMaterial::setNormalRotation(self,self->getCurrentBumpyRot() * DEG_TO_RAD); +} + +//static +void LLPanelFace::onCommitMaterialShinyRot(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	LLSelectedTEMaterial::setSpecularRotation(self,self->getCurrentShinyRot() * DEG_TO_RAD); +} + +//static +void LLPanelFace::onCommitMaterialGloss(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	LLSelectedTEMaterial::setSpecularLightExponent(self,self->getCurrentGlossiness()); +} + +//static +void LLPanelFace::onCommitMaterialEnv(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	llassert_always(self); +	LLSelectedTEMaterial::setEnvironmentIntensity(self,self->getCurrentEnvIntensity()); +} + +//static +void LLPanelFace::onCommitMaterialMaskCutoff(LLUICtrl* ctrl, void* userdata) +{ +	LLPanelFace* self = (LLPanelFace*) userdata; +	LLSelectedTEMaterial::setAlphaMaskCutoff(self,self->getCurrentAlphaMaskCutoff()); +}  // static  void LLPanelFace::onCommitTextureInfo( LLUICtrl* ctrl, void* userdata ) @@ -1073,16 +1996,68 @@ void LLPanelFace::onCommitTextureInfo( LLUICtrl* ctrl, void* userdata )  // Commit the number of repeats per meter  // static -void LLPanelFace::onClickApply(void* userdata) +void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata)  {  	LLPanelFace* self = (LLPanelFace*) userdata; -	gFocusMgr.setKeyboardFocus( NULL ); +	LLUICtrl*	repeats_ctrl	= self->getChild<LLUICtrl>("rptctrl"); +	LLComboBox* combo_matmedia = self->getChild<LLComboBox>("combobox matmedia"); +	LLComboBox* combo_mattype	= self->getChild<LLComboBox>("combobox mattype"); +	 +	U32 materials_media = combo_matmedia->getCurrentIndex(); +	 + +	U32 material_type			= (materials_media == MATMEDIA_MATERIAL) ? combo_mattype->getCurrentIndex() : 0; +	F32 repeats_per_meter	= repeats_ctrl->getValue().asReal(); +	 +   F32 obj_scale_s = 1.0f; +   F32 obj_scale_t = 1.0f; + +	bool identical_scale_s = false; +	bool identical_scale_t = false; -	//F32 repeats_per_meter = self->mCtrlRepeatsPerMeter->get(); -	F32 repeats_per_meter = (F32)self->getChild<LLUICtrl>("rptctrl")->getValue().asReal();//self->mCtrlRepeatsPerMeter->get(); +	LLSelectedTE::getObjectScaleS(obj_scale_s, identical_scale_s); +	LLSelectedTE::getObjectScaleS(obj_scale_t, identical_scale_t); +  +	switch (material_type) +	{ +		case MATTYPE_DIFFUSE: +		{  	LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );  } +		break; + +		case MATTYPE_NORMAL: +		{ +			LLUICtrl* bumpy_scale_u = self->getChild<LLUICtrl>("bumpyScaleU"); +			LLUICtrl* bumpy_scale_v = self->getChild<LLUICtrl>("bumpyScaleV"); +			 +			bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter); +			bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter); + +			LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter); +			LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter); +		} +		break; + +		case MATTYPE_SPECULAR: +		{ +			LLUICtrl* shiny_scale_u = self->getChild<LLUICtrl>("shinyScaleU"); +			LLUICtrl* shiny_scale_v = self->getChild<LLUICtrl>("shinyScaleV"); +			 +			shiny_scale_u->setValue(obj_scale_s * repeats_per_meter); +			shiny_scale_v->setValue(obj_scale_t * repeats_per_meter); + +			LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter); +			LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter); +		} +		break; + +		default: +			llassert(false); +		break; +	} +}  struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor  { @@ -1155,7 +2130,26 @@ void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)  void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp)  { -	LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control"); +	LL_DEBUGS("Materials") << "item asset " << itemp->getAssetUUID() << LL_ENDL; +	LLComboBox* combo_mattype = getChild<LLComboBox>("combobox mattype"); +	if (!combo_mattype) +	{ +		return; +	} +	U32 mattype = combo_mattype->getCurrentIndex(); +	std::string which_control="texture control"; +	switch (mattype) +	{ +		case MATTYPE_SPECULAR: +			which_control = "shinytexture control"; +			break; +		case MATTYPE_NORMAL: +			which_control = "bumpytexture control"; +			break; +		// no default needed +	} +	LL_DEBUGS("Materials") << "control " << which_control << LL_ENDL; +	LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>(which_control);  	if (texture_ctrl)  	{  		LLUUID obj_owner_id; @@ -1185,3 +2179,212 @@ void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp)  		}  	}  } + +bool LLPanelFace::isIdenticalPlanarTexgen() +{ +	LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT; +	bool identical_texgen = false; +	LLSelectedTE::getTexGen(selected_texgen, identical_texgen); +	return (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)); +} + +void LLPanelFace::LLSelectedTE::getFace(LLFace*& face_to_return, bool& identical_face) +{		 +	struct LLSelectedTEGetFace : public LLSelectedTEGetFunctor<LLFace *> +	{ +		LLFace* get(LLViewerObject* object, S32 te) +		{ +			return (object->mDrawable) ? object->mDrawable->getFace(te): NULL; +		} +	} get_te_face_func; +	identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, face_to_return); +} + +void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, bool& identical_face) +{ +	LLGLenum image_format; +	struct LLSelectedTEGetImageFormat : public LLSelectedTEGetFunctor<LLGLenum> +	{ +		LLGLenum get(LLViewerObject* object, S32 te_index) +		{ +			LLViewerTexture* image = object->getTEImage(te_index); +			return image ? image->getPrimaryFormat() : GL_RGB; +		} +	} get_glenum; +	identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_glenum, image_format); +	image_format_to_return = image_format; +} + +void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical) +{		 +	struct LLSelectedTEGetTexId : public LLSelectedTEGetFunctor<LLUUID> +	{ +		LLUUID get(LLViewerObject* object, S32 te_index) +		{ +			LLUUID id; +			LLViewerTexture* image = object->getTEImage(te_index); +			if (image) +			{ +				id = image->getID(); +			} + +			if (!id.isNull() && LLViewerMedia::textureHasMedia(id)) +			{ +				LLTextureEntry *te = object->getTE(te_index); +				if (te) +				{ +					LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID()) : NULL; +					if(!tex) +					{ +						tex = LLViewerFetchedTexture::sDefaultImagep; +					} +					if (tex) +					{ +						id = tex->getID(); +					} +				} +			} +			return id; +		} +	} func; +	identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id ); +} + +void LLPanelFace::LLSelectedTEMaterial::getCurrent(LLMaterialPtr& material_ptr, bool& identical_material) +{ +	struct MaterialFunctor : public LLSelectedTEGetFunctor<LLMaterialPtr> +	{ +		LLMaterialPtr get(LLViewerObject* object, S32 te_index) +		{ +			return object->getTE(te_index)->getMaterialParams(); +		} +	} func; +	identical_material = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_ptr); +} + +void LLPanelFace::LLSelectedTEMaterial::getMaxSpecularRepeats(F32& repeats, bool& identical) +{ +	struct LLSelectedTEGetMaxSpecRepeats : public LLSelectedTEGetFunctor<F32> +	{ +		F32 get(LLViewerObject* object, S32 face) +		{ +			LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); +			U32 s_axis = VX; +			U32 t_axis = VY; +			F32 repeats_s = 1.0f; +			F32 repeats_t = 1.0f; +			if (mat) +			{ +				mat->getSpecularRepeat(repeats_s, repeats_t); +				repeats_s /= object->getScale().mV[s_axis]; +				repeats_t /= object->getScale().mV[t_axis]; +			}					 +			return llmax(repeats_s, repeats_t); +		} + +	} max_spec_repeats_func; +	identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_spec_repeats_func, repeats); +} + +void LLPanelFace::LLSelectedTEMaterial::getMaxNormalRepeats(F32& repeats, bool& identical) +{ +	struct LLSelectedTEGetMaxNormRepeats : public LLSelectedTEGetFunctor<F32> +	{ +		F32 get(LLViewerObject* object, S32 face) +		{ +			LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); +			U32 s_axis = VX; +			U32 t_axis = VY; +			F32 repeats_s = 1.0f; +			F32 repeats_t = 1.0f; +			if (mat) +			{ +				mat->getNormalRepeat(repeats_s, repeats_t); +				repeats_s /= object->getScale().mV[s_axis]; +				repeats_t /= object->getScale().mV[t_axis]; +			}					 +			return llmax(repeats_s, repeats_t); +		} + +	} max_norm_repeats_func; +	identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_norm_repeats_func, repeats); +} + +void LLPanelFace::LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha) +{ +	struct LLSelectedTEGetDiffuseAlphaMode : public LLSelectedTEGetFunctor<U8> +	{ +		LLSelectedTEGetDiffuseAlphaMode() : _isAlpha(false) {} +		LLSelectedTEGetDiffuseAlphaMode(bool diffuse_texture_has_alpha) : _isAlpha(diffuse_texture_has_alpha) {} +		virtual ~LLSelectedTEGetDiffuseAlphaMode() {} + +		U8 get(LLViewerObject* object, S32 face) +		{ +			U8 diffuse_mode = _isAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + +			LLTextureEntry* tep = object->getTE(face); +			if (tep) +			{ +				LLMaterial* mat = tep->getMaterialParams().get(); +				if (mat) +				{ +					diffuse_mode = mat->getDiffuseAlphaMode(); +				} +			} +			 +			return diffuse_mode; +		} +		bool _isAlpha; // whether or not the diffuse texture selected contains alpha information +	} get_diff_mode(diffuse_texture_has_alpha); +	identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &get_diff_mode, diffuse_alpha_mode); +} + +void LLPanelFace::LLSelectedTE::getObjectScaleS(F32& scale_s, bool& identical) +{	 +	struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor<F32> +	{ +		F32 get(LLViewerObject* object, S32 face) +		{ +			U32 s_axis = VX; +			U32 t_axis = VY; +			LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); +			return object->getScale().mV[s_axis]; +		} + +	} scale_s_func; +	identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_s_func, scale_s ); +} + +void LLPanelFace::LLSelectedTE::getObjectScaleT(F32& scale_t, bool& identical) +{	 +	struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor<F32> +	{ +		F32 get(LLViewerObject* object, S32 face) +		{ +			U32 s_axis = VX; +			U32 t_axis = VY; +			LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); +			return object->getScale().mV[t_axis]; +		} + +	} scale_t_func; +	identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_t_func, scale_t ); +} + +void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identical) +{ +	struct LLSelectedTEGetMaxDiffuseRepeats : public LLSelectedTEGetFunctor<F32> +	{ +		F32 get(LLViewerObject* object, S32 face) +		{ +			U32 s_axis = VX; +			U32 t_axis = VY; +			LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); +			F32 repeats_s = object->getTE(face)->mScaleS / object->getScale().mV[s_axis]; +			F32 repeats_t = object->getTE(face)->mScaleT / object->getScale().mV[t_axis]; +			return llmax(repeats_s, repeats_t); +		} + +	} max_diff_repeats_func; +	identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats ); +} diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 3b5a9b1398..7fba58156c 100755 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -29,6 +29,10 @@  #include "v4color.h"  #include "llpanel.h" +#include "llmaterial.h" +#include "llmaterialmgr.h" +#include "lltextureentry.h" +#include "llselectmgr.h"  class LLButton;  class LLCheckBoxCtrl; @@ -42,6 +46,48 @@ class LLTextureCtrl;  class LLUICtrl;  class LLViewerObject;  class LLFloater; +class LLMaterialID; + +// Represents an edit for use in replicating the op across one or more materials in the selection set. +// +// The apply function optionally performs the edit which it implements +// as a functor taking Data that calls member func MaterialFunc taking SetValueType +// on an instance of the LLMaterial class. +// +// boost who? +// +template< +	typename DataType, +	typename SetValueType, +	void (LLMaterial::*MaterialEditFunc)(SetValueType data) > +class LLMaterialEditFunctor +{ +public: +	LLMaterialEditFunctor(const DataType& data) : _data(data) {} +	virtual ~LLMaterialEditFunctor() {} +	virtual void apply(LLMaterialPtr& material) { (material->*(MaterialEditFunc))(_data); } +	DataType _data; +}; + +template< +	typename DataType, +	DataType (LLMaterial::*MaterialGetFunc)() > +class LLMaterialGetFunctor +{ +public: +	LLMaterialGetFunctor() {} +	virtual DataType get(LLMaterialPtr& material) { return (material->*(MaterialGetFunc)); } +}; + +template< +	typename DataType, +	DataType (LLTextureEntry::*TEGetFunc)() > +class LLTEGetFunctor +{ +public: +	LLTEGetFunctor() {} +	virtual DataType get(LLTextureEntry* entry) { return (entry*(TEGetFunc)); } +};  class LLPanelFace : public LLPanel  { @@ -61,11 +107,11 @@ protected:  	void			sendTextureInfo();		// applies and sends texture scale, offset, etc.  	void			sendColor();			// applies and sends color  	void			sendAlpha();			// applies and sends transparency -	void			sendBump();				// applies and sends bump map +	void			sendBump(U32 bumpiness);				// applies and sends bump map  	void			sendTexGen();				// applies and sends bump map -	void			sendShiny();			// applies and sends shininess +	void			sendShiny(U32 shininess);			// applies and sends shininess  	void			sendFullbright();		// applies and sends full bright -	void            sendGlow(); +	void        sendGlow();  	void			sendMedia();  	// this function is to return TRUE if the drag should succeed. @@ -74,25 +120,228 @@ protected:  	void 	onCommitTexture(const LLSD& data);  	void 	onCancelTexture(const LLSD& data);  	void 	onSelectTexture(const LLSD& data); +	void 	onCommitSpecularTexture(const LLSD& data); +	void 	onCancelSpecularTexture(const LLSD& data); +	void 	onSelectSpecularTexture(const LLSD& data); +	void 	onCommitNormalTexture(const LLSD& data); +	void 	onCancelNormalTexture(const LLSD& data); +	void 	onSelectNormalTexture(const LLSD& data);  	void 	onCommitColor(const LLSD& data); +	void 	onCommitShinyColor(const LLSD& data);  	void 	onCommitAlpha(const LLSD& data);  	void 	onCancelColor(const LLSD& data);  	void 	onSelectColor(const LLSD& data); -	 -	static 	void onCommitTextureInfo( 		LLUICtrl* ctrl, void* userdata); -	static void		onCommitBump(			LLUICtrl* ctrl, void* userdata); + +	void 	onCloseTexturePicker(const LLSD& data); + +	// Make UI reflect state of currently selected material (refresh) +	// and UI mode (e.g. editing normal map v diffuse map) +	// +	void updateUI(); + +	// Convenience func to determine if all faces in selection have +	// identical planar texgen settings during edits +	//  +	bool isIdenticalPlanarTexgen(); + +	// Callback funcs for individual controls +	// +	static void		onCommitTextureInfo( 	LLUICtrl* ctrl, void* userdata); + +	static void		onCommitMaterialBumpyScaleX(	LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialBumpyScaleY(	LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialBumpyRot(		LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialBumpyOffsetX(	LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialBumpyOffsetY(	LLUICtrl* ctrl, void* userdata); + +	static void		onCommitMaterialShinyScaleX(	LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialShinyScaleY(	LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialShinyRot(		LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialShinyOffsetX(	LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialShinyOffsetY(	LLUICtrl* ctrl, void* userdata); + +	static void		onCommitMaterialGloss(			LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialEnv(				LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialMaskCutoff(	LLUICtrl* ctrl, void* userdata); + +	static void		onCommitMaterialsMedia(	LLUICtrl* ctrl, void* userdata); +	static void		onCommitMaterialType(	LLUICtrl* ctrl, void* userdata); +	static void		onCommitBump(				LLUICtrl* ctrl, void* userdata);  	static void		onCommitTexGen(			LLUICtrl* ctrl, void* userdata); -	static void		onCommitShiny(			LLUICtrl* ctrl, void* userdata); +	static void		onCommitShiny(				LLUICtrl* ctrl, void* userdata); +	static void		onCommitAlphaMode(		LLUICtrl* ctrl, void* userdata);  	static void		onCommitFullbright(		LLUICtrl* ctrl, void* userdata); -	static void     onCommitGlow(           LLUICtrl* ctrl, void *userdata); -	static void		onCommitPlanarAlign(	LLUICtrl* ctrl, void* userdata); -	 -	static void		onClickApply(void*); +	static void    onCommitGlow(				LLUICtrl* ctrl, void *userdata); +	static void		onCommitPlanarAlign(		LLUICtrl* ctrl, void* userdata); +	static void		onCommitRepeatsPerMeter(	LLUICtrl* ctrl, void* userinfo);  	static void		onClickAutoFix(void*); -	static F32      valueGlow(LLViewerObject* object, S32 face); + +	static F32     valueGlow(LLViewerObject* object, S32 face);  private: +	bool		isAlpha() { return mIsAlpha; } + +	// Convenience funcs to keep the visual flack to a minimum +	// +	LLUUID	getCurrentNormalMap(); +	LLUUID	getCurrentSpecularMap(); +	U32		getCurrentShininess(); +	U32		getCurrentBumpiness(); +	U8			getCurrentDiffuseAlphaMode(); +	U8			getCurrentAlphaMaskCutoff(); +	U8			getCurrentEnvIntensity(); +	U8			getCurrentGlossiness(); +	F32		getCurrentBumpyRot(); +	F32		getCurrentBumpyScaleU(); +	F32		getCurrentBumpyScaleV(); +	F32		getCurrentBumpyOffsetU(); +	F32		getCurrentBumpyOffsetV(); +	F32		getCurrentShinyRot(); +	F32		getCurrentShinyScaleU(); +	F32		getCurrentShinyScaleV(); +	F32		getCurrentShinyOffsetU(); +	F32		getCurrentShinyOffsetV(); + +	// Update visibility of controls to match current UI mode +	// (e.g. materials vs media editing) +	// +	// Do NOT call updateUI from within this function. +	// +	void updateVisibility(); + +	// Make material(s) reflect current state of UI (apply edit) +	// +	void updateMaterial(); + +	// Hey look everyone, a type-safe alternative to copy and paste! :) +	// + +	// Update material parameters by applying 'edit_func' to selected TEs +	// +	template< +		typename DataType, +		typename SetValueType, +		void (LLMaterial::*MaterialEditFunc)(SetValueType data) > +	static void edit(LLPanelFace* p, DataType data) +	{ +		LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc > edit(data); +		struct LLSelectedTEEditMaterial : public LLSelectedTEMaterialFunctor +		{ +			LLSelectedTEEditMaterial(LLPanelFace* panel, LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* editp) : _panel(panel), _edit(editp) {} +			virtual ~LLSelectedTEEditMaterial() {}; +			virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) +			{ +				if (_edit) +				{ +					LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial()); +					llassert_always(new_material); + +					// Determine correct alpha mode for current diffuse texture +					// (i.e. does it have an alpha channel that makes alpha mode useful) +					// +					U8 default_alpha_mode = (_panel->isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE); + +					// Default to matching expected state of UI +					// +					new_material->setDiffuseAlphaMode(current_material.isNull() ? default_alpha_mode : current_material->getDiffuseAlphaMode()); + +					// Do "It"! +					// +					_edit->apply(new_material); + +					U32		new_alpha_mode			= new_material->getDiffuseAlphaMode(); +					LLUUID	new_normal_map_id		= new_material->getNormalID(); +					LLUUID	new_spec_map_id		= new_material->getSpecularID(); + +					bool is_default_blend_mode		= (new_alpha_mode == default_alpha_mode); +					bool is_need_material			= !is_default_blend_mode || !new_normal_map_id.isNull() || !new_spec_map_id.isNull(); + +					if (!is_need_material) +					{ +						LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL; +						LLMaterialMgr::getInstance()->remove(object->getID(),face); +						new_material = NULL; +					} +					else +					{ +						LL_DEBUGS("Materials") << "Putting material on object " << object->getID() << " face " << face << ", material: " << new_material->asLLSD() << LL_ENDL; +						LLMaterialMgr::getInstance()->put(object->getID(),face,*new_material); +					} + +					object->setTEMaterialParams(face, new_material); +					return new_material; +				} +				return NULL; +			} +			LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >*	_edit; +			LLPanelFace*																			_panel; +		} editor(p, &edit); +		LLSelectMgr::getInstance()->selectionSetMaterialParams(&editor); +	} + +	template< +		typename DataType, +		typename ReturnType, +		ReturnType (LLMaterial::* const MaterialGetFunc)() const  > +	static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value) +	{ +		DataType data_value; +		struct GetTEMaterialVal : public LLSelectedTEGetFunctor<DataType> +		{ +			GetTEMaterialVal(DataType default_value) : _default(default_value) {} +			virtual ~GetTEMaterialVal() {} + +			DataType get(LLViewerObject* object, S32 face) +			{ +				DataType ret = _default; +				LLMaterialPtr material_ptr; +				LLTextureEntry* tep = object ? object->getTE(face) : NULL; +				if (tep) +				{ +					material_ptr = tep->getMaterialParams(); +					if (!material_ptr.isNull()) +					{ +						ret = (material_ptr->*(MaterialGetFunc))(); +					} +				} +				return ret; +			} +			DataType _default; +		} GetFunc(default_value); +		identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetFunc, data_value); +		data_to_return = data_value; +	} + +	template< +		typename DataType, +		typename ReturnType, // some kids just have to different... +		ReturnType (LLTextureEntry::* const TEGetFunc)() const > +	static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value) +	{ +		DataType data_value; +		struct GetTEVal : public LLSelectedTEGetFunctor<DataType> +		{ +			GetTEVal(DataType default_value) : _default(default_value) {} +			virtual ~GetTEVal() {} + +			DataType get(LLViewerObject* object, S32 face) { +				LLTextureEntry* tep = object ? object->getTE(face) : NULL; +				return tep ? ((tep->*(TEGetFunc))()) : _default; +			} +			DataType _default; +		} GetTEValFunc(default_value); +		identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value ); +		data_to_return = data_value; +	} + +	// Update vis and enabling of specific subsets of controls based on material params +	// (e.g. hide the spec controls if no spec texture is applied) +	// +	void updateShinyControls(bool is_setting_texture = false, bool mess_with_combobox = false); +	void updateBumpyControls(bool is_setting_texture = false, bool mess_with_combobox = false); +	void updateAlphaControls(); +  	/*  	 * Checks whether the selected texture from the LLFloaterTexturePicker can be applied to the currently selected object.  	 * If agent selects texture which is not allowed to be applied for the currently selected object, @@ -100,6 +349,126 @@ private:  	 */  	void onTextureSelectionChanged(LLInventoryItem* itemp); +	bool mIsAlpha; +	 +	/* These variables interlock processing of materials updates sent to +	 * the sim.  mUpdateInFlight is set to flag that an update has been +	 * sent to the sim and not acknowledged yet, and cleared when an +	 * update is received from the sim.  mUpdatePending is set when +	 * there's an update in flight and another UI change has been made +	 * that needs to be sent as a materials update, and cleared when the +	 * update is sent.  This prevents the sim from getting spammed with +	 * update messages when, for example, the user holds down the +	 * up-arrow on a spinner, and avoids running afoul of its throttle. +	 */ +	bool mUpdateInFlight; +	bool mUpdatePending; + +	#if defined(DEF_GET_MAT_STATE) +		#undef DEF_GET_MAT_STATE +	#endif + +	#if defined(DEF_GET_TE_STATE) +		#undef DEF_GET_TE_STATE +	#endif + +	#if defined(DEF_EDIT_MAT_STATE) +		DEF_EDIT_MAT_STATE +	#endif + +	// Accessors for selected TE material state +	// +	#define DEF_GET_MAT_STATE(DataType,ReturnType,MaterialMemberFunc,DefaultValue)												\ +		static void MaterialMemberFunc(DataType& data, bool& identical)																\ +		{																																					\ +			getTEMaterialValue< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(data, identical,DefaultValue);	\ +		} + +	// Mutators for selected TE material +	// +	#define DEF_EDIT_MAT_STATE(DataType,ReturnType,MaterialMemberFunc)																\ +		static void MaterialMemberFunc(LLPanelFace* p,DataType data)																	\ +		{																																					\ +			edit< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(p,data);													\ +		} + +	// Accessors for selected TE state proper (legacy settings etc) +	// +	#define DEF_GET_TE_STATE(DataType,ReturnType,TexEntryMemberFunc,DefaultValue)													\ +		static void TexEntryMemberFunc(DataType& data, bool& identical)																\ +		{																																					\ +			getTEValue< DataType, ReturnType, &LLTextureEntry::TexEntryMemberFunc >(data, identical,DefaultValue);		\ +		} + +	class LLSelectedTEMaterial +	{ +	public: +		static void getCurrent(LLMaterialPtr& material_ptr, bool& identical_material); +		static void getMaxSpecularRepeats(F32& repeats, bool& identical); +		static void getMaxNormalRepeats(F32& repeats, bool& identical); +		static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha); + +		DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getNormalID,LLUUID::null) +		DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getSpecularID,LLUUID::null) +		DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatX,1.0f) +		DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatY,1.0f) +		DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetX,0.0f) +		DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetY,0.0f) +		DEF_GET_MAT_STATE(F32,F32,getSpecularRotation,0.0f) + +		DEF_GET_MAT_STATE(F32,F32,getNormalRepeatX,1.0f) +		DEF_GET_MAT_STATE(F32,F32,getNormalRepeatY,1.0f) +		DEF_GET_MAT_STATE(F32,F32,getNormalOffsetX,0.0f) +		DEF_GET_MAT_STATE(F32,F32,getNormalOffsetY,0.0f) +		DEF_GET_MAT_STATE(F32,F32,getNormalRotation,0.0f) + +		DEF_EDIT_MAT_STATE(U8,U8,setDiffuseAlphaMode); +		DEF_EDIT_MAT_STATE(U8,U8,setAlphaMaskCutoff); + +		DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetX); +		DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetY); +		DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatX); +		DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatY); +		DEF_EDIT_MAT_STATE(F32,F32,setNormalRotation); + +		DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetX); +		DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetY); +		DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatX); +		DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatY); +		DEF_EDIT_MAT_STATE(F32,F32,setSpecularRotation); + +		DEF_EDIT_MAT_STATE(U8,U8,setEnvironmentIntensity); +		DEF_EDIT_MAT_STATE(U8,U8,setSpecularLightExponent); + +		DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID); +		DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID); +		DEF_EDIT_MAT_STATE(LLColor4U,	const LLColor4U&,setSpecularLightColor); +	}; + +	class LLSelectedTE +	{ +	public: + +		static void getFace(class LLFace*& face_to_return, bool& identical_face); +		static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face); +		static void getTexId(LLUUID& id, bool& identical); +		static void getObjectScaleS(F32& scale_s, bool& identical); +		static void getObjectScaleT(F32& scale_t, bool& identical); +		static void getMaxDiffuseRepeats(F32& repeats, bool& identical); + +		DEF_GET_TE_STATE(U8,U8,getBumpmap,0) +		DEF_GET_TE_STATE(U8,U8,getShiny,0) +		DEF_GET_TE_STATE(U8,U8,getFullbright,0) +		DEF_GET_TE_STATE(F32,F32,getRotation,0.0f) +		DEF_GET_TE_STATE(F32,F32,getOffsetS,0.0f) +		DEF_GET_TE_STATE(F32,F32,getOffsetT,0.0f) +		DEF_GET_TE_STATE(F32,F32,getScaleS,1.0f) +		DEF_GET_TE_STATE(F32,F32,getScaleT,1.0f) +		DEF_GET_TE_STATE(F32,F32,getGlow,0.0f) +		DEF_GET_TE_STATE(LLTextureEntry::e_texgen,LLTextureEntry::e_texgen,getTexGen,LLTextureEntry::TEX_GEN_DEFAULT) +		DEF_GET_TE_STATE(LLColor4,const LLColor4&,getColor,LLColor4::white)		 +	};  };  #endif + diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 3ee0746412..18b85cc9c3 100755 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -428,13 +428,13 @@ F32 LLPhysicsMotion::toLocal(const LLVector3 &world)  F32 LLPhysicsMotion::calculateVelocity_local()  {  	const F32 world_to_model_scale = 100.0f; -	LLJoint *joint = mJointState->getJoint(); -	const LLVector3 position_world = joint->getWorldPosition(); -	const LLVector3 last_position_world = mPosition_world; +        LLJoint *joint = mJointState->getJoint(); +        const LLVector3 position_world = joint->getWorldPosition(); +        const LLVector3 last_position_world = mPosition_world;  	const LLVector3 positionchange_world = (position_world-last_position_world) * world_to_model_scale; -	const LLVector3 velocity_world = positionchange_world; -	const F32 velocity_local = toLocal(velocity_world); -	return velocity_local; +        const LLVector3 velocity_world = positionchange_world; +        const F32 velocity_local = toLocal(velocity_world); +        return velocity_local;  }  F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local) diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp index 8086745471..ed9eeb9330 100644 --- a/indra/newview/llscenemonitor.cpp +++ b/indra/newview/llscenemonitor.cpp @@ -500,7 +500,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name)  	std::ofstream os(file_name.c_str()); -	os << std::setprecision(3); +	os << std::setprecision(10);  	PeriodicRecording& scene_load_recording = mSceneLoadRecording.getAcceptedRecording();  	const U32 frame_count = scene_load_recording.getNumRecordedPeriods(); @@ -508,12 +508,12 @@ void LLSceneMonitor::dumpToFile(std::string file_name)  	LLUnit<F64, LLUnits::Seconds> frame_time;  	os << "Stat"; -	for (S32 frame = 0; frame < frame_count; frame++) +	for (S32 frame = 1; frame <= frame_count; frame++)  	{  		frame_time += scene_load_recording.getPrevRecording(frame_count - frame).getDuration();  		os << ", " << frame_time.value();  	} -	os << std::endl; +	os << '\n';  	typedef TraceType<CountAccumulator> trace_count;  	for (trace_count::instance_iter it = trace_count::beginInstances(), end_it = trace_count::endInstances(); @@ -521,6 +521,8 @@ void LLSceneMonitor::dumpToFile(std::string file_name)  		++it)  	{  		std::ostringstream row; +		row << std::setprecision(10); +  		row << it->getName();  		const char* unit_label = it->getUnitLabel(); @@ -531,13 +533,13 @@ void LLSceneMonitor::dumpToFile(std::string file_name)  		S32 samples = 0; -		for (S32 frame = 0; frame < frame_count; frame++) +		for (S32 frame = 1; frame <= frame_count; frame++)  		{  			samples += scene_load_recording.getPrevRecording(frame_count - frame).getSampleCount(*it);  			row << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getSum(*it);  		} -		row << std::endl; +		row << '\n';  		if (samples > 0)  		{ @@ -552,6 +554,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name)  		++it)  	{  		std::ostringstream row; +		row << std::setprecision(10);  		row << it->getName();  		const char* unit_label = it->getUnitLabel(); @@ -562,13 +565,13 @@ void LLSceneMonitor::dumpToFile(std::string file_name)  		S32 samples = 0; -		for (S32 frame = 0; frame < frame_count; frame++) +		for (S32 frame = 1; frame <= frame_count; frame++)  		{  			samples += scene_load_recording.getPrevRecording(frame_count - frame).getSampleCount(*it);  			row << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMean(*it);  		} -		row << std::endl; +		row << '\n';  		if (samples > 0)  		{ @@ -583,6 +586,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name)  		++it)  	{  		std::ostringstream row; +		row << std::setprecision(10);  		row << it->getName();  		const char* unit_label = it->getUnitLabel(); @@ -593,13 +597,13 @@ void LLSceneMonitor::dumpToFile(std::string file_name)  		S32 samples = 0; -		for (S32 frame = 0; frame < frame_count; frame++) +		for (S32 frame = 1; frame <= frame_count; frame++)  		{  			samples += scene_load_recording.getPrevRecording(frame_count - frame).getSampleCount(*it);  			row << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMean(*it);  		} -		row << std::endl; +		row << '\n';   		if (samples > 0)  		{ @@ -614,12 +618,12 @@ void LLSceneMonitor::dumpToFile(std::string file_name)  	{  		os << it->getName() << "(KiB)"; -		for (S32 frame = 0; frame < frame_count; frame++) +		for (S32 frame = 1; frame <= frame_count; frame++)  		{  			os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(*it).getAs<LLUnits::Kibibytes>();  		} -		os << std::endl; +		os << '\n';  	}  	os.flush(); diff --git a/indra/newview/llscenemonitor.h b/indra/newview/llscenemonitor.h index 6af58b707a..9717310da4 100644 --- a/indra/newview/llscenemonitor.h +++ b/indra/newview/llscenemonitor.h @@ -37,7 +37,7 @@ class LLCharacter;  class LLRenderTarget;  class LLViewerTexture; -class LLSceneMonitor :  public LLSingleton<LLSceneMonitor> +class LLSceneMonitor : public LLSingleton<LLSceneMonitor>  {  	LOG_CLASS(LLSceneMonitor);  public: diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index da6ca8964a..b47c2de768 100755 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -29,6 +29,7 @@  // file include  #define LLSELECTMGR_CPP  #include "llselectmgr.h" +#include "llmaterialmgr.h"  // library includes  #include "llcachename.h" @@ -103,7 +104,6 @@ const F32 SILHOUETTE_UPDATE_THRESHOLD_SQUARED = 0.02f;  const S32 MAX_ACTION_QUEUE_SIZE = 20;  const S32 MAX_SILS_PER_FRAME = 50;  const S32 MAX_OBJECTS_PER_PACKET = 254; -const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF;  //  // Globals @@ -188,6 +188,7 @@ LLSelectMgr::LLSelectMgr()     mDebugSelectMgr(LLCachedControl<bool>(gSavedSettings, "DebugSelectMgr", FALSE))  {  	mTEMode = FALSE; +	mTextureChannel = LLRender::DIFFUSE_MAP;  	mLastCameraPos.clearVec();  	sHighlightThickness	= gSavedSettings.getF32("SelectionHighlightThickness"); @@ -236,6 +237,8 @@ void LLSelectMgr::clearSelections()  	mHighlightedObjects->deleteAllNodes();  	mRectSelectedObjects.clear();  	mGridObjects.deleteAllNodes(); + +	LLPipeline::setRenderHighlightTextureChannel(LLRender::DIFFUSE_MAP);  }  void LLSelectMgr::update() @@ -815,6 +818,7 @@ void LLSelectMgr::addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to  			if (objectp->getNumTEs() > 0)  			{  				nodep->selectAllTEs(TRUE); +				objectp->setAllTESelected(true);  			}  			else  			{ @@ -843,6 +847,10 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab  	// check to see if object is already in list  	LLSelectNode *nodep = mSelectedObjects->findNode(objectp); +	// Reset (in anticipation of being set to an appropriate value by panel refresh, if they're up) +	// +	setTextureChannel(LLRender::DIFFUSE_MAP); +  	// if not in list, add it  	if (!nodep)  	{ @@ -872,10 +880,12 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab  	else if (face == SELECT_ALL_TES)  	{  		nodep->selectAllTEs(TRUE); +		objectp->setAllTESelected(true);  	}  	else if (0 <= face && face < SELECT_MAX_TES)  	{  		nodep->selectTE(face, TRUE); +		objectp->setTESelected(face, true);  	}  	else  	{ @@ -1095,6 +1105,7 @@ LLObjectSelectionHandle LLSelectMgr::selectHighlightedObjects()  		// flag this object as selected  		objectp->setSelected(TRUE); +		objectp->setAllTESelected(true);  		mSelectedObjects->mSelectType = getSelectTypeForObject(objectp); @@ -1318,6 +1329,7 @@ void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable)  		if (nodep->isTESelected(te))  		{  			nodep->selectTE(te, FALSE); +			objectp->setTESelected(te, false);  		}  		else  		{ @@ -2004,6 +2016,76 @@ void LLSelectMgr::selectionSetGlow(F32 glow)  	mSelectedObjects->applyToObjects( &func2 );  } +void LLSelectMgr::selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func) +{ +	struct f1 : public LLSelectedTEFunctor +	{ +		LLMaterialPtr mMaterial; +		f1(LLSelectedTEMaterialFunctor* material_func) : _material_func(material_func) {} + +		bool apply(LLViewerObject* object, S32 face) +		{ +			if (object && object->permModify() && _material_func) +			{ +				LLTextureEntry* tep = object->getTE(face); +				if (tep) +				{ +					LLMaterialPtr current_material = tep->getMaterialParams(); +					_material_func->apply(object, face, tep, current_material); +				} +			} +			return true; +		} + +		LLSelectedTEMaterialFunctor* _material_func; +	} func1(material_func); +	mSelectedObjects->applyToTEs( &func1 ); + +	struct f2 : public LLSelectedObjectFunctor +	{ +		virtual bool apply(LLViewerObject* object) +		{ +			if (object->permModify()) +			{ +				object->sendTEUpdate(); +			} +			return true; +		} +	} func2; +	mSelectedObjects->applyToObjects( &func2 ); +} + +void LLSelectMgr::selectionRemoveMaterial() +{ +	struct f1 : public LLSelectedTEFunctor +	{ +		bool apply(LLViewerObject* object, S32 face) +		{ +			if (object->permModify()) +			{ +			        LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL; +				LLMaterialMgr::getInstance()->remove(object->getID(),face); +				object->setTEMaterialParams(face, NULL); +			} +			return true; +		} +	} func1; +	mSelectedObjects->applyToTEs( &func1 ); + +	struct f2 : public LLSelectedObjectFunctor +	{ +		virtual bool apply(LLViewerObject* object) +		{ +			if (object->permModify()) +			{ +				object->sendTEUpdate(); +			} +			return true; +		} +	} func2; +	mSelectedObjects->applyToObjects( &func2 ); +} +  //-----------------------------------------------------------------------------  // findObjectPermissions() @@ -2425,19 +2507,66 @@ void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch)  					continue;  				} -				LLVector3 scale_ratio = selectNode->mTextureScaleRatios[te_num];   				LLVector3 object_scale = object->getScale(); +				LLVector3 diffuse_scale_ratio  = selectNode->mTextureScaleRatios[te_num];  + +				// We like these to track together. NORSPEC-96 +				// +				LLVector3 normal_scale_ratio   = diffuse_scale_ratio;  +				LLVector3 specular_scale_ratio = diffuse_scale_ratio;   				// Apply new scale to face  				if (planar)  				{ -					object->setTEScale(te_num, 1.f/object_scale.mV[s_axis]*scale_ratio.mV[s_axis], -										1.f/object_scale.mV[t_axis]*scale_ratio.mV[t_axis]); +					F32 diffuse_scale_s = diffuse_scale_ratio.mV[s_axis]/object_scale.mV[s_axis]; +					F32 diffuse_scale_t = diffuse_scale_ratio.mV[t_axis]/object_scale.mV[t_axis]; + +					F32 normal_scale_s = normal_scale_ratio.mV[s_axis]/object_scale.mV[s_axis]; +					F32 normal_scale_t = normal_scale_ratio.mV[t_axis]/object_scale.mV[t_axis]; + +					F32 specular_scale_s = specular_scale_ratio.mV[s_axis]/object_scale.mV[s_axis]; +					F32 specular_scale_t = specular_scale_ratio.mV[t_axis]/object_scale.mV[t_axis]; + +					object->setTEScale(te_num, diffuse_scale_s, diffuse_scale_t); + +					LLTextureEntry* tep = object->getTE(te_num); + +					if (tep && !tep->getMaterialParams().isNull()) +					{ +						LLMaterialPtr orig = tep->getMaterialParams(); +						LLMaterialPtr p = new LLMaterial(orig->asLLSD()); +						p->setNormalRepeat(normal_scale_s, normal_scale_t); +						p->setSpecularRepeat(specular_scale_s, specular_scale_t); + +						LLMaterialMgr::getInstance()->put(object->getID(), te_num, *p); +					}  				}  				else  				{ -					object->setTEScale(te_num, scale_ratio.mV[s_axis]*object_scale.mV[s_axis], -											scale_ratio.mV[t_axis]*object_scale.mV[t_axis]); + +					F32 diffuse_scale_s = diffuse_scale_ratio.mV[s_axis]*object_scale.mV[s_axis]; +					F32 diffuse_scale_t = diffuse_scale_ratio.mV[t_axis]*object_scale.mV[t_axis]; + +					F32 normal_scale_s = normal_scale_ratio.mV[s_axis]*object_scale.mV[s_axis]; +					F32 normal_scale_t = normal_scale_ratio.mV[t_axis]*object_scale.mV[t_axis]; + +					F32 specular_scale_s = specular_scale_ratio.mV[s_axis]*object_scale.mV[s_axis]; +					F32 specular_scale_t = specular_scale_ratio.mV[t_axis]*object_scale.mV[t_axis]; + +					object->setTEScale(te_num, diffuse_scale_s,diffuse_scale_t); + +					LLTextureEntry* tep = object->getTE(te_num); + +					if (tep && !tep->getMaterialParams().isNull()) +					{ +						LLMaterialPtr orig = tep->getMaterialParams(); + +						LLMaterialPtr p = new LLMaterial(orig->asLLSD()); +						p->setNormalRepeat(normal_scale_s, normal_scale_t); +						p->setSpecularRepeat(specular_scale_s, specular_scale_t); + +						LLMaterialMgr::getInstance()->put(object->getID(), te_num, *p); +					}  				}  				send = send_to_sim;  			} @@ -2980,18 +3109,18 @@ private:  void LLSelectMgr::getFirst(LLSelectGetFirstTest* test)  {  	if (gSavedSettings.getBOOL("EditLinkedParts")) -{ +	{  		for (LLObjectSelection::valid_iterator iter = getSelection()->valid_begin();  			iter != getSelection()->valid_end(); ++iter ) -	{ -			if (!test->checkMatchingNode(*iter))  		{ +			if (!test->checkMatchingNode(*iter)) +			{  				break;  			}  		} -		} -		else -		{ +	} +	else +	{  		for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();  			iter != getSelection()->root_object_end(); ++iter )  		{ @@ -3001,31 +3130,31 @@ void LLSelectMgr::getFirst(LLSelectGetFirstTest* test)  			}  		}  	} -	} +}  //-----------------------------------------------------------------------------  // selectGetCreator()  // Creator information only applies to roots unless editing linked parts.  //-----------------------------------------------------------------------------  struct LLSelectGetFirstCreator : public LLSelectGetFirstTest -	{ +{  protected:  	virtual const LLUUID& getValueFromNode(LLSelectNode* node) -		{ +	{  		return node->mPermissions->getCreator(); -		} +	}  };  BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, std::string& name) -		{ +{  	LLSelectGetFirstCreator test;  	getFirst(&test);  	if (test.mFirstValue.isNull()) -		{ -			name = LLTrans::getString("AvatarNameNobody"); +	{ +		name = LLTrans::getString("AvatarNameNobody");  		return FALSE; -		} +	}  	result_id = test.mFirstValue; @@ -3046,18 +3175,18 @@ BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, std::string& name)  // Owner information only applies to roots unless editing linked parts.  //-----------------------------------------------------------------------------  struct LLSelectGetFirstOwner : public LLSelectGetFirstTest -	{ +{  protected:  	virtual const LLUUID& getValueFromNode(LLSelectNode* node) -		{ +	{  		// Don't use 'getOwnership' since we return a reference, not a copy.  		// Will return LLUUID::null if unowned (which is not allowed and should never happen.)  		return node->mPermissions->isGroupOwned() ? node->mPermissions->getGroup() : node->mPermissions->getOwner(); -		} +	}  };  BOOL LLSelectMgr::selectGetOwner(LLUUID& result_id, std::string& name) -		{ +{  	LLSelectGetFirstOwner test;  	getFirst(&test); @@ -3096,34 +3225,34 @@ struct LLSelectGetFirstLastOwner : public LLSelectGetFirstTest  {  protected:  	virtual const LLUUID& getValueFromNode(LLSelectNode* node) -{ +	{  		return node->mPermissions->getLastOwner();  	}  };  BOOL LLSelectMgr::selectGetLastOwner(LLUUID& result_id, std::string& name) -	{ +{  	LLSelectGetFirstLastOwner test;  	getFirst(&test);  	if (test.mFirstValue.isNull()) -		{ -			return FALSE; -		} +	{ +		return FALSE; +	}  	result_id = test.mFirstValue;  	if (test.mIdentical) -		{ +	{  		name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString(); -		} -		else -		{ +	} +	else +	{  		name.assign( "" ); -			} +	}  	return test.mIdentical; -		} +}  //-----------------------------------------------------------------------------  // selectGetGroup() @@ -3153,10 +3282,10 @@ BOOL LLSelectMgr::selectGetGroup(LLUUID& result_id)  // Returns TRUE if the first selected is group owned.  //-----------------------------------------------------------------------------  struct LLSelectGetFirstGroupOwner : public LLSelectGetFirstTest -	{ +{  protected:  	virtual const LLUUID& getValueFromNode(LLSelectNode* node) -		{ +	{  		if (node->mPermissions->isGroupOwned())  		{  			return node->mPermissions->getGroup(); @@ -4396,7 +4525,8 @@ void LLSelectMgr::saveSelectedObjectTransform(EActionType action_type)  	struct f : public LLSelectedNodeFunctor  	{  		EActionType mActionType; -		f(EActionType a) : mActionType(a) {} +		LLSelectMgr* mManager; +		f(EActionType a, LLSelectMgr* p) : mActionType(a), mManager(p) {}  		virtual bool apply(LLSelectNode* selectNode)  		{  			LLViewerObject*	object = selectNode->getObject(); @@ -4443,10 +4573,10 @@ void LLSelectMgr::saveSelectedObjectTransform(EActionType action_type)  			}  			selectNode->mSavedScale = object->getScale(); -			selectNode->saveTextureScaleRatios(); +			selectNode->saveTextureScaleRatios(mManager->mTextureChannel);			  			return true;  		} -	} func(action_type); +	} func(action_type, this);  	getSelection()->applyToNodes(&func);	  	mSavedSelectionBBox = getBBoxOfSelection(); @@ -5757,36 +5887,43 @@ void LLSelectNode::saveTextures(const uuid_vec_t& textures)  	}  } -void LLSelectNode::saveTextureScaleRatios() +void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query)  {  	mTextureScaleRatios.clear(); +  	if (mObject.notNull())  	{ +		 +		LLVector3 scale = mObject->getScale(); +  		for (U8 i = 0; i < mObject->getNumTEs(); i++)  		{ -			F32 s,t; +			F32 diffuse_s = 1.0f; +			F32 diffuse_t = 1.0f; +			 +			LLVector3 v;  			const LLTextureEntry* tep = mObject->getTE(i); -			tep->getScale(&s,&t); -			U32 s_axis = 0; -			U32 t_axis = 0; +			if (!tep) +				continue; +			U32 s_axis = VX; +			U32 t_axis = VY;  			LLPrimitive::getTESTAxes(i, &s_axis, &t_axis); -			LLVector3 v; -			LLVector3 scale = mObject->getScale(); +			tep->getScale(&diffuse_s,&diffuse_t);  			if (tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR)  			{ -				v.mV[s_axis] = s*scale.mV[s_axis]; -				v.mV[t_axis] = t*scale.mV[t_axis]; +				v.mV[s_axis] = diffuse_s*scale.mV[s_axis]; +				v.mV[t_axis] = diffuse_t*scale.mV[t_axis]; +				mTextureScaleRatios.push_back(v);  			}  			else  			{ -				v.mV[s_axis] = s/scale.mV[s_axis]; -				v.mV[t_axis] = t/scale.mV[t_axis]; +				v.mV[s_axis] = diffuse_s/scale.mV[s_axis]; +				v.mV[t_axis] = diffuse_t/scale.mV[t_axis]; +				mTextureScaleRatios.push_back(v);  			} - -			mTextureScaleRatios.push_back(v);  		}  	}  } diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index cc78e35869..d4b736640c 100755 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -43,10 +43,12 @@  #include "llpermissions.h"  #include "llcontrol.h"  #include "llviewerobject.h"	// LLObjectSelection::getSelectedTEValue template +#include "llmaterial.h"  #include <deque>  #include <boost/iterator/filter_iterator.hpp>  #include <boost/signals2.hpp> +#include <boost/make_shared.hpp>	// boost::make_shared  class LLMessageSystem;  class LLViewerTexture; @@ -83,6 +85,12 @@ struct LLSelectedTEFunctor  	virtual bool apply(LLViewerObject* object, S32 face) = 0;  }; +struct LLSelectedTEMaterialFunctor +{ +	virtual ~LLSelectedTEMaterialFunctor() {}; +	virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) = 0; +}; +  template <typename T> struct LLSelectedTEGetFunctor  {  	virtual ~LLSelectedTEGetFunctor() {}; @@ -121,6 +129,8 @@ typedef enum e_selection_type  	SELECT_TYPE_HUD  }ESelectType; +const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF; +  // Contains information about a selected object, particularly which TEs are selected.  class LLSelectNode  { @@ -143,7 +153,7 @@ public:  	// *NOTE: invalidate stored textures and colors when # faces change  	void saveColors();  	void saveTextures(const uuid_vec_t& textures); -	void saveTextureScaleRatios(); +	void saveTextureScaleRatios(LLRender::eTexIndex index_to_query);  	BOOL allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const; @@ -510,6 +520,11 @@ public:  	void saveSelectedObjectColors();  	void saveSelectedObjectTextures(); +	// Sets which texture channel to query for scale and rot of display +	// and depends on UI state of LLPanelFace when editing +	void setTextureChannel(LLRender::eTexIndex texIndex) { mTextureChannel = texIndex; } +	LLRender::eTexIndex getTextureChannel() { return mTextureChannel; } +  	void selectionUpdatePhysics(BOOL use_physics);  	void selectionUpdateTemporary(BOOL is_temporary);  	void selectionUpdatePhantom(BOOL is_ghost); @@ -540,6 +555,8 @@ public:  	void selectionSetClickAction(U8 action);  	void selectionSetIncludeInSearch(bool include_in_search);  	void selectionSetGlow(const F32 glow); +	void selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func); +	void selectionRemoveMaterial();  	void selectionSetObjectPermissions(U8 perm_field, BOOL set, U32 perm_mask, BOOL override = FALSE);  	void selectionSetObjectName(const std::string& name); @@ -771,6 +788,7 @@ private:  	EGridMode				mGridMode;  	BOOL					mTEMode;			// render te +	LLRender::eTexIndex	mTextureChannel; // diff, norm, or spec, depending on UI editing mode  	LLVector3d				mSelectionCenterGlobal;  	LLBBox					mSelectionBBox; diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index efef422bfb..a405129a25 100755 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -231,7 +231,7 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)  		{  			gAgentCamera.changeCameraToDefault();  			gAgentCamera.resetView(); -		} +		}	  	}  } diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h index 6359d6e86e..cde05a8d9b 100755 --- a/indra/newview/llsidepanelappearance.h +++ b/indra/newview/llsidepanelappearance.h @@ -47,7 +47,7 @@ public:  	virtual ~LLSidepanelAppearance();  	/*virtual*/ BOOL postBuild(); -	/*virtual*/ void onOpen(const LLSD& key); +	/*virtual*/ void onOpen(const LLSD& key);	  	void refreshCurrentOutfitName(const std::string& name = ""); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index b9d4c016c2..caa551d6fa 100755 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -487,12 +487,12 @@ void LLSpatialPartition::rebuildMesh(LLSpatialGroup* group)  }  LLSpatialGroup* LLSpatialGroup::getParent() -{	 +{  	return (LLSpatialGroup*)LLviewerOctreeGroup::getParent(); -} +	}  BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) -{ +	{  	if(!drawablep)  	{  		return FALSE; @@ -858,7 +858,7 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node)  				((LLDrawable*)entry->getDrawable())->setGroup(NULL);  			}  			else -			{ +	{  				llerrs << "No Drawable found in the entry." << llendl;  			}  		} @@ -1476,11 +1476,11 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result  	((LLSpatialGroup*)mOctree->getListener(0))->validate();  #endif -	LLOctreeSelect selecter(&camera, results); -	selecter.traverse(mOctree); +		LLOctreeSelect selecter(&camera, results); +		selecter.traverse(mOctree);  	return 0; -} +	}  S32 LLSpatialPartition::cull(LLCamera &camera)  { @@ -2131,9 +2131,9 @@ void renderNormals(LLDrawable* drawablep)  				gGL.vertex3fv(face.mPositions[j].getF32ptr());  				gGL.vertex3fv(p.getF32ptr()); -				if (face.mBinormals) +				if (face.mTangents)  				{ -					n.setMul(face.mBinormals[j], scale); +					n.setMul(face.mTangents[j], scale);  					p.setAdd(face.mPositions[j], n);  					gGL.diffuseColor4f(0,1,1,1); @@ -2984,11 +2984,17 @@ void renderRaycast(LLDrawable* drawablep)  					gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);					  					gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix); -					LLVector3 start, end; +					LLVector4a start, end;  					if (transform)  					{ -						start = vobj->agentPositionToVolume(gDebugRaycastStart); -						end = vobj->agentPositionToVolume(gDebugRaycastEnd); +						LLVector3 v_start(gDebugRaycastStart.getF32ptr()); +						LLVector3 v_end(gDebugRaycastEnd.getF32ptr()); + +						v_start = vobj->agentPositionToVolume(v_start); +						v_end = vobj->agentPositionToVolume(v_end); + +						start.load3(v_start.mV); +						end.load3(v_end.mV);  					}  					else  					{ @@ -2996,11 +3002,8 @@ void renderRaycast(LLDrawable* drawablep)  						end = gDebugRaycastEnd;  					} -					LLVector4a starta, enda; -					starta.load3(start.mV); -					enda.load3(end.mV);  					LLVector4a dir; -					dir.setSub(enda, starta); +					dir.setSub(end, start);  					gGL.flush();  					glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);				 @@ -3023,7 +3026,7 @@ void renderRaycast(LLDrawable* drawablep)  							((LLVolumeFace*) &face)->createOctree();   						} -						LLRenderOctreeRaycast render(starta, dir, &t); +						LLRenderOctreeRaycast render(start, dir, &t);  						render.traverse(face.mOctree);  					} @@ -3048,10 +3051,18 @@ void renderRaycast(LLDrawable* drawablep)  			// draw intersection point  			gGL.pushMatrix();  			gGL.loadMatrix(gGLModelView); -			LLVector3 translate = gDebugRaycastIntersection; +			LLVector3 translate(gDebugRaycastIntersection.getF32ptr());  			gGL.translatef(translate.mV[0], translate.mV[1], translate.mV[2]);  			LLCoordFrame orient; -			orient.lookDir(gDebugRaycastNormal, gDebugRaycastBinormal); +			LLVector4a debug_binormal; +			 +			debug_binormal.setCross3(gDebugRaycastNormal, gDebugRaycastTangent); +			debug_binormal.mul(gDebugRaycastTangent.getF32ptr()[3]); + +			LLVector3 normal(gDebugRaycastNormal.getF32ptr()); +			LLVector3 binormal(debug_binormal.getF32ptr()); +						 +			orient.lookDir(normal, binormal);  			LLMatrix4 rotation;  			orient.getRotMatrixToParent(rotation);  			gGL.multMatrix((float*)rotation.mMatrix); @@ -3565,28 +3576,30 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v)  	return TRUE;  } -class LLOctreeIntersect : public OctreeTraveler +LL_ALIGN_PREFIX(16) +class LLOctreeIntersect : public LLOctreeTraveler<LLViewerOctreeEntry>  {  public: -	LLVector3 mStart; -	LLVector3 mEnd; +	LL_ALIGN_16(LLVector4a mStart); +	LL_ALIGN_16(LLVector4a mEnd); +  	S32       *mFaceHit; -	LLVector3 *mIntersection; +	LLVector4a *mIntersection;  	LLVector2 *mTexCoord; -	LLVector3 *mNormal; -	LLVector3 *mBinormal; +	LLVector4a *mNormal; +	LLVector4a *mTangent;  	LLDrawable* mHit;  	BOOL mPickTransparent; -	LLOctreeIntersect(LLVector3 start, LLVector3 end, BOOL pick_transparent, -					  S32* face_hit, LLVector3* intersection, LLVector2* tex_coord, LLVector3* normal, LLVector3* binormal) +	LLOctreeIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, +					  S32* face_hit, LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)  		: mStart(start),  		  mEnd(end),  		  mFaceHit(face_hit),  		  mIntersection(intersection),  		  mTexCoord(tex_coord),  		  mNormal(normal), -		  mBinormal(binormal), +		  mTangent(tangent),  		  mHit(NULL),  		  mPickTransparent(pick_transparent)  	{ @@ -3618,23 +3631,22 @@ public:  			size = bounds[1];  			center = bounds[0]; -			LLVector3 local_start = mStart; -			LLVector3 local_end   = mEnd; +			LLVector4a local_start = mStart; +			LLVector4a local_end   = mEnd;  			if (group->getSpatialPartition()->isBridge())  			{  				LLMatrix4 local_matrix = group->getSpatialPartition()->asBridge()->mDrawable->getRenderMatrix();  				local_matrix.invert(); -				local_start = mStart * local_matrix; -				local_end   = mEnd   * local_matrix; -			} +				LLMatrix4a local_matrix4a; +				local_matrix4a.loadu(local_matrix); -			LLVector4a start, end; -			start.load3(local_start.mV); -			end.load3(local_end.mV); +				local_matrix4a.affineTransform(mStart, local_start); +				local_matrix4a.affineTransform(mEnd, local_end); +			} -			if (LLLineSegmentBoxIntersect(start, end, center, size)) +			if (LLLineSegmentBoxIntersect(local_start, local_end, center, size))  			{  				check(child);  			} @@ -3644,7 +3656,7 @@ public:  	}  	virtual bool check(LLViewerOctreeEntry* entry) -	{ +	{	  		LLDrawable* drawable = (LLDrawable*)entry->getDrawable();  		if (!drawable || !gPipeline.hasRenderType(drawable->getRenderType()) || !drawable->isVisible()) @@ -3667,14 +3679,14 @@ public:  			if (vobj)  			{ -				LLVector3 intersection; +				LLVector4a intersection;  				bool skip_check = false;  				if (vobj->isAvatar())  				{  					LLVOAvatar* avatar = (LLVOAvatar*) vobj;  					if (avatar->isSelf() && LLFloater::isVisible(gFloaterTools))  					{ -						LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal); +						LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mTangent);  						if (hit)  						{  							mEnd = intersection; @@ -3690,7 +3702,7 @@ public:  					}  				} -				if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal)) +				if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mTangent))  				{  					mEnd = intersection;  // shorten ray so we only find CLOSER hits  					if (mIntersection) @@ -3705,19 +3717,19 @@ public:  		return false;  	} -}; +} LL_ALIGN_POSTFIX(16); -LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  													 BOOL pick_transparent,													  													 S32* face_hit,                   // return the face hit -													 LLVector3* intersection,         // return the intersection point +													 LLVector4a* intersection,         // return the intersection point  													 LLVector2* tex_coord,            // return the texture coordinates of the intersection point -													 LLVector3* normal,               // return the surface normal at the intersection point -													 LLVector3* bi_normal             // return the surface bi-normal at the intersection point +													 LLVector4a* normal,               // return the surface normal at the intersection point +													 LLVector4a* tangent			// return the surface tangent at the intersection point  	)  { -	LLOctreeIntersect intersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, bi_normal); +	LLOctreeIntersect intersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, tangent);  	LLDrawable* drawable = intersect.check(mOctree);  	return drawable; @@ -3743,7 +3755,13 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,  	mGroup(NULL),  	mFace(NULL),  	mDistance(0.f), -	mDrawMode(LLRender::TRIANGLES) +	mDrawMode(LLRender::TRIANGLES), +	mMaterial(NULL), +	mShaderMask(0), +	mSpecColor(1.0f, 1.0f, 1.0f, 0.5f), +	mEnvIntensity(0.0f), +	mAlphaMaskCutoff(0.5f), +	mDiffuseAlphaMode(0)  {  	mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 406e796d4d..05ed70ab59 100755 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -105,6 +105,7 @@ public:  	U32 mOffset;  	BOOL mFullbright;  	U8 mBump; +	U8 mShiny;  	BOOL mParticle;  	F32 mPartSize;  	F32 mVSize; @@ -112,6 +113,18 @@ public:  	LL_ALIGN_16(LLFace* mFace); //associated face  	F32 mDistance;  	U32 mDrawMode; +	LLMaterialPtr mMaterial; // If this is null, the following parameters are unused. +	LLMaterialID mMaterialID; +	U32 mShaderMask; +	LLPointer<LLViewerTexture> mSpecularMap; +	const LLMatrix4* mSpecularMapMatrix; +	LLPointer<LLViewerTexture> mNormalMap; +	const LLMatrix4* mNormalMapMatrix; +	LLVector4 mSpecColor; // XYZ = Specular RGB, W = Specular Exponent +	F32  mEnvIntensity; +	F32  mAlphaMaskCutoff; +	U8   mDiffuseAlphaMode; +  	struct CompareTexture  	{ @@ -184,7 +197,7 @@ public:  	};  }; -LL_ALIGN_PREFIX(16) +LL_ALIGN_PREFIX(64)  class LLSpatialGroup : public LLOcclusionCullingGroup  {  	friend class LLSpatialPartition; @@ -258,11 +271,11 @@ public:  		IN_BUILD_Q1				= (NEW_DRAWINFO << 1),  		IN_BUILD_Q2				= (IN_BUILD_Q1 << 1),  		STATE_MASK				= 0x0000FFFF, -	} eSpatialState;	 +	} eSpatialState;  	LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part); -	BOOL isHUDGroup() ;	 +	BOOL isHUDGroup() ;  	void clearDrawMap();  	void validate(); @@ -278,7 +291,7 @@ public:  	BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE);  	BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group  	BOOL isRecentlyVisible() const; -	void shift(const LLVector4a &offset);	 +	void shift(const LLVector4a &offset);  	void destroyGL(bool keep_occlusion = false);  	void updateDistance(LLCamera& camera); @@ -340,8 +353,8 @@ private:  //-------------------  protected: -	virtual ~LLSpatialGroup();	 -	 +	virtual ~LLSpatialGroup(); +  	static S32 sLODSeed;  public: @@ -351,9 +364,9 @@ public:  	U32 mGeometryBytes; //used by volumes to track how many bytes of geometry data are in this node  	F32 mSurfaceArea; //used by volumes to track estimated surface area of geometry in this node -	F32 mBuilt;	 +	F32 mBuilt; -	LLPointer<LLVertexBuffer> mVertexBuffer;	 +	LLPointer<LLVertexBuffer> mVertexBuffer;  	U32 mBufferUsage;  	draw_map_t mDrawMap; @@ -389,13 +402,13 @@ public:  	LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE);  	BOOL remove(LLDrawable *drawablep, LLSpatialGroup *curp); -	LLDrawable* lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +	LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  									 BOOL pick_transparent,   									 S32* face_hit,                          // return the face hit -									 LLVector3* intersection = NULL,         // return the intersection point +									 LLVector4a* intersection = NULL,         // return the intersection point  									 LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point -									 LLVector3* normal = NULL,               // return the surface normal at the intersection point -									 LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point +									 LLVector4a* normal = NULL,               // return the surface normal at the intersection point +									 LLVector4a* tangent = NULL             // return the surface tangent at the intersection point  		); @@ -423,18 +436,18 @@ public:  	void renderDebug();  	void renderIntersectingBBoxes(LLCamera* camera);  	void restoreGL(); -	void resetVertexBuffers();	 +	void resetVertexBuffers();  	BOOL getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax);  public:  	LLSpatialBridge* mBridge; // NULL for non-LLSpatialBridge instances, otherwise, mBridge == this  							// use a pointer instead of making "isBridge" and "asBridge" virtual so it's safe -							// to call asBridge() from the destructor	 +							// to call asBridge() from the destructor  	BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane -	U32 mBufferUsage;	 -	const BOOL mRenderByGroup;	 +	U32 mBufferUsage; +	const BOOL mRenderByGroup;  	U32 mVertexDataMask;  	F32 mSlopRatio; //percentage distance must change before drawables receive LOD update (default is 0.25);  	BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering @@ -647,7 +660,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, BOOL batch_textures = FALSE); +	void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL no_materials = FALSE);  	void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);  }; diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index 8177a50cc2..dacea187c3 100755 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -418,7 +418,7 @@ void LLSpeakerMgr::update(BOOL resort_ok)  	{  		LLUUID speaker_id = speaker_it->first;  		LLSpeaker* speakerp = speaker_it->second; -		 +  		if (voice_channel_active && LLVoiceClient::getInstance()->getVoiceEnabled(speaker_id))  		{  			speakerp->mSpeechVolume = LLVoiceClient::getInstance()->getCurrentPower(speaker_id); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 3c67216688..de8d549055 100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -645,7 +645,7 @@ bool idle_startup()  				gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL();  			}  #endif - +              			if (gAudiop)  			{  #if LL_WINDOWS @@ -2293,7 +2293,7 @@ bool login_alert_status(const LLSD& notification, const LLSD& response)        //      break;          case 2:     // Teleport              // Restart the login process, starting at our home locaton -			LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME)); +	  LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME));              LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );              break;          default: diff --git a/indra/newview/lltextureatlas.cpp b/indra/newview/lltextureatlas.cpp index f8c1bca8ae..dbbe331954 100755 --- a/indra/newview/lltextureatlas.cpp +++ b/indra/newview/lltextureatlas.cpp @@ -71,7 +71,7 @@ LLTextureAtlas::~LLTextureAtlas()  //virtual   S8 LLTextureAtlas::getType() const  { -	return LLViewerTexture::ATLAS_TEXTURE ; +	return 0; //LLViewerTexture::ATLAS_TEXTURE ;  }  void LLTextureAtlas::getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yoffset) diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index f03cc22949..ee3b605cb0 100755 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -568,10 +568,13 @@ bool LLTextureCacheRemoteWorker::doWrite()  			idx = mCache->setHeaderCacheEntry(mID, entry, mImageSize, mDataSize); // create the new entry.  			if(idx >= 0)  			{ -				//write to the fast cache. +				// (almost always) write to the fast cache. +				if (mRawImage->getDataSize()) +				{  				llassert_always(mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel));  			}  		} +		}  		else  		{  			alreadyCached = mCache->updateEntry(idx, entry, mImageSize, mDataSize); // update the existing entry. @@ -1895,10 +1898,17 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d  bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel)  {  	//rescale image if needed +	if (raw.isNull() || !raw->getData()) +	{ +		llerrs << "Attempted to write NULL raw image to fastcache" << llendl; +		return false; +	} +  	S32 w, h, c;  	w = raw->getWidth();  	h = raw->getHeight();  	c = raw->getComponents(); +  	S32 i = 0 ;  	while(((w >> i) * (h >> i) * c) > TEXTURE_FAST_CACHE_ENTRY_SIZE - TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index 5a68c31a6d..c2a5cf9405 100755 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -24,7 +24,7 @@   * $/LicenseInfo$   */ -#ifndef LL_LLTEXTURECACHE_ +#ifndef LL_LLTEXTURECACHE_H  #define LL_LLTEXTURECACHE_H  #include "lldir.h" diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index a8038b7cf2..3276b2b9e1 100755 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -144,7 +144,7 @@ public:  	static void		onBtnCancel( void* userdata );  		   void		onBtnPipette( );  	//static void		onBtnRevert( void* userdata ); -	static void		onBtnWhite( void* userdata ); +	static void		onBtnBlank( void* userdata );  	static void		onBtnNone( void* userdata );  	static void		onBtnClear( void* userdata );  		   void		onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action); @@ -165,7 +165,6 @@ protected:  	LLUUID				mImageAssetID; // Currently selected texture  	LLUIImagePtr		mFallbackImage; // What to show if currently selected texture is null. -	LLUUID				mWhiteImageAssetID;  	LLUUID				mSpecialCurrentImageAssetID;  // Used when the asset id has no corresponding texture in the user's inventory.  	LLUUID				mOriginalImageAssetID; @@ -187,7 +186,7 @@ protected:  	F32					mContextConeOpacity;  	LLSaveFolderState	mSavedFolderState;  	BOOL				mSelectedItemPinned; -	 +  	LLRadioGroup*		mModeSelector;  	LLScrollListCtrl*	mLocalScrollCtrl; @@ -209,7 +208,6 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(  	mOwner( owner ),  	mImageAssetID( owner->getImageAssetID() ),  	mFallbackImage( fallback_image ), -	mWhiteImageAssetID( gSavedSettings.getString( "UIImgWhiteUUID" ) ),  	mOriginalImageAssetID(owner->getImageAssetID()),  	mLabel(label),  	mTentativeLabel(NULL), @@ -426,7 +424,7 @@ BOOL LLFloaterTexturePicker::postBuild()  	childSetAction("Default",LLFloaterTexturePicker::onBtnSetToDefault,this);  	childSetAction("None", LLFloaterTexturePicker::onBtnNone,this); -	childSetAction("Blank", LLFloaterTexturePicker::onBtnWhite,this); +	childSetAction("Blank", LLFloaterTexturePicker::onBtnBlank,this);  	childSetCommitCallback("show_folders_check", onShowFolders, this); @@ -581,7 +579,7 @@ void LLFloaterTexturePicker::draw()  		}  		getChildView("Default")->setEnabled(mImageAssetID != mOwner->getDefaultImageAssetID()); -		getChildView("Blank")->setEnabled(mImageAssetID != mWhiteImageAssetID ); +		getChildView("Blank")->setEnabled(mImageAssetID != mOwner->getBlankImageAssetID());  		getChildView("None")->setEnabled(mOwner->getAllowNoTexture() && !mImageAssetID.isNull() );  		LLFloater::draw(); @@ -721,11 +719,11 @@ void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)  }  // static -void LLFloaterTexturePicker::onBtnWhite(void* userdata) +void LLFloaterTexturePicker::onBtnBlank(void* userdata)  {  	LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;  	self->setCanApply(true, true); -	self->setImageID( self->mWhiteImageAssetID ); +	self->setImageID( self->mOwner->getBlankImageAssetID() );  	self->commitIfImmediateSet();  } @@ -1042,6 +1040,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)  	mDragCallback(NULL),  	mDropCallback(NULL),  	mOnCancelCallback(NULL), +	mOnCloseCallback(NULL),  	mOnSelectCallback(NULL),  	mBorderColor( p.border_color() ),  	mAllowNoTexture( FALSE ), @@ -1056,6 +1055,12 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)  	mDefaultImageName(p.default_image_name),  	mFallbackImage(p.fallback_image)  { + +	// Default of defaults is white image for diff tex +	// +	LLUUID whiteImage( gSavedSettings.getString( "UIImgWhiteUUID" ) ); +	setBlankImageAssetID( whiteImage ); +  	setAllowNoTexture(p.allow_no_texture);  	setCanApplyImmediately(p.can_apply_immediately);  	mCommitOnSelection = !p.no_commit_on_selection; @@ -1292,6 +1297,10 @@ void LLTextureCtrl::onFloaterClose()  	if (floaterp)  	{ +		if (mOnCloseCallback) +		{ +			mOnCloseCallback(this,LLSD()); +		}  		floaterp->setOwner(NULL);  	} @@ -1311,7 +1320,7 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)  		// (i.e. op == TEXTURE_SELECT) or texture changes via DnD.  		else if (mCommitOnSelection || op == TEXTURE_SELECT)  			mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? - +			  		if(floaterp->isDirty() || id.notNull()) // mModelView->setDirty does not work.  		{  			setTentative( FALSE ); diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 599d9c70c5..ad79042ef1 100755 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -126,6 +126,7 @@ public:  	// LLTextureCtrl interface  	void			showPicker(BOOL take_focus); +	bool			isPickerShown() { return !mFloaterHandle.isDead(); }  	void			setLabel(const std::string& label);  	void			setLabelWidth(S32 label_width) {mLabelWidth =label_width;}	  	const std::string&	getLabel() const							{ return mLabel; } @@ -145,6 +146,9 @@ public:  	const std::string&	getDefaultImageName() const					{ return mDefaultImageName; } +	void			setBlankImageAssetID( const LLUUID& id )	{ mBlankImageAssetID = id; } +	const LLUUID&	getBlankImageAssetID() const { return mBlankImageAssetID; } +  	void			setCaption(const std::string& caption);  	void			setCanApplyImmediately(BOOL b); @@ -174,7 +178,7 @@ public:  	void setDropCallback(drag_n_drop_callback cb)	{ mDropCallback = cb; }  	void setOnCancelCallback(commit_callback_t cb)	{ mOnCancelCallback = cb; } -	 +	void setOnCloseCallback(commit_callback_t cb)	{ mOnCloseCallback = cb; }  	void setOnSelectCallback(commit_callback_t cb)	{ mOnSelectCallback = cb; }  	/* @@ -195,12 +199,14 @@ private:  	drag_n_drop_callback	 	mDropCallback;  	commit_callback_t		 	mOnCancelCallback;  	commit_callback_t		 	mOnSelectCallback; +	commit_callback_t		 	mOnCloseCallback;  	texture_selected_callback	mOnTextureSelectedCallback;  	LLPointer<LLViewerFetchedTexture> mTexturep;  	LLUIColor				 	mBorderColor;  	LLUUID					 	mImageItemID;  	LLUUID					 	mImageAssetID;  	LLUUID					 	mDefaultImageAssetID; +	LLUUID					 	mBlankImageAssetID;  	LLUIImagePtr				mFallbackImage;  	std::string					mDefaultImageName;  	LLHandle<LLFloater>			mFloaterHandle; diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 766b66efa0..72ed3d4485 100755 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -512,13 +512,13 @@ void LLGLTexMemBar::draw()  	LLUnit<S32, LLUnits::Mibibytes> total_mem = LLViewerTexture::sTotalTextureMemory;  	LLUnit<S32, LLUnits::Mibibytes> max_total_mem = LLViewerTexture::sMaxTotalTextureMem;  	F32 discard_bias = LLViewerTexture::sDesiredDiscardBias; -	F32 cache_usage = (F32)LLTrace::Mibibytes(LLAppViewer::getTextureCache()->getUsage()).value() ; -	F32 cache_max_usage = (F32)LLTrace::Mibibytes(LLAppViewer::getTextureCache()->getMaxUsage()).value() ; +	F32 cache_usage = (F32)LLUnit<F32, LLUnits::Mibibytes>(LLAppViewer::getTextureCache()->getUsage()).value() ; +	F32 cache_max_usage = (F32)LLUnit<F32, LLUnits::Mibibytes>(LLAppViewer::getTextureCache()->getMaxUsage()).value() ;  	S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();  	S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);  	LLUnit<F32, LLUnits::Bytes> total_texture_downloaded = gTotalTextureData;  	LLUnit<F32, LLUnits::Bytes> total_object_downloaded = gTotalObjectData; -	U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests() ; +	U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests();  	U32 total_active_cached_objects = LLWorld::getInstance()->getNumOfActiveCachedObjects();  	U32 total_objects = gObjectList.getNumObjects(); diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index dc4c9fe4ad..6ab2aefc34 100755 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp @@ -153,29 +153,29 @@ namespace LLViewerAssetStatsFF  		};  		if (at < 0 || at >= LLViewerAssetType::AT_COUNT) -		{ +{  			return EVACOtherGet; -		} +}  		EViewerAssetCategories ret(asset_to_bin_map[at]);  		if (EVACTextureTempHTTPGet == ret)  		{  			// Indexed with [is_temp][with_http]  			static const EViewerAssetCategories texture_bin_map[2][2] = -			{ -				{ +{ +	{  					EVACTextureNonTempUDPGet,  						EVACTextureNonTempHTTPGet,  				},  				{  					EVACTextureTempUDPGet,  						EVACTextureTempHTTPGet, -					} +	}  			}; - +	  			ret = texture_bin_map[is_temp][with_http];  		}  		return ret; -	} +}  	static LLTrace::CountStatHandle<> sEnqueueAssetRequestsTempTextureHTTP   ("enqueuedassetrequeststemptexturehttp",   																	"Number of temporary texture asset http requests enqueued"), @@ -204,7 +204,7 @@ namespace LLViewerAssetStatsFF  		&sEnqueuedAssetRequestsGestureUdp,  		&sEnqueuedAssetRequestsOther              	}; - +	  	static LLTrace::CountStatHandle<> sDequeueAssetRequestsTempTextureHTTP   ("dequeuedassetrequeststemptexturehttp",   																	"Number of temporary texture asset http requests dequeued"),  							sDequeueAssetRequestsTempTextureUDP    ("dequeuedassetrequeststemptextureudp",  @@ -233,7 +233,7 @@ namespace LLViewerAssetStatsFF  		&sDequeuedAssetRequestsOther              	}; -	static LLTrace::EventStatHandle<LLTrace::Seconds>	sResponseAssetRequestsTempTextureHTTP   ("assetresponsetimestemptexturehttp", +	static LLTrace::EventStatHandle<LLUnit<F64, LLUnits::Seconds> >	sResponseAssetRequestsTempTextureHTTP   ("assetresponsetimestemptexturehttp",  																							"Time spent responding to temporary texture asset http requests"),  													sResponseAssetRequestsTempTextureUDP    ("assetresponsetimestemptextureudp",   																							"Time spent responding to temporary texture asset udp requests"), @@ -250,7 +250,7 @@ namespace LLViewerAssetStatsFF  													sResponsedAssetRequestsOther            ("assetresponsetimesother",   																							"Time spent responding to other asset requests"); -	static LLTrace::EventStatHandle<LLTrace::Seconds>* sResponse[EVACCount] = { +	static LLTrace::EventStatHandle<LLUnit<F64, LLUnits::Seconds> >* sResponse[EVACCount] = {  		&sResponseAssetRequestsTempTextureHTTP,     		&sResponseAssetRequestsTempTextureUDP,    		&sResponseAssetRequestsNonTempTextureHTTP, @@ -314,9 +314,9 @@ void LLViewerAssetStats::handleStop()  }  void LLViewerAssetStats::handleReset() -{ +	{  	reset(); -} +	}  void LLViewerAssetStats::reset() @@ -365,7 +365,7 @@ void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)  	using namespace LLViewerAssetStatsFF;  	stats.regions.setProvided(); - +	  	for (PerRegionRecordingContainer::iterator it = mRegionRecordings.begin(), end_it = mRegionRecordings.end();  		it != end_it;  		++it) @@ -383,50 +383,50 @@ void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)  									.resp_min(rec.getMin(*sResponse[EVACTextureTempHTTPGet]).value())  									.resp_max(rec.getMax(*sResponse[EVACTextureTempHTTPGet]).value())  									.resp_mean(rec.getMean(*sResponse[EVACTextureTempHTTPGet]).value()); -		} +}  		if (!compact_output  			|| rec.getSum(*sEnqueued[EVACTextureTempUDPGet])   			|| rec.getSum(*sDequeued[EVACTextureTempUDPGet])  			|| rec.getSum(*sResponse[EVACTextureTempUDPGet]).value()) -		{ +{  			r.get_texture_temp_udp	.enqueued((S32)rec.getSum(*sEnqueued[EVACTextureTempUDPGet]))  									.dequeued((S32)rec.getSum(*sDequeued[EVACTextureTempUDPGet]))  									.resp_count((S32)rec.getSum(*sResponse[EVACTextureTempUDPGet]).value())  									.resp_min(rec.getMin(*sResponse[EVACTextureTempUDPGet]).value())  									.resp_max(rec.getMax(*sResponse[EVACTextureTempUDPGet]).value())  									.resp_mean(rec.getMean(*sResponse[EVACTextureTempUDPGet]).value()); -		} +}  		if (!compact_output  			|| rec.getSum(*sEnqueued[EVACTextureNonTempHTTPGet])   			|| rec.getSum(*sDequeued[EVACTextureNonTempHTTPGet])  			|| rec.getSum(*sResponse[EVACTextureNonTempHTTPGet]).value()) -		{ +{  			r.get_texture_non_temp_http	.enqueued((S32)rec.getSum(*sEnqueued[EVACTextureNonTempHTTPGet]))  										.dequeued((S32)rec.getSum(*sDequeued[EVACTextureNonTempHTTPGet]))  										.resp_count((S32)rec.getSum(*sResponse[EVACTextureNonTempHTTPGet]).value())  										.resp_min(rec.getMin(*sResponse[EVACTextureNonTempHTTPGet]).value())  										.resp_max(rec.getMax(*sResponse[EVACTextureNonTempHTTPGet]).value())  										.resp_mean(rec.getMean(*sResponse[EVACTextureNonTempHTTPGet]).value()); -		} +}  		if (!compact_output  			|| rec.getSum(*sEnqueued[EVACTextureNonTempUDPGet])   			|| rec.getSum(*sDequeued[EVACTextureNonTempUDPGet])  			|| rec.getSum(*sResponse[EVACTextureNonTempUDPGet]).value()) -		{ +{  			r.get_texture_non_temp_udp	.enqueued((S32)rec.getSum(*sEnqueued[EVACTextureNonTempUDPGet]))  										.dequeued((S32)rec.getSum(*sDequeued[EVACTextureNonTempUDPGet]))  										.resp_count((S32)rec.getSum(*sResponse[EVACTextureNonTempUDPGet]).value())  										.resp_min(rec.getMin(*sResponse[EVACTextureNonTempUDPGet]).value())  										.resp_max(rec.getMax(*sResponse[EVACTextureNonTempUDPGet]).value())  										.resp_mean(rec.getMean(*sResponse[EVACTextureNonTempUDPGet]).value()); -		} +}  		if (!compact_output  			|| rec.getSum(*sEnqueued[EVACWearableUDPGet])   			|| rec.getSum(*sDequeued[EVACWearableUDPGet])  			|| rec.getSum(*sResponse[EVACWearableUDPGet]).value()) -		{ +{  			r.get_wearable_udp	.enqueued((S32)rec.getSum(*sEnqueued[EVACWearableUDPGet]))  								.dequeued((S32)rec.getSum(*sDequeued[EVACWearableUDPGet]))  								.resp_count((S32)rec.getSum(*sResponse[EVACWearableUDPGet]).value()) @@ -460,12 +460,12 @@ void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)  								.resp_max(rec.getMax(*sResponse[EVACGestureUDPGet]).value())  								.resp_mean(rec.getMean(*sResponse[EVACGestureUDPGet]).value());  		} - +			  		if (!compact_output  			|| rec.getSum(*sEnqueued[EVACOtherGet])   			|| rec.getSum(*sDequeued[EVACOtherGet])  			|| rec.getSum(*sResponse[EVACOtherGet]).value()) -		{ +			{  			r.get_other	.enqueued((S32)rec.getSum(*sEnqueued[EVACOtherGet]))  						.dequeued((S32)rec.getSum(*sDequeued[EVACOtherGet]))  						.resp_count((S32)rec.getSum(*sResponse[EVACOtherGet]).value()) @@ -493,19 +493,19 @@ void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)  }  LLSD LLViewerAssetStats::asLLSD(bool compact_output) -{ +		{  	LLParamSDParser parser;  	LLSD sd;  	AssetStats stats;  	getStats(stats, compact_output);  	LLInitParam::predicate_rule_t rule = LLInitParam::default_parse_rules();  	if (!compact_output) -	{ +		{  		rule.allow(LLInitParam::EMPTY); -	} +		}  	parser.writeSD(sd, stats, rule);  	return sd; -} +	}  // ------------------------------------------------------  // Global free-function definitions (LLViewerAssetStatsFF namespace) @@ -539,7 +539,7 @@ void record_response(LLViewerAssetType::EType at, bool with_http, bool is_temp,  {  	const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); -	record(*sResponse[int(eac)], LLTrace::Microseconds(duration)); +	record(*sResponse[int(eac)], LLUnit<F64, LLUnits::Microseconds>(duration));  }  void init() @@ -570,7 +570,7 @@ LLViewerAssetStats::AssetRequestType::AssetRequestType()  	resp_max("resp_max"),  	resp_mean("resp_mean")  {} - +	  LLViewerAssetStats::FPSStats::FPSStats()   :	count("count"),  	min("min"), diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h index e03b7c53a6..2126d569f8 100755 --- a/indra/newview/llviewerassetstats.h +++ b/indra/newview/llviewerassetstats.h @@ -105,7 +105,7 @@ public:  	};  	struct FPSStats : public LLInitParam::Block<FPSStats> -	{ +			{  		Mandatory<S32>	count;  		Mandatory<F64>	min,  						max, @@ -114,7 +114,7 @@ public:  	};  	struct RegionStats : public LLInitParam::Block<RegionStats> -	{ +				{  		Optional<AssetRequestType>	get_texture_temp_http,  									get_texture_temp_udp,  									get_texture_non_temp_http, @@ -130,7 +130,7 @@ public:  		RegionStats();  	}; - +		  	struct AssetStats : public LLInitParam::Block<AssetStats>  	{  		Multiple<RegionStats>	regions; diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index ffdaa21c84..c1518833bd 100755 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -502,11 +502,11 @@ void audio_update_wind(bool force_update)  		// standing still.  		static LLUICachedControl<F32> wind_level("AudioLevelWind", 0.5f);  		LLVector3 scaled_wind_vec = gWindVec * wind_level; -         +  		// Mix in the avatar's motion, subtract because when you walk north,  		// the apparent wind moves south.  		LLVector3 final_wind_vec = scaled_wind_vec - gAgent.getVelocity(); -         +  		// rotate the wind vector to be listener (agent) relative  		gRelativeWindVec = gAgent.getFrameAgent().rotateToLocal( final_wind_vec ); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index a62f73deef..afbb59e723 100755 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -401,6 +401,25 @@ static bool handleRenderDeferredChanged(const LLSD& newvalue)  	return true;  } +// This looks a great deal like handleRenderDeferredChanged because +// Advanced Lighting (Materials) implies bumps and shiny so disabling +// bumps should further disable that feature. +// +static bool handleRenderBumpChanged(const LLSD& newval) +{ +	LLRenderTarget::sUseFBO = newval.asBoolean(); +	if (gPipeline.isInit()) +	{ +		gPipeline.updateRenderBump(); +		gPipeline.updateRenderDeferred(); +		gPipeline.releaseGLBuffers(); +		gPipeline.createGLBuffers(); +		gPipeline.resetVertexBuffers(); +		LLViewerShaderMgr::instance()->setShaders(); +	} +	return true; +} +  static bool handleRenderUseImpostorsChanged(const LLSD& newvalue)  {  	LLVOAvatar::sUseImpostors = newvalue.asBoolean(); @@ -629,7 +648,7 @@ void settings_setup_listeners()  	gSavedSettings.getControl("RenderDebugTextureBind")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));  	gSavedSettings.getControl("RenderAutoMaskAlphaDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));  	gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); -	gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); +	gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleRenderBumpChanged, _2));  	gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));  	gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));  	gSavedSettings.getControl("RenderUseImpostors")->getSignal()->connect(boost::bind(&handleRenderUseImpostorsChanged, _2)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index bd85056d70..1de8493749 100755 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -96,6 +96,7 @@ BOOL gDepthDirty = FALSE;  BOOL gResizeScreenTexture = FALSE;  BOOL gWindowResized = FALSE;  BOOL gSnapshot = FALSE; +BOOL gShaderProfileFrame = FALSE;  U32 gRecentFrameCount = 0; // number of 'recent' frames  LLFrameTimer gRecentFPSTime; @@ -112,7 +113,8 @@ void render_disconnected_background();  void display_startup()  { -	if (   !gViewerWindow->getActive() +	if (   !gViewerWindow +		|| !gViewerWindow->getActive()  		|| !gViewerWindow->getWindow()->getVisible()   		|| gViewerWindow->getWindow()->getMinimized() )  	{ @@ -123,7 +125,14 @@ void display_startup()  	// Update images?  	//gImageList.updateImages(0.01f); +	 +	// Written as branch to appease GCC which doesn't like different +	// pointer types across ternary ops +	// +	if (!LLViewerFetchedTexture::sWhiteImagep.isNull()) +	{  	LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName(); +	}  	LLGLSDefault gls_default; @@ -145,10 +154,12 @@ void display_startup()  	LLGLSUIDefault gls_ui;  	gPipeline.disableLights(); +	if (gViewerWindow)  	gViewerWindow->setup2DRender();  	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);  	gGL.color4f(1,1,1,1); +	if (gViewerWindow)  	gViewerWindow->draw();  	gGL.flush(); @@ -157,7 +168,9 @@ void display_startup()  	LLGLState::checkStates();  	LLGLState::checkTextureChannels(); +	if (gViewerWindow && gViewerWindow->getWindow())  	gViewerWindow->getWindow()->swapBuffers(); +  	glClear(GL_DEPTH_BUFFER_BIT);  } @@ -338,6 +351,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		return;  	} + +	if (gShaderProfileFrame) +	{ +		LLGLSLShader::initProfile(); +	} +  	//LLGLState::verify(FALSE);  	///////////////////////////////////////////////// @@ -1026,6 +1045,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  	LLAppViewer::instance()->pingMainloopTimeout("Display:Done");  	gShiftFrame = false; + +	if (gShaderProfileFrame) +	{ +		gShaderProfileFrame = FALSE; +		LLGLSLShader::finishProfile(); +	}  }  void render_hud_attachments() @@ -1045,6 +1070,7 @@ void render_hud_attachments()  	if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())  	{ +		LLPipeline::sRenderingHUDs = TRUE;  		LLCamera hud_cam = *LLViewerCamera::getInstance();  		hud_cam.setOrigin(-1.f,0,0);  		hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1)); @@ -1089,10 +1115,13 @@ void render_hud_attachments()  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE);  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME);  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA); +		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA_MASK); +		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK);  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT);  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA);  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK);  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_BUMP); +		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_MATERIAL);  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT);  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK);  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY); @@ -1117,6 +1146,7 @@ void render_hud_attachments()  			gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);  		}  		LLPipeline::sUseOcclusion = use_occlusion; +		LLPipeline::sRenderingHUDs = FALSE;  	}  	gGL.matrixMode(LLRender::MM_PROJECTION);  	gGL.popMatrix(); diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 61b1b8d846..ab19a12014 100755 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -256,7 +256,7 @@ class AddFavoriteLandmarkCallback : public LLInventoryCallback  public:  	AddFavoriteLandmarkCallback() : mTargetLandmarkId(LLUUID::null) {}  	void setTargetLandmarkId(const LLUUID& target_uuid) { mTargetLandmarkId = target_uuid; } - +	  private:  	void fire(const LLUUID& inv_item); @@ -283,13 +283,13 @@ public:  	// virtual  	void fire(const LLUUID& item_id) -	{ +{  		mFireFunc(item_id);  	}  	// virtual  	~LLBoostFuncInventoryCallback() -	{ +{  		mDestroyFunc();  	} diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index bb3f0fe932..fb199ba879 100755 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -124,7 +124,6 @@  #include "llwindow.h"  #include "llpathfindingmanager.h"  #include "boost/unordered_map.hpp" -#include "llscenemonitor.h"  using namespace LLAvatarAppearanceDefines; @@ -148,6 +147,8 @@ void handle_test_load_url(void*);  //extern BOOL gDebugAvatarRotation;  extern BOOL gDebugClicks;  extern BOOL gDebugWindowProc; +extern BOOL gShaderProfileFrame; +  //extern BOOL gDebugTextEditorTips;  //extern BOOL gDebugSelectMgr; @@ -292,6 +293,7 @@ void request_friendship(const LLUUID& agent_id);  // Tools menu  void handle_selected_texture_info(void*); +void handle_selected_material_info();  void handle_dump_followcam(void*);  void handle_viewer_enable_message_log(void*); @@ -525,10 +527,7 @@ class LLAdvancedToggleConsole : public view_listener_t  		{  			toggle_visibility( (void*)gSceneView);  		} -		else if ("scene monitor" == console_type) -		{ -			toggle_visibility( (void*)gSceneMonitorView); -		} +  #if MEM_TRACK_MEM  		else if ("memory view" == console_type)  		{ @@ -556,9 +555,9 @@ class LLAdvancedCheckConsole : public view_listener_t  		{  			new_value = LLFloaterReg::instanceVisible("fast_timers");  		} -		else if ("scene monitor" == console_type) +		else if ("scene view" == console_type)  		{ -			new_value = get_visibility( (void*) gSceneMonitorView); +			new_value = get_visibility( (void*) gSceneView);  		}  #if MEM_TRACK_MEM  		else if ("memory view" == console_type) @@ -1193,28 +1192,6 @@ class LLAdvancedCheckWireframe : public view_listener_t  	}  }; -////////////////////// -// TEXTURE ATLAS // -////////////////////// - -class LLAdvancedToggleTextureAtlas : public view_listener_t -{ -	bool handleEvent(const LLSD& userdata) -	{ -		LLViewerTexture::sUseTextureAtlas = !LLViewerTexture::sUseTextureAtlas; -		gSavedSettings.setBOOL("EnableTextureAtlas", LLViewerTexture::sUseTextureAtlas) ; -		return true; -	} -}; - -class LLAdvancedCheckTextureAtlas : public view_listener_t -{ -	bool handleEvent(const LLSD& userdata) -	{ -		bool new_value = LLViewerTexture::sUseTextureAtlas; // <-- make this using LLCacheControl -		return new_value; -	} -};  //////////////////////////  // DUMP SCRIPTED CAMERA // @@ -3967,24 +3944,24 @@ class LLViewToggleUI : public view_listener_t  	{  		if(gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK)  		{ -		LLNotification::Params params("ConfirmHideUI"); -		params.functor.function(boost::bind(&LLViewToggleUI::confirm, this, _1, _2)); -		LLSD substitutions; +			LLNotification::Params params("ConfirmHideUI"); +			params.functor.function(boost::bind(&LLViewToggleUI::confirm, this, _1, _2)); +			LLSD substitutions;  #if LL_DARWIN -		substitutions["SHORTCUT"] = "Cmd+Shift+U"; +			substitutions["SHORTCUT"] = "Cmd+Shift+U";  #else -		substitutions["SHORTCUT"] = "Ctrl+Shift+U"; +			substitutions["SHORTCUT"] = "Ctrl+Shift+U";  #endif -		params.substitutions = substitutions; +			params.substitutions = substitutions;  			if (!gSavedSettings.getBOOL("HideUIControls")) -		{ -			// hiding, so show notification -			LLNotifications::instance().add(params); -		} -		else -		{ -			LLNotifications::instance().forceResponse(params, 0); -		} +			{ +				// hiding, so show notification +				LLNotifications::instance().add(params); +			} +			else +			{ +				LLNotifications::instance().forceResponse(params, 0); +			}  		}  		return true;  	} @@ -4031,6 +4008,72 @@ void handle_duplicate_in_place(void*)  	LLSelectMgr::getInstance()->selectDuplicate(offset, TRUE);  } +/* dead code 30-apr-2008 +void handle_deed_object_to_group(void*) +{ +	LLUUID group_id; +	 +	LLSelectMgr::getInstance()->selectGetGroup(group_id); +	LLSelectMgr::getInstance()->sendOwner(LLUUID::null, group_id, FALSE); +	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_RELEASE_COUNT); +} + +BOOL enable_deed_object_to_group(void*) +{ +	if(LLSelectMgr::getInstance()->getSelection()->isEmpty()) return FALSE; +	LLPermissions perm; +	LLUUID group_id; + +	if (LLSelectMgr::getInstance()->selectGetGroup(group_id) && +		gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && +		LLSelectMgr::getInstance()->selectGetPermissions(perm) && +		perm.deedToGroup(gAgent.getID(), group_id)) +	{ +		return TRUE; +	} +	return FALSE; +} + +*/ + + +/* + * No longer able to support viewer side manipulations in this way + * +void god_force_inv_owner_permissive(LLViewerObject* object, +									LLInventoryObject::object_list_t* inventory, +									S32 serial_num, +									void*) +{ +	typedef std::vector<LLPointer<LLViewerInventoryItem> > item_array_t; +	item_array_t items; + +	LLInventoryObject::object_list_t::const_iterator inv_it = inventory->begin(); +	LLInventoryObject::object_list_t::const_iterator inv_end = inventory->end(); +	for ( ; inv_it != inv_end; ++inv_it) +	{ +		if(((*inv_it)->getType() != LLAssetType::AT_CATEGORY)) +		{ +			LLInventoryObject* obj = *inv_it; +			LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem((LLViewerInventoryItem*)obj); +			LLPermissions perm(new_item->getPermissions()); +			perm.setMaskBase(PERM_ALL); +			perm.setMaskOwner(PERM_ALL); +			new_item->setPermissions(perm); +			items.push_back(new_item); +		} +	} +	item_array_t::iterator end = items.end(); +	item_array_t::iterator it; +	for(it = items.begin(); it != end; ++it) +	{ +		// since we have the inventory item in the callback, it should not +		// invalidate iteration through the selection manager. +		object->updateInventory((*it), TASK_INVENTORY_ITEM_KEY, false); +	} +} +*/ +  void handle_object_owner_permissive(void*)  {  	// only send this if they're a god. @@ -6401,7 +6444,7 @@ class LLAttachmentDetachFromPoint : public view_listener_t  				LLViewerObject *attached_object = (*iter);  				ids_to_remove.push_back(attached_object->getAttachmentItemID());  			} -		} +			}  		if (!ids_to_remove.empty())  		{  			LLAppearanceMgr::instance().removeItemsFromAvatar(ids_to_remove); @@ -6858,6 +6901,47 @@ void handle_selected_texture_info(void*)  	}  } +void handle_selected_material_info() +{ +	for (LLObjectSelection::valid_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_begin(); +		iter != LLSelectMgr::getInstance()->getSelection()->valid_end(); iter++) +	{ +		LLSelectNode* node = *iter; +		 +		std::string msg; +		msg.assign("Material info for: \n"); +		msg.append(node->mName); +		 +		U8 te_count = node->getObject()->getNumTEs(); +		// map from material ID to list of faces using it +		typedef std::map<LLMaterialID, std::vector<U8> > map_t; +		map_t faces_per_material; +		for (U8 i = 0; i < te_count; i++) +		{ +			if (!node->isTESelected(i)) continue; +	 +			const LLMaterialID& material_id = node->getObject()->getTE(i)->getMaterialID(); +			faces_per_material[material_id].push_back(i); +		} +		// Per-material, dump which faces are using it. +		map_t::iterator it; +		for (it = faces_per_material.begin(); it != faces_per_material.end(); ++it) +		{ +			const LLMaterialID& material_id = it->first; +			msg += llformat("%s on face ", material_id.asString().c_str()); +			for (U8 i = 0; i < it->second.size(); ++i) +			{ +				msg.append( llformat("%d ", (S32)(it->second[i]))); +			} +			msg.append("\n"); +		} + +		LLSD args; +		args["MESSAGE"] = msg; +		LLNotificationsUtil::add("SystemMessage", args); +	} +} +  void handle_test_male(void*)  {  	LLAppearanceMgr::instance().wearOutfitByName("Male Shape & Outfit"); @@ -6960,6 +7044,15 @@ class LLAdvancedClickRenderShadowOption: public view_listener_t  	}  }; +class LLAdvancedClickRenderProfile: public view_listener_t +{ +	bool handleEvent(const LLSD& userdata) +	{ +		gShaderProfileFrame = TRUE; +		return true; +	} +}; +  void menu_toggle_attached_lights(void* user_data)  {  	LLPipeline::sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights"); @@ -7549,23 +7642,6 @@ void handle_web_browser_test(const LLSD& param)  	LLWeb::loadURLInternal(url);  } -bool callback_clear_cache_immediately(const LLSD& notification, const LLSD& response) -{ -	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); -	if ( option == 0 ) // YES -	{ -		//clear cache -		LLAppViewer::instance()->purgeCacheImmediate(); -	} - -	return false; -} - -void handle_cache_clear_immediately() -{ -	LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache_immediately); -} -  void handle_web_content_test(const LLSD& param)  {  	std::string url = param.asString(); @@ -8295,10 +8371,10 @@ void initialize_menus()  	view_listener_t::addMenu(new LLViewStatusAway(), "View.Status.CheckAway");  	view_listener_t::addMenu(new LLViewStatusDoNotDisturb(), "View.Status.CheckDoNotDisturb");  	view_listener_t::addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments"); - +	  	// Me > Movement  	view_listener_t::addMenu(new LLAdvancedAgentFlyingInfo(), "Agent.getFlying"); -	 +  	// Communicate > Voice morphing > Subscribe...  	commit.add("Communicate.VoiceMorphing.Subscribe", boost::bind(&handle_voice_morphing_subscribe));  	LLVivoxVoiceClient * voice_clientp = LLVivoxVoiceClient::getInstance(); @@ -8306,7 +8382,7 @@ void initialize_menus()  		, boost::bind(&LLVivoxVoiceClient::onCheckVoiceEffect, voice_clientp, "NoVoiceMorphing"));  	commit.add("Communicate.VoiceMorphing.NoVoiceMorphing.Click"  		, boost::bind(&LLVivoxVoiceClient::onClickVoiceEffect, voice_clientp, "NoVoiceMorphing")); -	 +  	// World menu  	view_listener_t::addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun");  	view_listener_t::addMenu(new LLWorldCreateLandmark(), "World.CreateLandmark"); @@ -8397,11 +8473,10 @@ void initialize_menus()  	view_listener_t::addMenu(new LLAdvancedToggleInfoDisplay(), "Advanced.ToggleInfoDisplay");  	view_listener_t::addMenu(new LLAdvancedCheckInfoDisplay(), "Advanced.CheckInfoDisplay");  	view_listener_t::addMenu(new LLAdvancedSelectedTextureInfo(), "Advanced.SelectedTextureInfo"); +	commit.add("Advanced.SelectedMaterialInfo", boost::bind(&handle_selected_material_info));  	view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe");  	view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe");  	// Develop > Render -	view_listener_t::addMenu(new LLAdvancedToggleTextureAtlas(), "Advanced.ToggleTextureAtlas"); -	view_listener_t::addMenu(new LLAdvancedCheckTextureAtlas(), "Advanced.CheckTextureAtlas");  	view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion");  	view_listener_t::addMenu(new LLAdvancedEnableRenderFBO(), "Advanced.EnableRenderFBO");  	view_listener_t::addMenu(new LLAdvancedEnableRenderDeferred(), "Advanced.EnableRenderDeferred"); @@ -8415,7 +8490,7 @@ void initialize_menus()  	view_listener_t::addMenu(new LLAdvancedHandleAttachedLightParticles(), "Advanced.HandleAttachedLightParticles");  	view_listener_t::addMenu(new LLAdvancedCheckRenderShadowOption(), "Advanced.CheckRenderShadowOption");  	view_listener_t::addMenu(new LLAdvancedClickRenderShadowOption(), "Advanced.ClickRenderShadowOption"); -	 +	view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile");  	#ifdef TOGGLE_HACKED_GODLIKE_VIEWER  	view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode"); @@ -8532,8 +8607,6 @@ void initialize_menus()  	//Develop (Texture Fetch Debug Console)  	view_listener_t::addMenu(new LLDevelopTextureFetchDebugger(), "Develop.SetTexFetchDebugger"); -	//Develop (clear cache immediately) -	commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) );  	// Admin >Object  	view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy"); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 0309acdad2..c33efd4255 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1181,7 +1181,7 @@ bool check_offer_throttle(const std::string& from_name, bool check_only)  		}  	}  } - +   // Return "true" if we have a preview method for that asset type, "false" otherwise  bool check_asset_previewable(const LLAssetType::EType asset_type)  { @@ -1529,7 +1529,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&  	from_string = chatHistory_string = mFromName;  	LLNotificationFormPtr modified_form(notification_ptr ? new LLNotificationForm(*notification_ptr->getForm()) : new LLNotificationForm()); -	 +  	switch(button)  	{  	case IOR_SHOW: @@ -1627,7 +1627,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&  			{  				opener = discard_agent_offer;  			} -			 +  			if (modified_form != NULL)  			{  				modified_form->setElementEnabled("Show", false); @@ -2376,7 +2376,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  	LLNotification::Params params;  	switch(dialog) -	{ +	{   	case IM_CONSOLE_AND_CHAT_HISTORY:  		args["MESSAGE"] = message;  		payload["from_id"] = from_id; @@ -3075,11 +3075,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  				}  				else  				{ -					LLNotification::Params params("TeleportOffered"); -					params.substitutions = args; -					params.payload = payload; -					LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false); -				} +			    LLNotification::Params params("TeleportOffered"); +			    params.substitutions = args; +			    params.payload = payload; +			    LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false); +			}  			}  		} @@ -3170,10 +3170,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  			}  			else  			{ -				// do not show a message box, because you're about to be -				// teleported. -				LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0); -			} +			// do not show a message box, because you're about to be +			// teleported. +			LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0); +		}  		}  		break; @@ -4340,7 +4340,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)  		msg_number += 1;  		if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT)  		{ -			//LL_INFOS("Messaging") << " head rot " << head_rotation << LL_ENDL; +			//LL_INFOS("Messaging") << "head rot " << head_rotation << LL_ENDL;  			LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", head_rot_chg " << head_rot_chg << LL_ENDL;  		}  		if (cam_rot_chg.magVec() > ROTATION_THRESHOLD)  @@ -4359,7 +4359,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)  		{  			LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", dcf = " << control_flag_change << LL_ENDL;  		} -		*/ +*/  		duplicate_count = 0;  	} @@ -5750,7 +5750,7 @@ bool handle_teleport_access_blocked(LLSD& llsdBlock)  			maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback);  			returnValue = true;  		} -	} +		}  	if ((maturityLevelNotification == NULL) || maturityLevelNotification->isIgnored())  	{ @@ -5916,8 +5916,8 @@ void process_alert_core(const std::string& message, BOOL modal)  		std::string alert_name(message.substr(ALERT_PREFIX.length()));  		if (!handle_special_alerts(alert_name))  		{ -			LLNotificationsUtil::add(alert_name); -		} +		LLNotificationsUtil::add(alert_name); +	}  	}  	else if (message.find(NOTIFY_PREFIX) == 0)  	{ @@ -6370,7 +6370,7 @@ void process_script_question(LLMessageSystem *msg, void **user_data)  			args["DOWNLOADURL"] = LLTrans::getString("ViewerDownloadURL");  			LLNotificationsUtil::add("UnknownScriptQuestion",args,payload);  		} - +		  		if (known_questions)  		{  			LLSD payload; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 9de55f96f0..5ae08a8b9e 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -207,6 +207,8 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe  	mTotalCRC(0),  	mListIndex(-1),  	mTEImages(NULL), +	mTENormalMaps(NULL), +	mTESpecularMaps(NULL),  	mGLName(0),  	mbCanSelect(TRUE),  	mFlags(0), @@ -327,6 +329,18 @@ void LLViewerObject::deleteTEImages()  {  	delete[] mTEImages;  	mTEImages = NULL; +	 +	if (mTENormalMaps != NULL) +	{ +		delete[] mTENormalMaps; +		mTENormalMaps = NULL; +	} +	 +	if (mTESpecularMaps != NULL) +	{ +		delete[] mTESpecularMaps; +		mTESpecularMaps = NULL; +	}	  }  void LLViewerObject::markDead() @@ -640,6 +654,17 @@ void LLViewerObject::setNameValueList(const std::string& name_value_list)  	}  } +void LLViewerObject::setSelected(BOOL sel) +{ +	mUserSelected = sel; +	resetRot(); + +	if (!sel) +	{ +		setAllTESelected(false); +	} +} +  // This method returns true if the object is over land owned by the  // agent.  bool LLViewerObject::isReturnable() @@ -1856,8 +1881,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  				// stores the extended permission info.  				if(mesgsys != NULL)  				{ -					U32 flags; -					mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num); +				U32 flags; +				mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num);  					loadFlags(flags);					  				}  			} @@ -2237,7 +2262,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  		// If we're snapping the position by more than 0.5m, update LLViewerStats::mAgentPositionSnaps  		if ( asAvatar() && asAvatar()->isSelf() && (mag_sqr > 0.25f) )  		{ -			record(LLStatViewer::AGENT_POSITION_SNAP, LLTrace::Meters(diff.length())); +			record(LLStatViewer::AGENT_POSITION_SNAP, LLUnit<F64, LLUnits::Meters>(diff.length()));  		}  	} @@ -2919,25 +2944,25 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS  		if (object->loadTaskInvFile(ft->mFilename))  		{ -		LLInventoryObject::object_list_t::iterator it = object->mInventory->begin(); -		LLInventoryObject::object_list_t::iterator end = object->mInventory->end(); -		std::list<LLUUID>& pending_lst = object->mPendingInventoryItemsIDs; +			LLInventoryObject::object_list_t::iterator it = object->mInventory->begin(); +			LLInventoryObject::object_list_t::iterator end = object->mInventory->end(); +			std::list<LLUUID>& pending_lst = object->mPendingInventoryItemsIDs; -		for (; it != end && pending_lst.size(); ++it) -		{ -			LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(it->get()); -			if(item && item->getType() != LLAssetType::AT_CATEGORY) +			for (; it != end && pending_lst.size(); ++it)  			{ -				std::list<LLUUID>::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID()); -				if (id_it != pending_lst.end()) +				LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(it->get()); +				if(item && item->getType() != LLAssetType::AT_CATEGORY)  				{ -					pending_lst.erase(id_it); +					std::list<LLUUID>::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID()); +					if (id_it != pending_lst.end()) +					{ +						pending_lst.erase(id_it); +					}  				}  			}  		} -	} -	else -	{ +		else +		{  			// MAINT-2597 - crash when trying to edit a no-mod object  			// Somehow get an contents inventory response, but with an invalid stream (possibly 0 size?)  			// Stated repro was specific to no-mod objects so failing without user interaction should be safe. @@ -4014,19 +4039,19 @@ LLViewerObject* LLViewerObject::getRootEdit() const  } -BOOL LLViewerObject::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +BOOL LLViewerObject::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  										  S32 face,  										  BOOL pick_transparent,  										  S32* face_hit, -										  LLVector3* intersection, +										  LLVector4a* intersection,  										  LLVector2* tex_coord, -										  LLVector3* normal, -										  LLVector3* bi_normal) +										  LLVector4a* normal, +										  LLVector4a* tangent)  {  	return false;  } -BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end) +BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end)  {  	if (mDrawable.isNull() || mDrawable->isDead())  	{ @@ -4043,11 +4068,7 @@ BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVect  	size.setSub(ext[1], ext[0]);  	size.mul(0.5f); -	LLVector4a starta, enda; -	starta.load3(start.mV); -	enda.load3(end.mV); - -	return LLLineSegmentBoxIntersect(starta, enda, center, size); +	return LLLineSegmentBoxIntersect(start, end, center, size);  }  U8 LLViewerObject::getMediaType() const @@ -4146,25 +4167,39 @@ void LLViewerObject::setNumTEs(const U8 num_tes)  		{  			LLPointer<LLViewerTexture> *new_images;  			new_images = new LLPointer<LLViewerTexture>[num_tes]; +			 +			LLPointer<LLViewerTexture> *new_normmaps; +			new_normmaps = new LLPointer<LLViewerTexture>[num_tes]; +			 +			LLPointer<LLViewerTexture> *new_specmaps; +			new_specmaps = new LLPointer<LLViewerTexture>[num_tes];  			for (i = 0; i < num_tes; i++)  			{  				if (i < getNumTEs())  				{  					new_images[i] = mTEImages[i]; +					new_normmaps[i] = mTENormalMaps[i]; +					new_specmaps[i] = mTESpecularMaps[i];  				}  				else if (getNumTEs())  				{  					new_images[i] = mTEImages[getNumTEs()-1]; +					new_normmaps[i] = mTENormalMaps[getNumTEs()-1]; +					new_specmaps[i] = mTESpecularMaps[getNumTEs()-1];  				}  				else  				{  					new_images[i] = NULL; +					new_normmaps[i] = NULL; +					new_specmaps[i] = NULL;  				}  			}  			deleteTEImages();  			mTEImages = new_images; +			mTENormalMaps = new_normmaps; +			mTESpecularMaps = new_specmaps;  		}  		else  		{ @@ -4243,12 +4278,18 @@ void LLViewerObject::sendTEUpdate() const  void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)  {  	LLPrimitive::setTE(te, texture_entry); -//  This doesn't work, don't get any textures. -//	if (mDrawable.notNull() && mDrawable->isVisible()) -//	{ +  		const LLUUID& image_id = getTE(te)->getID();  		mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); -//	} +	 +	if (getTE(te)->getMaterialParams().notNull()) +	{ +		const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID(); +		mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(norm_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); +		 +		const LLUUID& spec_id = getTE(te)->getMaterialParams()->getSpecularID(); +		mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); +	}  }  void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep) @@ -4283,6 +4324,52 @@ S32 LLViewerObject::setTETextureCore(const U8 te, LLViewerTexture *image)  	return retval;  } +S32 LLViewerObject::setTENormalMapCore(const U8 te, LLViewerTexture *image) +{ +	S32 retval = TEM_CHANGE_TEXTURE; +	const LLUUID& uuid = image ? image->getID() : LLUUID::null; +	if (uuid != getTE(te)->getID() || +		uuid == LLUUID::null) +	{ +		LLTextureEntry* tep = getTE(te); +		LLMaterial* mat = NULL; +		if (tep) +		{ +		   mat = tep->getMaterialParams(); +		} + +		if (mat) +		{ +			mat->setNormalID(uuid); +		} +	} +	changeTENormalMap(te,image);	 +	return retval; +} + +S32 LLViewerObject::setTESpecularMapCore(const U8 te, LLViewerTexture *image) +{ +	S32 retval = TEM_CHANGE_TEXTURE; +	const LLUUID& uuid = image ? image->getID() : LLUUID::null; +	if (uuid != getTE(te)->getID() || +		uuid == LLUUID::null) +	{ +		LLTextureEntry* tep = getTE(te); +		LLMaterial* mat = NULL; +		if (tep) +		{ +			mat = tep->getMaterialParams(); +		} + +		if (mat) +		{ +			mat->setSpecularID(uuid); +		}		 +	} +	changeTESpecularMap(te, image); +	return retval; +} +  //virtual  void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)   { @@ -4293,6 +4380,26 @@ void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)  	mTEImages[index] = new_image ;  } +void LLViewerObject::changeTENormalMap(S32 index, LLViewerTexture* new_image) +{ +	if(index < 0 || index >= getNumTEs()) +	{ +		return ; +	} +	mTENormalMaps[index] = new_image ; +	refreshMaterials(); +} + +void LLViewerObject::changeTESpecularMap(S32 index, LLViewerTexture* new_image) +{ +	if(index < 0 || index >= getNumTEs()) +	{ +		return ; +	} +	mTESpecularMaps[index] = new_image ; +	refreshMaterials(); +} +  S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)  {  	// Invalid host == get from the agent's sim @@ -4301,6 +4408,19 @@ S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)  	return setTETextureCore(te,image);  } +S32 LLViewerObject::setTENormalMap(const U8 te, const LLUUID& uuid) +{ +	LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture( +		uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost::invalid); +	return setTENormalMapCore(te, image); +} + +S32 LLViewerObject::setTESpecularMap(const U8 te, const LLUUID& uuid) +{ +	LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture( +		uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost::invalid); +	return setTESpecularMapCore(te, image); +}  S32 LLViewerObject::setTEColor(const U8 te, const LLColor3& color)  { @@ -4461,6 +4581,61 @@ S32 LLViewerObject::setTEGlow(const U8 te, const F32 glow)  	return retval;  } +S32 LLViewerObject::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) +{ +	S32 retval = 0; +	const LLTextureEntry *tep = getTE(te); +	if (!tep) +	{ +		LL_WARNS("Material") << "No texture entry for te " << (S32)te +							 << ", object " << mID +							 << ", material " << pMaterialID +							 << LL_ENDL; +	} +	//else if (pMaterialID != tep->getMaterialID()) +	{ +		LL_DEBUGS("Material") << "Changing texture entry for te " << (S32)te +							 << ", object " << mID +							 << ", material " << pMaterialID +							 << LL_ENDL; +		retval = LLPrimitive::setTEMaterialID(te, pMaterialID); +		refreshMaterials(); +	} +	return retval; +} + +S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) +{ +	S32 retval = 0; +	const LLTextureEntry *tep = getTE(te); +	if (!tep) +	{ +		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl; +		return 0; +	} + +	retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams); +	LL_DEBUGS("Material") << "Changing material params for te " << (S32)te +							<< ", object " << mID +			               << " (" << retval << ")" +							<< LL_ENDL; +	setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null); +	setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null); + +	refreshMaterials(); +	return retval; +} + +void LLViewerObject::refreshMaterials() +{ +	setChanged(ALL_CHANGED); +	if (mDrawable.notNull()) +	{ +		gPipeline.markTextured(mDrawable); +		gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL); +		dirtySpatialGroup(TRUE); +	} +}  S32 LLViewerObject::setTEScale(const U8 te, const F32 s, const F32 t)  { @@ -4562,6 +4737,50 @@ LLViewerTexture *LLViewerObject::getTEImage(const U8 face) const  } +LLViewerTexture *LLViewerObject::getTENormalMap(const U8 face) const +{ +	//	llassert(mTEImages); +	 +	if (face < getNumTEs()) +	{ +		LLViewerTexture* image = mTENormalMaps[face]; +		if (image) +		{ +			return image; +		} +		else +		{ +			return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep); +		} +	} +	 +	llerrs << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl; +	 +	return NULL; +} + +LLViewerTexture *LLViewerObject::getTESpecularMap(const U8 face) const +{ +	//	llassert(mTEImages); +	 +	if (face < getNumTEs()) +	{ +		LLViewerTexture* image = mTESpecularMaps[face]; +		if (image) +		{ +			return image; +		} +		else +		{ +			return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep); +		} +	} +	 +	llerrs << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl; +	 +	return NULL; +} +  void LLViewerObject::fitFaceTexture(const U8 face)  {  	llinfos << "fitFaceTexture not implemented" << llendl; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 41a559c19d..5556a4c7d3 100755 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -212,7 +212,7 @@ public:  	LLViewerRegion* getRegion() const				{ return mRegionp; }  	BOOL isSelected() const							{ return mUserSelected; } -	virtual void setSelected(BOOL sel)				{ mUserSelected = sel; resetRot();} +	virtual void setSelected(BOOL sel);  	const LLUUID &getID() const						{ return mID; }  	U32 getLocalID() const							{ return mLocalID; } @@ -259,17 +259,17 @@ public:  	//detect if given line segment (in agent space) intersects with this viewer object.  	//returns TRUE if intersection detected and returns information about intersection -	virtual BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +	virtual BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  									  S32 face = -1,                          // which face to check, -1 = ALL_SIDES  									  BOOL pick_transparent = FALSE,  									  S32* face_hit = NULL,                   // which face was hit -									  LLVector3* intersection = NULL,         // return the intersection point +									  LLVector4a* intersection = NULL,         // return the intersection point  									  LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point -									  LLVector3* normal = NULL,               // return the surface normal at the intersection point -									  LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point +									  LLVector4a* normal = NULL,               // return the surface normal at the intersection point +									  LLVector4a* tangent = NULL             // return the surface tangent at the intersection point  		); -	virtual BOOL lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end); +	virtual BOOL lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end);  	virtual const LLVector3d getPositionGlobal() const;  	virtual const LLVector3 &getPositionRegion() const; @@ -302,7 +302,11 @@ public:  	/*virtual*/	void	setNumTEs(const U8 num_tes);  	/*virtual*/	void	setTE(const U8 te, const LLTextureEntry &texture_entry);  	/*virtual*/ S32		setTETexture(const U8 te, const LLUUID &uuid); +	/*virtual*/ S32		setTENormalMap(const U8 te, const LLUUID &uuid); +	/*virtual*/ S32		setTESpecularMap(const U8 te, const LLUUID &uuid);  	S32 				setTETextureCore(const U8 te, LLViewerTexture *image); +	S32 setTENormalMapCore(const U8 te, LLViewerTexture *image); +	S32 setTESpecularMapCore(const U8 te, LLViewerTexture *image);  	/*virtual*/ S32		setTEColor(const U8 te, const LLColor3 &color);  	/*virtual*/ S32		setTEColor(const U8 te, const LLColor4 &color);  	/*virtual*/ S32		setTEScale(const U8 te, const F32 s, const F32 t); @@ -319,10 +323,22 @@ public:  	/*virtual*/	S32		setTEFullbright(const U8 te, const U8 fullbright );  	/*virtual*/	S32		setTEMediaFlags(const U8 te, const U8 media_flags );  	/*virtual*/ S32     setTEGlow(const U8 te, const F32 glow); +	/*virtual*/ S32     setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); +	/*virtual*/ S32		setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams); + +	// Used by Materials update functions to properly kick off rebuilds +	// of VBs etc when materials updates require changes. +	// +	void refreshMaterials(); +  	/*virtual*/	BOOL	setMaterial(const U8 material);  	virtual		void	setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive  	virtual     void    changeTEImage(S32 index, LLViewerTexture* new_image)  ; +	virtual     void    changeTENormalMap(S32 index, LLViewerTexture* new_image)  ; +	virtual     void    changeTESpecularMap(S32 index, LLViewerTexture* new_image)  ;  	LLViewerTexture		*getTEImage(const U8 te) const; +	LLViewerTexture		*getTENormalMap(const U8 te) const; +	LLViewerTexture		*getTESpecularMap(const U8 te) const;  	void fitFaceTexture(const U8 face);  	void sendTEUpdate() const;			// Sends packed representation of all texture entry information @@ -607,6 +623,8 @@ public:  	S32				mListIndex;  	LLPointer<LLViewerTexture> *mTEImages; +	LLPointer<LLViewerTexture> *mTENormalMaps; +	LLPointer<LLViewerTexture> *mTESpecularMaps;  	// Selection, picking and rendering variables  	U32				mGLName;			// GL "name" used by selection code diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index ea004560d2..b215869a3e 100755 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -263,7 +263,7 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,  	// so that the drawable parent is set properly  	if(msg != NULL)  	{ -		findOrphans(objectp, msg->getSenderIP(), msg->getSenderPort()); +	findOrphans(objectp, msg->getSenderIP(), msg->getSenderPort());  	}  	else  	{ @@ -456,9 +456,9 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  		if (compressed)  		{ -			S32	uncompressed_length = 2048; -			compressed_dp.reset();			 -			 +			S32							uncompressed_length = 2048; +			compressed_dp.reset(); +  			uncompressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data);  			mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compressed_dpbuffer, 0, i);  			compressed_dp.assignBuffer(compressed_dpbuffer, uncompressed_length); @@ -470,10 +470,10 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  				if(flags & FLAGS_TEMPORARY_ON_REZ)  				{ -					compressed_dp.unpackUUID(fullid, "ID"); -					compressed_dp.unpackU32(local_id, "LocalID"); -					compressed_dp.unpackU8(pcode, "PCode"); -				} +				compressed_dp.unpackUUID(fullid, "ID"); +				compressed_dp.unpackU32(local_id, "LocalID"); +				compressed_dp.unpackU8(pcode, "PCode"); +			}  				else //send to object cache  				{  					regionp->cacheFullUpdate(compressed_dp, flags); @@ -520,7 +520,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  			// llinfos << "Full Update, obj " << local_id << ", global ID" << fullid << "from " << mesgsys->getSender() << llendl;  		}  		objectp = findObject(fullid); -		 +  		if(remove_from_cache)  		{  			objectp = regionp->forceToRemoveFromCache(local_id, objectp); @@ -628,11 +628,11 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  				if(!(flags & FLAGS_TEMPORARY_ON_REZ))  				{ -					bCached = true; +				bCached = true;  					LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp, flags); -					recorder.cacheFullUpdate(local_id, update_type, result, objectp, msg_size); -				} +				recorder.cacheFullUpdate(local_id, update_type, result, objectp, msg_size);  			} +		}  #endif  		}  		else @@ -1025,10 +1025,10 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)  	static std::vector<LLViewerObject*> idle_list;  	U32 idle_count = 0; -		 +	  	{  		LLFastTimer t(FTM_IDLE_COPY); -		 +   		for (std::vector<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin();  			active_iter != mActiveObjects.end(); active_iter++)  		{ @@ -1037,9 +1037,9 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)  			{  				if (idle_count >= idle_list.size())  				{ -					idle_list.push_back( objectp ); -				} -				else +				idle_list.push_back( objectp ); +			} +			else  				{  					idle_list[idle_count] = objectp;  				} @@ -1056,7 +1056,7 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)  	std::vector<LLViewerObject*>::iterator idle_end = idle_list.begin()+idle_count;  	if (gSavedSettings.getBOOL("FreezeTime")) -	{	 +	{  		for (std::vector<LLViewerObject*>::iterator iter = idle_list.begin();  			iter != idle_end; iter++) @@ -1077,14 +1077,14 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)  			llassert(objectp->isActive());  			objectp->idleUpdate(agent, world, frame_time); -		} +			}  		//update flexible objects  		LLVolumeImplFlexible::updateClass();  		//update animated textures  		LLViewerTextureAnim::updateClass(); -	} +			} @@ -1521,10 +1521,10 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp)  			{  				mActiveObjects.push_back(objectp);  				objectp->setListIndex(mActiveObjects.size()-1); -				objectp->setOnActiveList(TRUE); -			} -			else -			{ +			objectp->setOnActiveList(TRUE); +		} +		else +		{  				llassert(idx < mActiveObjects.size());  				llassert(mActiveObjects[idx] == objectp); @@ -1653,13 +1653,13 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset)  	{  		LLFastTimer t(FTM_PIPELINE_SHIFT); -		gPipeline.shiftObjects(offset); +	gPipeline.shiftObjects(offset);  	}  	{  		LLFastTimer t(FTM_REGION_SHIFT); -		LLWorld::getInstance()->shiftRegions(offset); -	} +	LLWorld::getInstance()->shiftRegions(offset); +}  }  void LLViewerObjectList::repartitionObjects() diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index c3c791c158..dd4c7f2aff 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -93,28 +93,28 @@ typedef std::map<std::string, std::string> CapabilityMap;  class LLViewerRegionImpl {  public:  	LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host) -	:	mHost(host), -		mCompositionp(NULL), -		mEventPoll(NULL), -		mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS), -		mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN), -		mSeedCapAttempts(0), -		mHttpResponderID(0), +		:	mHost(host), +			mCompositionp(NULL), +			mEventPoll(NULL), +			mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS), +			mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN), +			mSeedCapAttempts(0), +			mHttpResponderID(0),  		mLastCameraUpdate(0),  		mLastCameraOrigin(),  		mVOCachePartition(NULL),  		mLandp(NULL), -		// I'd prefer to set the LLCapabilityListener name to match the region -		// name -- it's disappointing that's not available at construction time. -		// We could instead store an LLCapabilityListener*, making -		// setRegionNameAndZone() replace the instance. Would that pose -		// consistency problems? Can we even request a capability before calling -		// setRegionNameAndZone()? -		// For testability -- the new Michael Feathers paradigm -- -		// LLCapabilityListener binds all the globals it expects to need at -		// construction time. -		mCapabilityListener(host.getString(), gMessageSystem, *region, -		                    gAgent.getID(), gAgent.getSessionID()) +		    // I'd prefer to set the LLCapabilityListener name to match the region +		    // name -- it's disappointing that's not available at construction time. +		    // We could instead store an LLCapabilityListener*, making +		    // setRegionNameAndZone() replace the instance. Would that pose +		    // consistency problems? Can we even request a capability before calling +		    // setRegionNameAndZone()? +		    // For testability -- the new Michael Feathers paradigm -- +		    // LLCapabilityListener binds all the globals it expects to need at +		    // construction time. +		    mCapabilityListener(host.getString(), gMessageSystem, *region, +		                        gAgent.getID(), gAgent.getSessionID())  	{}  	void buildCapabilityNames(LLSD& capabilityNames); @@ -157,7 +157,7 @@ public:  	CapabilityMap mCapabilities;  	CapabilityMap mSecondCapabilitiesTracker;  -	 +  	LLEventPoll* mEventPoll;  	S32 mSeedCapMaxAttempts; @@ -237,7 +237,7 @@ public:  		}      } -    void result(const LLSD& content) +   void result(const LLSD& content)      {  		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);  		if(!regionp) //region was removed @@ -1168,8 +1168,8 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time)  	max_update_time -= update_timer.getElapsedTimeF32();  	if(max_update_time < 0.f || mImpl->mCacheMap.empty())  	{ -		return did_update; -	} +	return did_update; +}  	if(!sVOCacheCullingEnabled)  	{ @@ -1905,7 +1905,7 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerB  	LLViewerObject::unpackU32(&dp, crc, "CRC");  	LLVOCacheEntry* entry = getCacheEntry(local_id); -	 +  	if (entry)  	{  		// we've seen this object before @@ -1933,8 +1933,8 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerB  				mImpl->mCacheMap[local_id] = entry;  				decodeBoundingInfo(entry); -			} -			 +		} +  			result = CACHE_UPDATE_CHANGED;  		}  	} @@ -1952,7 +1952,7 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerB  	entry->setUpdateFlags(flags);  	return result; -} +	}  LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags)  { @@ -1964,7 +1964,7 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec  	{  		return result;  	} - +		  	if(objectp->mDrawable.notNull() && !entry->getEntry())  	{  		entry->setOctreeEntry(objectp->mDrawable->getEntry()); @@ -2055,7 +2055,7 @@ bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss  		{  			// Record a hit  			entry->recordHit(); -			cache_miss_type = CACHE_MISS_TYPE_NONE; +		cache_miss_type = CACHE_MISS_TYPE_NONE;  			entry->setUpdateFlags(flags);  			if(entry->isState(LLVOCacheEntry::ACTIVE)) @@ -2103,7 +2103,7 @@ void LLViewerRegion::requestCacheMisses()  	LLMessageSystem* msg = gMessageSystem;  	BOOL start_new_message = TRUE;  	S32 blocks = 0; -	 +  	//send requests for all cache-missed objects  	for (CacheMissItem::cache_miss_list_t::iterator iter = mCacheMissList.begin(); iter != mCacheMissList.end(); ++iter)  	{ @@ -2133,7 +2133,7 @@ void LLViewerRegion::requestCacheMisses()  	if (!start_new_message)  	{  		sendReliableMessage(); -	}	 +	}  	mCacheDirty = TRUE ;  	// llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl; @@ -2349,7 +2349,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("EventQueueGet");  	if (gSavedSettings.getBOOL("UseHTTPInventory")) -	{ +	{	  		capabilityNames.append("FetchLib2");  		capabilityNames.append("FetchLibDescendents2");  		capabilityNames.append("FetchInventory2"); @@ -2379,6 +2379,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("ProductInfoRequest");  	capabilityNames.append("ProvisionVoiceAccountRequest");  	capabilityNames.append("RemoteParcelRequest"); +	capabilityNames.append("RenderMaterials");  	capabilityNames.append("RequestTextureDownload");  	capabilityNames.append("ResourceCostSelected");  	capabilityNames.append("RetrieveNavMeshSrc"); @@ -2416,8 +2417,8 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  void LLViewerRegion::setSeedCapability(const std::string& url)  {  	if (getCapability("Seed") == url) -    { -		// llwarns << "Ignoring duplicate seed capability" << llendl; +    {	 +		//llwarns << "Ignoring duplicate seed capability" << llendl;  		//Instead of just returning we build up a second set of seed caps and compare them   		//to the "original" seed cap received and determine why there is problem!  		LLSD capabilityNames = LLSD::emptyArray(); diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 78a6c782a9..29483662e8 100755 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -86,7 +86,7 @@ public:  		PARTITION_GRASS,  		PARTITION_VOLUME,  		PARTITION_BRIDGE, -		PARTITION_HUD_PARTICLE,		 +		PARTITION_HUD_PARTICLE,  		PARTITION_VO_CACHE,  		PARTITION_NONE,  		NUM_PARTITIONS @@ -358,7 +358,7 @@ public:  	void getNeighboringRegionsStatus( std::vector<S32>& regions );  	const LLViewerRegionImpl * getRegionImpl() const { return mImpl; }  	LLViewerRegionImpl * getRegionImplNC() { return mImpl; } -	 +  	void removeFromCreatedList(U32 local_id);  	void addToCreatedList(U32 local_id); @@ -457,16 +457,16 @@ private:  	// Maps local ids to cache entries.  	// Regions can have order 10,000 objects, so assume  	// a structure of size 2^14 = 16,000 -	BOOL	mCacheLoaded; -	BOOL    mCacheDirty; +	BOOL									mCacheLoaded; +	BOOL                                    mCacheDirty;  	BOOL	mAlive;					// can become false if circuit disconnects  	BOOL	mCapabilitiesReceived;  	BOOL    mReleaseNotesRequested;  	BOOL    mDead;  //if true, this region is in the process of deleting. -	 +  	typedef std::map<U32, std::vector<U32> > orphan_list_t;  	orphan_list_t mOrphanMap; -	 +  	class CacheMissItem  	{  	public: @@ -474,7 +474,7 @@ private:  		U32                            mID;     //local object id  		LLViewerRegion::eCacheMissType mType;   //cache miss type -	 +  		typedef std::list<CacheMissItem> cache_miss_list_t;  	};  	CacheMissItem::cache_miss_list_t   mCacheMissList; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 78775c7205..e31d47fe93 100755 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -44,6 +44,18 @@  #if LL_DARWIN  #include "OpenGL/OpenGL.h" + +// include spec exp clamp to fix older mac rendering artifacts +// +#define SINGLE_FP_PERMUTATION(shader)					\ +	if (gGLManager.mIsMobileGF)							\ +	{																\ +		shader.addPermutation("SINGLE_FP_ONLY","1");		\ +	} + + +#else +#define SINGLE_FP_PERMUTATION(shader)  #endif  #ifdef LL_RELEASE_FOR_DOWNLOAD @@ -68,7 +80,7 @@ LLGLSLShader			gTransformPositionProgram;  LLGLSLShader			gTransformTexCoordProgram;  LLGLSLShader			gTransformNormalProgram;  LLGLSLShader			gTransformColorProgram; -LLGLSLShader			gTransformBinormalProgram; +LLGLSLShader			gTransformTangentProgram;  //utility shaders  LLGLSLShader	gOcclusionProgram; @@ -145,6 +157,9 @@ LLGLSLShader		gUnderWaterProgram;  //interface shaders  LLGLSLShader		gHighlightProgram; +LLGLSLShader		gHighlightNormalProgram; +LLGLSLShader		gHighlightSpecularProgram; +  LLGLSLShader		gPathfindingProgram;  LLGLSLShader		gPathfindingNoNormalsProgram; @@ -202,13 +217,20 @@ LLGLSLShader			gDeferredEmissiveProgram;  LLGLSLShader			gDeferredPostProgram;  LLGLSLShader			gDeferredCoFProgram;  LLGLSLShader			gDeferredDoFCombineProgram; +LLGLSLShader			gDeferredPostGammaCorrectProgram;  LLGLSLShader			gFXAAProgram;  LLGLSLShader			gDeferredPostNoDoFProgram;  LLGLSLShader			gDeferredWLSkyProgram;  LLGLSLShader			gDeferredWLCloudProgram;  LLGLSLShader			gDeferredStarProgram; +LLGLSLShader			gDeferredFullbrightShinyProgram; +LLGLSLShader			gDeferredSkinnedFullbrightShinyProgram; +LLGLSLShader			gDeferredSkinnedFullbrightProgram;  LLGLSLShader			gNormalMapGenProgram; +// Deferred materials shaders +LLGLSLShader			gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; +  LLViewerShaderMgr::LLViewerShaderMgr() :  	mVertexShaderLevel(SHADER_COUNT, 0),  	mMaxAvatarShaderLevel(0) @@ -273,9 +295,20 @@ LLViewerShaderMgr::LLViewerShaderMgr() :  	mShaderList.push_back(&gUnderWaterProgram);  	mShaderList.push_back(&gDeferredSunProgram);  	mShaderList.push_back(&gDeferredSoftenProgram); +	mShaderList.push_back(&gDeferredMaterialProgram[1]); +	mShaderList.push_back(&gDeferredMaterialProgram[5]); +	mShaderList.push_back(&gDeferredMaterialProgram[9]); +	mShaderList.push_back(&gDeferredMaterialProgram[13]); +	mShaderList.push_back(&gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT]); +	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(&gDeferredAlphaProgram);  	mShaderList.push_back(&gDeferredSkinnedAlphaProgram);  	mShaderList.push_back(&gDeferredFullbrightProgram); +	mShaderList.push_back(&gDeferredFullbrightShinyProgram); +	mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram); +	mShaderList.push_back(&gDeferredSkinnedFullbrightProgram);  	mShaderList.push_back(&gDeferredEmissiveProgram);  	mShaderList.push_back(&gDeferredAvatarEyesProgram);  	mShaderList.push_back(&gDeferredWaterProgram); @@ -453,6 +486,12 @@ void LLViewerShaderMgr::setShaders()  		S32 deferred_class = 0;  		S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0; +		static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback"); +		if (!use_transform_feedback) +		{ +			transform_class = 0; +		} +		  		if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&  		    gSavedSettings.getBOOL("RenderDeferred") &&  			gSavedSettings.getBOOL("RenderAvatarVP") && @@ -744,6 +783,8 @@ void LLViewerShaderMgr::unloadShaders()  	gAvatarEyeballProgram.unload();  	gAvatarPickProgram.unload();  	gHighlightProgram.unload(); +	gHighlightNormalProgram.unload(); +	gHighlightSpecularProgram.unload();  	gWLSkyProgram.unload();  	gWLCloudProgram.unload(); @@ -764,7 +805,7 @@ void LLViewerShaderMgr::unloadShaders()  	gTransformTexCoordProgram.unload();  	gTransformNormalProgram.unload();  	gTransformColorProgram.unload(); -	gTransformBinormalProgram.unload(); +	gTransformTangentProgram.unload();  	mVertexShaderLevel[SHADER_LIGHTING] = 0;  	mVertexShaderLevel[SHADER_OBJECT] = 0; @@ -784,9 +825,6 @@ BOOL LLViewerShaderMgr::loadBasicShaders()  	// Load basic dependency shaders first  	// All of these have to load for any shaders to function -#if LL_DARWIN // Mac can't currently handle all 8 lights,  -	S32 sum_lights_class = 2; -#else   	S32 sum_lights_class = 3;  	// class one cards will get the lower sum lights @@ -797,7 +835,6 @@ BOOL LLViewerShaderMgr::loadBasicShaders()  	{  		sum_lights_class = 2;  	} -#endif  	// If we have sun and moon only checked, then only sum those lights.  	if (gPipeline.getLightingDetail() == 0) @@ -805,6 +842,14 @@ BOOL LLViewerShaderMgr::loadBasicShaders()  		sum_lights_class = 1;  	} +#if LL_DARWIN +	// Work around driver crashes on older Macs when using deferred rendering +	// NORSPEC-59 +	// +	if (gGLManager.mIsMobileGF) +		sum_lights_class = 3; +#endif +	  	// Use the feature table to mask out the max light level to use.  Also make sure it's at least 1.  	S32 max_light_class = gSavedSettings.getS32("RenderShaderLightingMaxLevel");  	sum_lights_class = llclamp(sum_lights_class, 1, max_light_class); @@ -831,11 +876,13 @@ BOOL LLViewerShaderMgr::loadBasicShaders()  	}  	shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl",		1 ) ); +	boost::unordered_map<std::string, std::string> attribs; +	  	// We no longer have to bind the shaders to global glhandles, they are automatically added to a map now.  	for (U32 i = 0; i < shaders.size(); i++)  	{  		// Note usage of GL_VERTEX_SHADER_ARB -		if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB) == 0) +		if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB, &attribs) == 0)  		{  			return FALSE;  		} @@ -887,7 +934,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders()  	for (U32 i = 0; i < shaders.size(); i++)  	{  		// Note usage of GL_FRAGMENT_SHADER_ARB -		if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, index_channels[i]) == 0) +		if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, &attribs, index_channels[i]) == 0)  		{  			return FALSE;  		} @@ -1101,12 +1148,21 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredPostProgram.unload();		  		gDeferredCoFProgram.unload();		  		gDeferredDoFCombineProgram.unload(); +		gDeferredPostGammaCorrectProgram.unload();  		gFXAAProgram.unload();  		gDeferredWaterProgram.unload();  		gDeferredWLSkyProgram.unload();  		gDeferredWLCloudProgram.unload();  		gDeferredStarProgram.unload(); +		gDeferredFullbrightShinyProgram.unload(); +		gDeferredSkinnedFullbrightShinyProgram.unload(); +		gDeferredSkinnedFullbrightProgram.unload(); +  		gNormalMapGenProgram.unload(); +		for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i) +		{ +			gDeferredMaterialProgram[i].unload(); +		}  		return TRUE;  	} @@ -1200,10 +1256,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSkinnedAlphaProgram.mFeatures.isAlphaLighting = true;  		gDeferredSkinnedAlphaProgram.mFeatures.disableTextureIndex = true;  		gDeferredSkinnedAlphaProgram.mShaderFiles.clear(); -		gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredSkinnedAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; -		 +		gDeferredSkinnedAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1"); +		gDeferredSkinnedAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1"); +		gDeferredSkinnedAlphaProgram.addPermutation("HAS_SKIN", "1"); +		gDeferredSkinnedAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");  		success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL);  		// Hack to include uniforms for lighting without linking in lighting file @@ -1221,6 +1280,56 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		success = gDeferredBumpProgram.createShader(NULL, NULL);  	} +	gDeferredMaterialProgram[1].mFeatures.hasLighting = false; +	gDeferredMaterialProgram[5].mFeatures.hasLighting = false; +	gDeferredMaterialProgram[9].mFeatures.hasLighting = false; +	gDeferredMaterialProgram[13].mFeatures.hasLighting = false; +	gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; +	gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; +	gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; +	gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; + +	for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i) +	{ +		if (success) +		{ +			gDeferredMaterialProgram[i].mName = llformat("Deferred Material Shader %d", i); +			 +			U32 alpha_mode = i & 0x3; + +			gDeferredMaterialProgram[i].mShaderFiles.clear(); +			gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB)); +			gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB)); +			gDeferredMaterialProgram[i].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +			gDeferredMaterialProgram[i].addPermutation("HAS_NORMAL_MAP", i & 0x8? "1" : "0"); +			gDeferredMaterialProgram[i].addPermutation("HAS_SPECULAR_MAP", i & 0x4 ? "1" : "0"); +			gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); +			gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0"); +			bool has_skin = i & 0x10; +			gDeferredMaterialProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0"); + +			SINGLE_FP_PERMUTATION(gDeferredMaterialProgram[i]); + +			if (has_skin) +			{ +				gDeferredMaterialProgram[i].mFeatures.hasObjectSkinning = true; +			} + +			success = gDeferredMaterialProgram[i].createShader(NULL, NULL); +		} +	} + +	gDeferredMaterialProgram[1].mFeatures.hasLighting = true; +	gDeferredMaterialProgram[5].mFeatures.hasLighting = true; +	gDeferredMaterialProgram[9].mFeatures.hasLighting = true; +	gDeferredMaterialProgram[13].mFeatures.hasLighting = true; +	gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; +	gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; +	gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; +	gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; + + +	  	if (success)  	{  		gDeferredTreeProgram.mName = "Deferred Tree Shader"; @@ -1258,6 +1367,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + +		SINGLE_FP_PERMUTATION(gDeferredLightProgram); +  		success = gDeferredLightProgram.createShader(NULL, NULL);  	} @@ -1268,6 +1380,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredMultiLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + +		SINGLE_FP_PERMUTATION(gDeferredMultiLightProgram); +  		success = gDeferredMultiLightProgram.createShader(NULL, NULL);  	} @@ -1278,6 +1393,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + +		SINGLE_FP_PERMUTATION(gDeferredSpotLightProgram); +  		success = gDeferredSpotLightProgram.createShader(NULL, NULL);  	} @@ -1288,6 +1406,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredMultiSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + +		SINGLE_FP_PERMUTATION(gDeferredMultiSpotLightProgram); +  		success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL);  	} @@ -1314,6 +1435,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER_ARB));  		gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredSunProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + +		SINGLE_FP_PERMUTATION(gDeferredSunProgram); +  		success = gDeferredSunProgram.createShader(NULL, NULL);  	} @@ -1324,6 +1448,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredBlurLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + +		SINGLE_FP_PERMUTATION(gDeferredBlurLightProgram); +  		success = gDeferredBlurLightProgram.createShader(NULL, NULL);  	} @@ -1350,8 +1477,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAlphaProgram.mShaderFiles.clear();  		gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredAlphaProgram.addPermutation("USE_INDEXED_TEX", "1"); +		gDeferredAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1"); +		gDeferredAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");  		gDeferredAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		SINGLE_FP_PERMUTATION(gDeferredAlphaProgram); +  		success = gDeferredAlphaProgram.createShader(NULL, NULL);  		// Hack @@ -1389,6 +1521,50 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ +		gDeferredFullbrightShinyProgram.mName = "Deferred FullbrightShiny Shader"; +		gDeferredFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; +		gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true; +		gDeferredFullbrightShinyProgram.mFeatures.hasTransport = true; +		gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels-1; +		gDeferredFullbrightShinyProgram.mShaderFiles.clear(); +		gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		success = gDeferredFullbrightShinyProgram.createShader(NULL, &mShinyUniforms); +	} + +	if (success) +	{ +		gDeferredSkinnedFullbrightProgram.mName = "Skinned Fullbright Shader"; +		gDeferredSkinnedFullbrightProgram.mFeatures.calculatesAtmospherics = true; +		gDeferredSkinnedFullbrightProgram.mFeatures.hasGamma = true; +		gDeferredSkinnedFullbrightProgram.mFeatures.hasTransport = true; +		gDeferredSkinnedFullbrightProgram.mFeatures.hasObjectSkinning = true; +		gDeferredSkinnedFullbrightProgram.mFeatures.disableTextureIndex = true; +		gDeferredSkinnedFullbrightProgram.mShaderFiles.clear(); +		gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredSkinnedFullbrightProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		success = gDeferredSkinnedFullbrightProgram.createShader(NULL, NULL); +	} + +	if (success) +	{ +		gDeferredSkinnedFullbrightShinyProgram.mName = "Skinned Fullbright Shiny Shader"; +		gDeferredSkinnedFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; +		gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasGamma = true; +		gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasTransport = true; +		gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasObjectSkinning = true; +		gDeferredSkinnedFullbrightShinyProgram.mFeatures.disableTextureIndex = true; +		gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.clear(); +		gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredSkinnedFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; +		success = gDeferredSkinnedFullbrightShinyProgram.createShader(NULL, &mShinyUniforms); +	} + +	if (success) +	{  		gDeferredEmissiveProgram.mName = "Deferred Emissive Shader";  		gDeferredEmissiveProgram.mFeatures.calculatesAtmospherics = true;  		gDeferredEmissiveProgram.mFeatures.hasGamma = true; @@ -1424,6 +1600,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSoftenProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		SINGLE_FP_PERMUTATION(gDeferredSoftenProgram); +  		if (gSavedSettings.getBOOL("RenderDeferredSSAO"))  		{ //if using SSAO, take screen space light map into account as if shadows are enabled  			gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2); @@ -1439,6 +1617,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");  		success = gDeferredShadowProgram.createShader(NULL, NULL);  	} @@ -1448,6 +1627,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredShadowCubeProgram.mShaderFiles.clear();  		gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");  		gDeferredShadowCubeProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredShadowCubeProgram.createShader(NULL, NULL);  	} @@ -1459,6 +1639,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredShadowAlphaMaskProgram.mShaderFiles.clear();  		gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");  		gDeferredShadowAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL);  	} @@ -1470,6 +1651,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAvatarShadowProgram.mShaderFiles.clear();  		gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredAvatarShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");  		gDeferredAvatarShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredAvatarShadowProgram.createShader(NULL, &mAvatarUniforms);  	} @@ -1481,6 +1663,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAttachmentShadowProgram.mShaderFiles.clear();  		gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredAttachmentShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");  		gDeferredAttachmentShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredAttachmentShadowProgram.createShader(NULL, NULL);  	} @@ -1519,8 +1702,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true;  		gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true;  		gDeferredAvatarAlphaProgram.mShaderFiles.clear(); -		gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaNoColorV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedNoColorF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredAvatarAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1"); +		gDeferredAvatarAlphaProgram.addPermutation("IS_AVATAR_SKIN", "1"); +		gDeferredAvatarAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");  		gDeferredAvatarAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredAvatarAlphaProgram.createShader(NULL, &mAvatarUniforms); @@ -1531,6 +1717,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ +		gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process"; +		gDeferredPostGammaCorrectProgram.mShaderFiles.clear(); +		gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredPostGammaCorrectProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		success = gDeferredPostGammaCorrectProgram.createShader(NULL, NULL); +	} + +	if (success) +	{  		gFXAAProgram.mName = "FXAA Shader";  		gFXAAProgram.mShaderFiles.clear();  		gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); @@ -2310,6 +2506,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectSimpleProgram.mFeatures.hasAtmospherics = true;  			gSkinnedObjectSimpleProgram.mFeatures.hasLighting = true;  			gSkinnedObjectSimpleProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectSimpleProgram.mFeatures.hasAlphaMask = true;  			gSkinnedObjectSimpleProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectSimpleProgram.mShaderFiles.clear();  			gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); @@ -2326,6 +2523,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightProgram.mFeatures.hasTransport = true;  			gSkinnedObjectFullbrightProgram.mFeatures.isFullbright = true;  			gSkinnedObjectFullbrightProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectFullbrightProgram.mFeatures.hasAlphaMask = true;			  			gSkinnedObjectFullbrightProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectFullbrightProgram.mShaderFiles.clear();  			gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); @@ -2376,6 +2574,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightShinyProgram.mFeatures.isShiny = true;  			gSkinnedObjectFullbrightShinyProgram.mFeatures.isFullbright = true;  			gSkinnedObjectFullbrightShinyProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectFullbrightShinyProgram.mFeatures.hasAlphaMask = true;  			gSkinnedObjectFullbrightShinyProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.clear();  			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); @@ -2392,6 +2591,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectShinySimpleProgram.mFeatures.hasGamma = true;  			gSkinnedObjectShinySimpleProgram.mFeatures.hasAtmospherics = true;  			gSkinnedObjectShinySimpleProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectShinySimpleProgram.mFeatures.hasAlphaMask = true;  			gSkinnedObjectShinySimpleProgram.mFeatures.isShiny = true;  			gSkinnedObjectShinySimpleProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectShinySimpleProgram.mShaderFiles.clear(); @@ -2429,6 +2629,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightWaterProgram.mFeatures.hasTransport = true;  			gSkinnedObjectFullbrightWaterProgram.mFeatures.isFullbright = true;  			gSkinnedObjectFullbrightWaterProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectFullbrightWaterProgram.mFeatures.hasAlphaMask = true;  			gSkinnedObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true;  			gSkinnedObjectFullbrightWaterProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; @@ -2448,6 +2649,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isShiny = true;  			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true;  			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasAlphaMask = true;  			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true;  			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.disableTextureIndex = true;  			gSkinnedObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; @@ -2466,6 +2668,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasGamma = true;  			gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasAtmospherics = true;  			gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasObjectSkinning = true; +			gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasAlphaMask = true;  			gSkinnedObjectShinySimpleWaterProgram.mFeatures.isShiny = true;  			gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasWaterFog = true;  			gSkinnedObjectShinySimpleWaterProgram.mFeatures.disableTextureIndex = true; @@ -2606,6 +2809,26 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  	if (success)  	{ +		gHighlightNormalProgram.mName = "Highlight Normals Shader"; +		gHighlightNormalProgram.mShaderFiles.clear(); +		gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER_ARB)); +		gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gHighlightNormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];		 +		success = gHighlightNormalProgram.createShader(NULL, NULL); +	} + +	if (success) +	{ +		gHighlightSpecularProgram.mName = "Highlight Spec Shader"; +		gHighlightSpecularProgram.mShaderFiles.clear(); +		gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER_ARB)); +		gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gHighlightSpecularProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];		 +		success = gHighlightSpecularProgram.createShader(NULL, NULL); +	} + +	if (success) +	{  		gUIProgram.mName = "UI Shader";  		gUIProgram.mShaderFiles.clear();  		gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER_ARB)); @@ -2881,7 +3104,7 @@ BOOL LLViewerShaderMgr::loadTransformShaders()  		gTransformTexCoordProgram.unload();  		gTransformNormalProgram.unload();  		gTransformColorProgram.unload(); -		gTransformBinormalProgram.unload(); +		gTransformTangentProgram.unload();  		return TRUE;  	} @@ -2944,16 +3167,16 @@ BOOL LLViewerShaderMgr::loadTransformShaders()  	if (success)  	{ -		gTransformBinormalProgram.mName = "Binormal Transform Shader"; -		gTransformBinormalProgram.mShaderFiles.clear(); -		gTransformBinormalProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB)); -		gTransformBinormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM]; +		gTransformTangentProgram.mName = "Binormal Transform Shader"; +		gTransformTangentProgram.mShaderFiles.clear(); +		gTransformTangentProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB)); +		gTransformTangentProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];  		const char* varyings[] = { -			"binormal_out", +			"tangent_out",  		}; -		success = gTransformBinormalProgram.createShader(NULL, NULL, 1, varyings); +		success = gTransformTangentProgram.createShader(NULL, NULL, 1, varyings);  	} diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 24f9111d3d..7fb90b26c6 100755 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -28,6 +28,7 @@  #define LL_VIEWER_SHADER_MGR_H  #include "llshadermgr.h" +#include "llmaterial.h"  class LLViewerShaderMgr: public LLShaderMgr  { @@ -216,7 +217,7 @@ extern LLGLSLShader			gTransformPositionProgram;  extern LLGLSLShader			gTransformTexCoordProgram;  extern LLGLSLShader			gTransformNormalProgram;  extern LLGLSLShader			gTransformColorProgram; -extern LLGLSLShader			gTransformBinormalProgram; +extern LLGLSLShader			gTransformTangentProgram; @@ -304,6 +305,9 @@ extern LLGLSLShader			gGlowExtractProgram;  //interface shaders  extern LLGLSLShader			gHighlightProgram; +extern LLGLSLShader			gHighlightNormalProgram; +extern LLGLSLShader			gHighlightSpecularProgram; +  extern LLGLSLShader			gPathfindingProgram;  extern LLGLSLShader			gPathfindingNoNormalsProgram; @@ -353,6 +357,7 @@ extern LLGLSLShader			gDeferredCoFProgram;  extern LLGLSLShader			gDeferredDoFCombineProgram;  extern LLGLSLShader			gFXAAProgram;  extern LLGLSLShader			gDeferredPostNoDoFProgram; +extern LLGLSLShader			gDeferredPostGammaCorrectProgram;  extern LLGLSLShader			gDeferredAvatarShadowProgram;  extern LLGLSLShader			gDeferredAttachmentShadowProgram;  extern LLGLSLShader			gDeferredAlphaProgram; @@ -363,6 +368,13 @@ extern LLGLSLShader			gDeferredAvatarAlphaProgram;  extern LLGLSLShader			gDeferredWLSkyProgram;  extern LLGLSLShader			gDeferredWLCloudProgram;  extern LLGLSLShader			gDeferredStarProgram; +extern LLGLSLShader			gDeferredFullbrightShinyProgram; +extern LLGLSLShader			gDeferredSkinnedFullbrightShinyProgram; +extern LLGLSLShader			gDeferredSkinnedFullbrightProgram;  extern LLGLSLShader			gNormalMapGenProgram; + +// Deferred materials shaders +extern LLGLSLShader			gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; +  #endif diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 7ddee48b38..3d4c75cec3 100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -89,17 +89,17 @@ LLTrace::CountStatHandle<>	FPS("framesrendered"),  							TEX_BAKES("texbakes"),  							TEX_REBAKES("texrebakes"),  							NUM_NEW_OBJECTS("numnewobjectsstat"); -LLTrace::CountStatHandle<LLTrace::Kibibits>	KBIT("kbitstat"), -											LAYERS_KBIT("layerskbitstat"), -											OBJECT_KBIT("objectkbitstat"), -											ASSET_KBIT("assetkbitstat"), -											TEXTURE_KBIT("texturekbitstat"), -											ACTUAL_IN_KBIT("actualinkbitstat"), -											ACTUAL_OUT_KBIT("actualoutkbitstat"); - -LLTrace::CountStatHandle<LLTrace::Seconds>	SIM_20_FPS_TIME("sim20fpstime", "Seconds with sim FPS below 20"), -											SIM_PHYSICS_20_FPS_TIME("simphysics20fpstime", "Seconds with physics FPS below 20"), -											LOSS_5_PERCENT_TIME("loss5percenttime", "Seconds with packet loss > 5%"); +LLTrace::CountStatHandle<LLUnit<F64, LLUnits::Kibibits> >	KBIT("kbitstat"), +															LAYERS_KBIT("layerskbitstat"), +															OBJECT_KBIT("objectkbitstat"), +															ASSET_KBIT("assetkbitstat"), +															TEXTURE_KBIT("texturekbitstat"), +															ACTUAL_IN_KBIT("actualinkbitstat"), +															ACTUAL_OUT_KBIT("actualoutkbitstat"); + +LLTrace::CountStatHandle<LLUnit<F64, LLUnits::Seconds> >	SIM_20_FPS_TIME("sim20fpstime", "Seconds with sim FPS below 20"), +															SIM_PHYSICS_20_FPS_TIME("simphysics20fpstime", "Seconds with physics FPS below 20"), +															LOSS_5_PERCENT_TIME("loss5percenttime", "Seconds with packet loss > 5%");  SimMeasurement<>			SIM_TIME_DILATION("simtimedilation", "", LL_SIM_STAT_TIME_DILATION),  							SIM_FPS("simfps", "", LL_SIM_STAT_FPS), @@ -141,15 +141,15 @@ LLTrace::SampleStatHandle<>	FPS_SAMPLE("fpssample"),  static LLTrace::SampleStatHandle<S64> CHAT_BUBBLES("chatbubbles", "Chat Bubbles Enabled"); -LLTrace::SampleStatHandle<LLTrace::Bytes>	GL_TEX_MEM("gltexmemstat"), -											GL_BOUND_MEM("glboundmemstat"), -											RAW_MEM("rawmemstat"), -											FORMATTED_MEM("formattedmemstat"), -											DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"), -											MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting"); +LLTrace::SampleStatHandle<LLUnit<F64, LLUnits::Megabytes> >	GL_TEX_MEM("gltexmemstat"), +															GL_BOUND_MEM("glboundmemstat"), +															RAW_MEM("rawmemstat"), +															FORMATTED_MEM("formattedmemstat"); +LLTrace::SampleStatHandle<LLUnit<F64, LLUnits::Kibibytes> >	DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"), +															MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting"); -SimMeasurement<LLTrace::Milliseconds>	SIM_FRAME_TIME("simframemsec", "", LL_SIM_STAT_FRAMEMS), +SimMeasurement<LLUnit<F64, LLUnits::Milliseconds> >	SIM_FRAME_TIME("simframemsec", "", LL_SIM_STAT_FRAMEMS),  										SIM_NET_TIME("simnetmsec", "", LL_SIM_STAT_NETMS),  										SIM_OTHER_TIME("simsimothermsec", "", LL_SIM_STAT_SIMOTHERMS),  										SIM_PHYSICS_TIME("simsimphysicsmsec", "", LL_SIM_STAT_SIMPHYSICSMS), @@ -164,18 +164,18 @@ SimMeasurement<LLTrace::Milliseconds>	SIM_FRAME_TIME("simframemsec", "", LL_SIM_  										SIM_SLEEP_TIME("simsleepmsec", "", LL_SIM_STAT_SIMSLEEPTIME),  										SIM_PUMP_IO_TIME("simpumpiomsec", "", LL_SIM_STAT_IOPUMPTIME); -SimMeasurement<LLTrace::Bytes>	SIM_UNACKED_BYTES("simtotalunackedbytes", "", LL_SIM_STAT_TOTAL_UNACKED_BYTES), -								SIM_PHYSICS_MEM("physicsmemoryallocated", "", LL_SIM_STAT_SIMPHYSICSMEMORY); +SimMeasurement<LLUnit<F64, LLUnits::Bytes> >	SIM_UNACKED_BYTES("simtotalunackedbytes", "", LL_SIM_STAT_TOTAL_UNACKED_BYTES), +												SIM_PHYSICS_MEM("physicsmemoryallocated", "", LL_SIM_STAT_SIMPHYSICSMEMORY); -LLTrace::SampleStatHandle<LLTrace::Milliseconds>	FRAMETIME_JITTER("frametimejitter", "Average delta between successive frame times"), +LLTrace::SampleStatHandle<LLUnit<F64, LLUnits::Milliseconds> >	FRAMETIME_JITTER("frametimejitter", "Average delta between successive frame times"),  													FRAMETIME_SLEW("frametimeslew", "Average delta between frame time and mean"),  													SIM_PING("simpingstat"); -LLTrace::EventStatHandle<LLTrace::Meters> AGENT_POSITION_SNAP("agentpositionsnap", "agent position corrections"); +LLTrace::EventStatHandle<LLUnit<F64, LLUnits::Meters> > AGENT_POSITION_SNAP("agentpositionsnap", "agent position corrections");  LLTrace::EventStatHandle<>	LOADING_WEARABLES_LONG_DELAY("loadingwearableslongdelay", "Wearables took too long to load"); -LLTrace::EventStatHandle<LLTrace::Milliseconds>	REGION_CROSSING_TIME("regioncrossingtime", "CROSSING_AVG"), +LLTrace::EventStatHandle<LLUnit<F64, LLUnits::Milliseconds> >	REGION_CROSSING_TIME("regioncrossingtime", "CROSSING_AVG"),  												FRAME_STACKTIME("framestacktime", "FRAME_SECS"),  												UPDATE_STACKTIME("updatestacktime", "UPDATE_SECS"),  												NETWORK_STACKTIME("networkstacktime", "NETWORK_SECS"), @@ -183,12 +183,12 @@ LLTrace::EventStatHandle<LLTrace::Milliseconds>	REGION_CROSSING_TIME("regioncros  												REBUILD_STACKTIME("rebuildstacktime", "REBUILD_SECS"),  												RENDER_STACKTIME("renderstacktime", "RENDER_SECS"); -LLTrace::EventStatHandle<LLTrace::Seconds>	AVATAR_EDIT_TIME("avataredittime", "Seconds in Edit Appearance"), -											TOOLBOX_TIME("toolboxtime", "Seconds using Toolbox"), -											MOUSELOOK_TIME("mouselooktime", "Seconds in Mouselook"), -											FPS_10_TIME("fps10time", "Seconds below 10 FPS"), -											FPS_8_TIME("fps8time", "Seconds below 8 FPS"), -											FPS_2_TIME("fps2time", "Seconds below 2 FPS"); +LLTrace::EventStatHandle<LLUnit<F64, LLUnits::Seconds> >	AVATAR_EDIT_TIME("avataredittime", "Seconds in Edit Appearance"), +															TOOLBOX_TIME("toolboxtime", "Seconds using Toolbox"), +															MOUSELOOK_TIME("mouselooktime", "Seconds in Mouselook"), +															FPS_10_TIME("fps10time", "Seconds below 10 FPS"), +															FPS_8_TIME("fps8time", "Seconds below 8 FPS"), +															FPS_2_TIME("fps2time", "Seconds below 2 FPS");  } @@ -211,7 +211,7 @@ void LLViewerStats::resetStats()  void LLViewerStats::updateFrameStats(const F64 time_diff)  { -	LLTrace::Seconds time_diff_seconds(time_diff); +	LLUnit<F64, LLUnits::Seconds> time_diff_seconds(time_diff);  	if (getRecording().getLastValue(LLStatViewer::PACKETS_LOST_PERCENT) > 5.0)  	{  		add(LLStatViewer::LOSS_5_PERCENT_TIME, time_diff_seconds); @@ -249,15 +249,15 @@ void LLViewerStats::updateFrameStats(const F64 time_diff)  		add(LLStatViewer::FRAMETIME_DOUBLED, time_diff >= 2.0 * mLastTimeDiff ? 1 : 0);  		// old stats that were never really used -		sample(LLStatViewer::FRAMETIME_JITTER, LLTrace::Milliseconds(mLastTimeDiff - time_diff)); +		sample(LLStatViewer::FRAMETIME_JITTER, LLUnit<F64, LLUnits::Milliseconds> (mLastTimeDiff - time_diff));  		F32 average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount; -		sample(LLStatViewer::FRAMETIME_SLEW, LLTrace::Milliseconds(average_frametime - time_diff)); +		sample(LLStatViewer::FRAMETIME_SLEW, LLUnit<F64, LLUnits::Milliseconds> (average_frametime - time_diff));  		F32 max_bandwidth = gViewerThrottle.getMaxBandwidth();  		F32 delta_bandwidth = gViewerThrottle.getCurrentBandwidth() - max_bandwidth; -		sample(LLStatViewer::DELTA_BANDWIDTH, LLTrace::Bits(delta_bandwidth)); -		sample(LLStatViewer::MAX_BANDWIDTH, LLTrace::Bits(max_bandwidth)); +		sample(LLStatViewer::DELTA_BANDWIDTH, LLUnit<F64, LLUnits::Bits>(delta_bandwidth)); +		sample(LLStatViewer::MAX_BANDWIDTH, LLUnit<F64, LLUnits::Bits>(max_bandwidth));  	}  	mLastTimeDiff = time_diff; @@ -347,13 +347,13 @@ void update_statistics()  	LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());  	if (cdp)  	{ -		sample(LLStatViewer::SIM_PING, LLTrace::Milliseconds(cdp->getPingDelay())); +		sample(LLStatViewer::SIM_PING, LLUnit<F64, LLUnits::Milliseconds> (cdp->getPingDelay()));  		gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1);  		gSimPingCount++;  	}  	else  	{ -		sample(LLStatViewer::SIM_PING, LLTrace::Seconds(10)); +		sample(LLStatViewer::SIM_PING, LLUnit<F64, LLUnits::Seconds>(10));  	}  	if (LLViewerStats::instance().getRecording().getSum(LLStatViewer::FPS)) @@ -363,10 +363,10 @@ void update_statistics()  	add(LLStatViewer::FPS, 1);  	F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits()); -	add(LLStatViewer::LAYERS_KBIT, LLTrace::Bits(layer_bits)); +	add(LLStatViewer::LAYERS_KBIT, LLUnit<F64, LLUnits::Bits>(layer_bits));  	add(LLStatViewer::OBJECT_KBIT, gObjectData);  	sample(LLStatViewer::PENDING_VFS_OPERATIONS, LLVFile::getVFSThread()->getPending()); -	add(LLStatViewer::ASSET_KBIT, LLTrace::Bits(gTransferManager.getTransferBitsIn(LLTCT_ASSET))); +	add(LLStatViewer::ASSET_KBIT, LLUnit<F64, LLUnits::Bits>(gTransferManager.getTransferBitsIn(LLTCT_ASSET)));  	gTransferManager.resetTransferBitsIn(LLTCT_ASSET);  	if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) @@ -403,7 +403,7 @@ void update_statistics()  		static LLFrameTimer texture_stats_timer;  		if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq)  		{ -			gTotalTextureData = LLTrace::Bytes(LLViewerStats::instance().getRecording().getSum(LLStatViewer::TEXTURE_KBIT)); +			gTotalTextureData = LLUnit<F64, LLUnits::Bytes>(LLViewerStats::instance().getRecording().getSum(LLStatViewer::TEXTURE_KBIT));  			texture_stats_timer.reset();  		}  	} @@ -552,9 +552,9 @@ void send_stats()  	LLSD &download = body["downloads"]; -	download["world_kbytes"] = LLTrace::Kibibytes(gTotalWorldData).value(); -	download["object_kbytes"] = LLTrace::Kibibytes(gTotalObjectData).value(); -	download["texture_kbytes"] = LLTrace::Kibibytes(gTotalTextureData).value(); +	download["world_kbytes"] = LLUnit<F64, LLUnits::Kibibytes>(gTotalWorldData).value(); +	download["object_kbytes"] = LLUnit<F64, LLUnits::Kibibytes>(gTotalObjectData).value(); +	download["texture_kbytes"] = LLUnit<F64, LLUnits::Kibibytes>(gTotalTextureData).value();  	download["mesh_kbytes"] = LLMeshRepository::sBytesReceived/1024.0;  	LLSD &in = body["stats"]["net"]["in"]; diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 4e48a61264..879f0067b9 100755 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -94,17 +94,17 @@ extern LLTrace::CountStatHandle<>			FPS,  											NUM_NEW_OBJECTS; -extern LLTrace::CountStatHandle<LLTrace::Kibibits>	KBIT, -											LAYERS_KBIT, -											OBJECT_KBIT, -											ASSET_KBIT, -											TEXTURE_KBIT, -											ACTUAL_IN_KBIT, -											ACTUAL_OUT_KBIT; - -extern LLTrace::CountStatHandle<LLTrace::Seconds>		SIM_20_FPS_TIME, -														SIM_PHYSICS_20_FPS_TIME, -														LOSS_5_PERCENT_TIME; +extern LLTrace::CountStatHandle<LLUnit<F64, LLUnits::Kibibits> >	KBIT, +																	LAYERS_KBIT, +																	OBJECT_KBIT, +																	ASSET_KBIT, +																	TEXTURE_KBIT, +																	ACTUAL_IN_KBIT, +																	ACTUAL_OUT_KBIT; + +extern LLTrace::CountStatHandle<LLUnit<F64, LLUnits::Seconds> >		SIM_20_FPS_TIME, +																	SIM_PHYSICS_20_FPS_TIME, +																	LOSS_5_PERCENT_TIME;  extern SimMeasurement<>						SIM_TIME_DILATION,  											SIM_FPS, @@ -144,41 +144,40 @@ extern LLTrace::SampleStatHandle<>		FPS_SAMPLE,  										WINDOW_WIDTH,  										WINDOW_HEIGHT; -extern LLTrace::SampleStatHandle<LLTrace::Bytes>	DELTA_BANDWIDTH, -													MAX_BANDWIDTH, -													GL_TEX_MEM, -													GL_BOUND_MEM, -													RAW_MEM, -													FORMATTED_MEM; - -extern SimMeasurement<LLTrace::Milliseconds>	SIM_FRAME_TIME, -												SIM_NET_TIME, -												SIM_OTHER_TIME, -												SIM_PHYSICS_TIME, -												SIM_PHYSICS_STEP_TIME, -												SIM_PHYSICS_SHAPE_UPDATE_TIME, -												SIM_PHYSICS_OTHER_TIME, -												SIM_AI_TIME, -												SIM_AGENTS_TIME, -												SIM_IMAGES_TIME, -												SIM_SCRIPTS_TIME, -												SIM_SPARE_TIME, -												SIM_SLEEP_TIME, -												SIM_PUMP_IO_TIME; - -extern SimMeasurement<LLTrace::Bytes>			SIM_UNACKED_BYTES, -												SIM_PHYSICS_MEM; - - -extern LLTrace::SampleStatHandle<LLTrace::Milliseconds>	FRAMETIME_JITTER, -														FRAMETIME_SLEW, -														SIM_PING; - -extern LLTrace::EventStatHandle<LLTrace::Meters> AGENT_POSITION_SNAP; +extern LLTrace::SampleStatHandle<LLUnit<F64, LLUnits::Megabytes> >	GL_TEX_MEM, +																	GL_BOUND_MEM, +																	RAW_MEM, +																	FORMATTED_MEM; +extern LLTrace::SampleStatHandle<LLUnit<F64, LLUnits::Kibibytes> >	DELTA_BANDWIDTH, +																	MAX_BANDWIDTH; +extern SimMeasurement<LLUnit<F64, LLUnits::Milliseconds> >	SIM_FRAME_TIME, +															SIM_NET_TIME, +															SIM_OTHER_TIME, +															SIM_PHYSICS_TIME, +															SIM_PHYSICS_STEP_TIME, +															SIM_PHYSICS_SHAPE_UPDATE_TIME, +															SIM_PHYSICS_OTHER_TIME, +															SIM_AI_TIME, +															SIM_AGENTS_TIME, +															SIM_IMAGES_TIME, +															SIM_SCRIPTS_TIME, +															SIM_SPARE_TIME, +															SIM_SLEEP_TIME, +															SIM_PUMP_IO_TIME; + +extern SimMeasurement<LLUnit<F64, LLUnits::Bytes> >	SIM_UNACKED_BYTES, +													SIM_PHYSICS_MEM; + + +extern LLTrace::SampleStatHandle<LLUnit<F64, LLUnits::Milliseconds> >	FRAMETIME_JITTER, +																		FRAMETIME_SLEW, +																		SIM_PING; + +extern LLTrace::EventStatHandle<LLUnit<F64, LLUnits::Meters> > AGENT_POSITION_SNAP;  extern LLTrace::EventStatHandle<>	LOADING_WEARABLES_LONG_DELAY; -extern LLTrace::EventStatHandle<LLTrace::Milliseconds>	REGION_CROSSING_TIME, +extern LLTrace::EventStatHandle<LLUnit<F64, LLUnits::Milliseconds> >	REGION_CROSSING_TIME,  														FRAME_STACKTIME,  														UPDATE_STACKTIME,  														NETWORK_STACKTIME, @@ -186,12 +185,12 @@ extern LLTrace::EventStatHandle<LLTrace::Milliseconds>	REGION_CROSSING_TIME,  														REBUILD_STACKTIME,  														RENDER_STACKTIME; -extern LLTrace::EventStatHandle<LLTrace::Seconds>	AVATAR_EDIT_TIME, -													TOOLBOX_TIME, -													MOUSELOOK_TIME, -													FPS_10_TIME, -													FPS_8_TIME, -													FPS_2_TIME; +extern LLTrace::EventStatHandle<LLUnit<F64, LLUnits::Seconds> >	AVATAR_EDIT_TIME, +																TOOLBOX_TIME, +																MOUSELOOK_TIME, +																FPS_10_TIME, +																FPS_8_TIME, +																FPS_2_TIME;  } diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp index acd8f6a29c..0e78bdc04c 100755 --- a/indra/newview/llviewerstatsrecorder.cpp +++ b/indra/newview/llviewerstatsrecorder.cpp @@ -166,6 +166,7 @@ void LLViewerStatsRecorder::recordRequestCacheMissesEvent(S32 count)  void LLViewerStatsRecorder::writeToLog( F32 interval )  { +	size_t data_size = 0;  	F64 delta_time = LLTimer::getTotalSeconds() - mLastSnapshotTime;  	S32 total_objects = mObjectCacheHitCount + mObjectCacheMissCrcCount + mObjectCacheMissFullCount + mObjectFullUpdates + mObjectTerseUpdates + mObjectCacheMissRequests + mObjectCacheMissResponses + mObjectCacheUpdateDupes + mObjectCacheUpdateChanges + mObjectCacheUpdateAdds + mObjectCacheUpdateReplacements + mObjectUpdateFailures; @@ -187,7 +188,6 @@ void LLViewerStatsRecorder::writeToLog( F32 interval )  		<< mObjectUpdateFailures << " update failures"  		<< llendl; -	U32 data_size;  	if (mObjectCacheFile == NULL)  	{  		mStartTime = LLTimer::getTotalSeconds(); @@ -224,15 +224,15 @@ void LLViewerStatsRecorder::writeToLog( F32 interval )  			}  		}  		else -	{ +		{  			//llwarns << "Couldn't open " << STATS_FILE_NAME << " for logging." << llendl;  			return;  		}  	} -		std::ostringstream data_msg; +	std::ostringstream data_msg; -		data_msg << getTimeSinceStart() +	data_msg << getTimeSinceStart()  		<< "\t " << mObjectCacheHitCount  		<< "\t" << mObjectCacheMissFullCount  		<< "\t" << mObjectCacheMissCrcCount @@ -255,9 +255,9 @@ void LLViewerStatsRecorder::writeToLog( F32 interval )  		<< "\n";  	data_size = data_msg.str().size(); -	if (fwrite(data_msg.str().c_str(), 1, data_size, mObjectCacheFile ) != data_size) +	if ( data_size != fwrite(data_msg.str().c_str(), 1, data_size, mObjectCacheFile ))  	{ -		llwarns << "failed to write full stats to " << STATS_FILE_NAME << llendl; +				llwarns << "Unable to write complete column data to " << STATS_FILE_NAME << llendl;  	}  	clearStats(); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index f468df0674..2872c277b1 100755 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -55,8 +55,6 @@  #include "llappviewer.h"  #include "llface.h"  #include "llviewercamera.h" -#include "lltextureatlas.h" -#include "lltextureatlasmanager.h"  #include "lltextureentry.h"  #include "lltexturemanagerbridge.h"  #include "llmediaentry.h" @@ -78,6 +76,7 @@ LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sMissingAssetImagep =  LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sWhiteImagep = NULL;  LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultImagep = NULL;  LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sSmokeImagep = NULL; +LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sFlatNormalImagep = NULL;  LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap ;  LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL ;  const std::string sTesterName("TextureTester"); @@ -103,7 +102,6 @@ S32 LLViewerTexture::sMinLargeImageSize = 65536 ; //256 * 256.  S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA ;  BOOL LLViewerTexture::sFreezeImageScalingDown = FALSE ;  F32 LLViewerTexture::sCurrentTime = 0.0f ; -BOOL LLViewerTexture::sUseTextureAtlas        = FALSE ;  F32  LLViewerTexture::sTexelPixelRatio = 1.0f;  LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF; @@ -282,7 +280,7 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(  }  LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile( -	                                               const std::string& filename,												    +	                                               const std::string& filename,  												   FTType f_type,  												   BOOL usemipmaps,  												   LLViewerTexture::EBoostLevel boost_priority, @@ -295,7 +293,7 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(  }  //static  -LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url,									  +LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url,  									 FTType f_type,  									 BOOL usemipmaps,  									 LLViewerTexture::EBoostLevel boost_priority, @@ -402,7 +400,7 @@ void LLViewerTextureManager::init()  	LLViewerTexture::sCheckerBoardImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE);  	LLViewerTexture::initClass() ; - +	  	// Create a texture manager bridge.  	gTextureManagerBridgep = new LLViewerTextureManagerBridge; @@ -430,6 +428,7 @@ void LLViewerTextureManager::cleanup()  	LLViewerFetchedTexture::sSmokeImagep = NULL;  	LLViewerFetchedTexture::sMissingAssetImagep = NULL;  	LLViewerFetchedTexture::sWhiteImagep = NULL; +	LLViewerFetchedTexture::sFlatNormalImagep = NULL;  	LLViewerMediaTexture::cleanUpClass() ;	  } @@ -570,7 +569,6 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity  		}  	}  	sDesiredDiscardBias = llclamp(sDesiredDiscardBias, desired_discard_bias_min, desired_discard_bias_max); -	LLViewerTexture::sUseTextureAtlas = gSavedSettings.getBOOL("EnableTextureAtlas") ;  	F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ;  	F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed(); @@ -637,9 +635,14 @@ void LLViewerTexture::init(bool firstinit)  	mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval ;  	mAdditionalDecodePriority = 0.f ;	  	mParcelMedia = NULL ; -	mNumFaces = 0 ; +	  	mNumVolumes = 0; -	mFaceList.clear() ; +	mFaceList[LLRender::DIFFUSE_MAP].clear() ; +	mFaceList[LLRender::NORMAL_MAP].clear() ; +	mFaceList[LLRender::SPECULAR_MAP].clear() ; +	mNumFaces[LLRender::DIFFUSE_MAP] =  +	mNumFaces[LLRender::NORMAL_MAP] =  +	mNumFaces[LLRender::SPECULAR_MAP] = 0 ;  	mVolumeList.clear();  } @@ -651,7 +654,9 @@ S8 LLViewerTexture::getType() const  void LLViewerTexture::cleanup()  { -	mFaceList.clear() ; +	mFaceList[LLRender::DIFFUSE_MAP].clear() ; +	mFaceList[LLRender::NORMAL_MAP].clear() ; +	mFaceList[LLRender::SPECULAR_MAP].clear() ;  	mVolumeList.clear();  } @@ -791,38 +796,57 @@ void LLViewerTexture::setKnownDrawSize(S32 width, S32 height)  }  //virtual -void LLViewerTexture::addFace(LLFace* facep)  +void LLViewerTexture::addFace(U32 ch, LLFace* facep)   { -	if(mNumFaces >= mFaceList.size()) +	llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); + +	if(mNumFaces[ch] >= mFaceList[ch].size())  	{ -		mFaceList.resize(2 * mNumFaces + 1) ;		 +		mFaceList[ch].resize(2 * mNumFaces[ch] + 1) ;		  	} -	mFaceList[mNumFaces] = facep ; -	facep->setIndexInTex(mNumFaces) ; -	mNumFaces++ ; +	mFaceList[ch][mNumFaces[ch]] = facep ; +	facep->setIndexInTex(ch, mNumFaces[ch]) ; +	mNumFaces[ch]++ ;  	mLastFaceListUpdateTimer.reset() ;  }  //virtual -void LLViewerTexture::removeFace(LLFace* facep)  +void LLViewerTexture::removeFace(U32 ch, LLFace* facep)   { -	if(mNumFaces > 1) +	llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); + +	if(mNumFaces[ch] > 1)  	{ -		S32 index = facep->getIndexInTex() ;  -		mFaceList[index] = mFaceList[--mNumFaces] ; -		mFaceList[index]->setIndexInTex(index) ; +		S32 index = facep->getIndexInTex(ch) ;  +		llassert(index < mFaceList[ch].size()); +		llassert(index < mNumFaces[ch]); +		mFaceList[ch][index] = mFaceList[ch][--mNumFaces[ch]] ; +		mFaceList[ch][index]->setIndexInTex(ch, index) ;  	}  	else   	{ -		mFaceList.clear() ; -		mNumFaces = 0 ; +		mFaceList[ch].clear() ; +		mNumFaces[ch] = 0 ;  	}  	mLastFaceListUpdateTimer.reset() ;  } -S32 LLViewerTexture::getNumFaces() const +S32 LLViewerTexture::getTotalNumFaces() const +{ +	S32 ret = 0; + +	for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) +	{ +		ret += mNumFaces[i]; +	} + +	return ret; +} + +S32 LLViewerTexture::getNumFaces(U32 ch) const  { -	return mNumFaces ; +	llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); +	return mNumFaces[ch];  } @@ -845,6 +869,8 @@ void LLViewerTexture::removeVolume(LLVOVolume* volumep)  	if(mNumVolumes > 1)  	{  		S32 index = volumep->getIndexInTex() ;  +		llassert(index < mVolumeList.size()); +		llassert(index < mNumVolumes);  		mVolumeList[index] = mVolumeList[--mNumVolumes] ;  		mVolumeList[index]->setIndexInTex(index) ;  	} @@ -866,18 +892,22 @@ void LLViewerTexture::reorganizeFaceList()  	static const F32 MAX_WAIT_TIME = 20.f; // seconds  	static const U32 MAX_EXTRA_BUFFER_SIZE = 4 ; -	if(mNumFaces + MAX_EXTRA_BUFFER_SIZE > mFaceList.size()) +	if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)  	{  		return ;  	} -	if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME) +	for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) +	{ +		if(mNumFaces[i] + MAX_EXTRA_BUFFER_SIZE > mFaceList[i].size())  	{  		return ;  	} +		mFaceList[i].erase(mFaceList[i].begin() + mNumFaces[i], mFaceList[i].end()); +	} +	  	mLastFaceListUpdateTimer.reset() ; -	mFaceList.erase(mFaceList.begin() + mNumFaces, mFaceList.end());  }  void LLViewerTexture::reorganizeVolumeList() @@ -1206,7 +1236,7 @@ void LLViewerFetchedTexture::destroyTexture()  	{  		return ;  	} -	 +  	//LL_DEBUGS("Avatar") << mID << llendl;  	destroyGLTexture() ;  	mFullyLoaded = FALSE ; @@ -1223,9 +1253,14 @@ void LLViewerFetchedTexture::addToCreateTexture()  		mGLTexturep->setComponents(mComponents) ;  		force_update = true ; -		for(U32 i = 0 ; i < mNumFaces ; i++) +		for (U32 j = 0; j < LLRender::NUM_TEXTURE_CHANNELS; ++j) +		{ +			llassert(mNumFaces[j] <= mFaceList[j].size()); + +			for(U32 i = 0 ; i < mNumFaces[j]; i++)  		{ -			mFaceList[i]->dirtyTexture() ; +				mFaceList[j][i]->dirtyTexture() ; +			}  		}  		//discard the cached raw image and the saved raw image @@ -1369,11 +1404,8 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)  		return FALSE;  	} -	if(!(res = insertToAtlas())) -	{  		res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel); -		resetFaceAtlas() ; -	} +	  	setActive() ;  	if (!needsToSaveRawImage()) @@ -1662,9 +1694,13 @@ void LLViewerFetchedTexture::updateVirtualSize()  		addTextureStats(0.f, FALSE) ;//reset  	} -	for(U32 i = 0 ; i < mNumFaces ; i++) +	for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)  	{				 -		LLFace* facep = mFaceList[i] ; +		llassert(mNumFaces[ch] <= mFaceList[ch].size()); + +		for(U32 i = 0 ; i < mNumFaces[ch]; i++) +		{				 +			LLFace* facep = mFaceList[ch][i] ;  		if( facep )  		{  			LLDrawable* drawable = facep->getDrawable(); @@ -1683,7 +1719,7 @@ void LLViewerFetchedTexture::updateVirtualSize()  			}  		}  	} - +	}  	//reset whether or not a face was selected after 10 seconds  	const F32 SELECTION_RESET_TIME = 10.f; @@ -2775,190 +2811,6 @@ F32 LLViewerFetchedTexture::getElapsedLastReferencedSavedRawImageTime() const  {   	return sCurrentTime - mLastReferencedSavedRawImageTime ;  } -//---------------------------------------------------------------------------------------------- -//atlasing -//---------------------------------------------------------------------------------------------- -void LLViewerFetchedTexture::resetFaceAtlas() -{ -	//Nothing should be done here. -} - -//invalidate all atlas slots for this image. -void LLViewerFetchedTexture::invalidateAtlas(BOOL rebuild_geom) -{ -	for(U32 i = 0 ; i < mNumFaces ; i++) -	{ -		LLFace* facep = mFaceList[i] ; -		facep->removeAtlas() ; -		if(rebuild_geom && facep->getDrawable() && facep->getDrawable()->getSpatialGroup()) -		{ -			facep->getDrawable()->getSpatialGroup()->setState(LLSpatialGroup::GEOM_DIRTY); -		} -	} -} - -BOOL LLViewerFetchedTexture::insertToAtlas() -{ -	if(!LLViewerTexture::sUseTextureAtlas) -	{ -		return FALSE ; -	} -	if(getNumFaces() < 1) -	{ -		return FALSE ; -	}						 -	if(mGLTexturep->getDiscardLevelInAtlas() > 0 && mRawDiscardLevel >= mGLTexturep->getDiscardLevelInAtlas()) -	{ -		return FALSE ; -	} -	if(!LLTextureAtlasManager::getInstance()->canAddToAtlas(mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents(), mGLTexturep->getTexTarget())) -	{ -		return FALSE ; -	} - -	BOOL ret = TRUE ;//if ret is set to false, will generate a gl texture for this image. -	S32 raw_w = mRawImage->getWidth() ; -	S32 raw_h = mRawImage->getHeight() ; -	F32 xscale = 1.0f, yscale = 1.0f ; -	LLPointer<LLTextureAtlasSlot> slot_infop; -	LLTextureAtlasSlot* cur_slotp ;//no need to be smart pointer. -	LLSpatialGroup* groupp ; -	LLFace* facep; - -	//if the atlas slot pointers for some faces are null, process them later. -	ll_face_list_t waiting_list ; -	for(U32 i = 0 ; i < mNumFaces ; i++) -	{ -		{ -			facep = mFaceList[i] ;			 -			 -			//face can not use atlas. -			if(!facep->canUseAtlas()) -			{ -				if(facep->getAtlasInfo()) -				{ -					facep->removeAtlas() ;	 -				} -				ret = FALSE ; -				continue ; -			} - -			//the atlas slot is updated -			slot_infop = facep->getAtlasInfo() ; -			groupp = facep->getDrawable()->getSpatialGroup() ;	 - -			if(slot_infop)  -			{ -				if(slot_infop->getSpatialGroup() != groupp) -				{ -					if((cur_slotp = groupp->getCurUpdatingSlot(this))) //switch slot -					{ -						facep->setAtlasInfo(cur_slotp) ; -						facep->setAtlasInUse(TRUE) ; -						continue ; -					} -					else //do not forget to update slot_infop->getSpatialGroup(). -					{ -						LLSpatialGroup* gp = slot_infop->getSpatialGroup() ; -						gp->setCurUpdatingTime(gFrameCount) ; -						gp->setCurUpdatingTexture(this) ; -						gp->setCurUpdatingSlot(slot_infop) ; -					} -				} -				else //same group -				{ -					if(gFrameCount && slot_infop->getUpdatedTime() == gFrameCount)//slot is just updated -					{ -						facep->setAtlasInUse(TRUE) ; -						continue ; -					} -				} -			}				 -			else -			{ -				//if the slot is null, wait to process them later. -				waiting_list.push_back(facep) ; -				continue ; -			} -						 -			//---------- -			//insert to atlas -			if(!slot_infop->getAtlas()->insertSubTexture(mGLTexturep, mRawDiscardLevel, mRawImage, slot_infop->getSlotCol(), slot_infop->getSlotRow()))			 -			{ -				 -				//the texture does not qualify to add to atlas, do not bother to try for other faces. -				//invalidateAtlas(); -				return FALSE ; -			} -			 -			//update texture scale		 -			slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ; -			slot_infop->setTexCoordScale(xscale, yscale) ; -			slot_infop->setValid() ; -			slot_infop->setUpdatedTime(gFrameCount) ; -			 -			//update spatial group atlas info -			groupp->setCurUpdatingTime(gFrameCount) ; -			groupp->setCurUpdatingTexture(this) ; -			groupp->setCurUpdatingSlot(slot_infop) ; - -			//make the face to switch to the atlas. -			facep->setAtlasInUse(TRUE) ; -		} -	} - -	//process the waiting_list -	for(std::vector<LLFace*>::iterator iter = waiting_list.begin(); iter != waiting_list.end(); ++iter) -	{ -		facep = (LLFace*)*iter ;	 -		groupp = facep->getDrawable()->getSpatialGroup() ; - -		//check if this texture already inserted to atlas for this group -		if((cur_slotp = groupp->getCurUpdatingSlot(this))) -		{ -			facep->setAtlasInfo(cur_slotp) ; -			facep->setAtlasInUse(TRUE) ;		 -			continue ; -		} - -		//need to reserve a slot from atlas -		slot_infop = LLTextureAtlasManager::getInstance()->reserveAtlasSlot(llmax(mFullWidth, mFullHeight), getComponents(), groupp, this) ;	 - -		facep->setAtlasInfo(slot_infop) ; -		 -		groupp->setCurUpdatingTime(gFrameCount) ; -		groupp->setCurUpdatingTexture(this) ; -		groupp->setCurUpdatingSlot(slot_infop) ; - -		//slot allocation failed. -		if(!slot_infop || !slot_infop->getAtlas()) -		{			 -			ret = FALSE ; -			facep->setAtlasInUse(FALSE) ; -			continue ; -		} -				 -		//insert to atlas -		if(!slot_infop->getAtlas()->insertSubTexture(mGLTexturep, mRawDiscardLevel, mRawImage, slot_infop->getSlotCol(), slot_infop->getSlotRow())) -		{ -			//the texture does not qualify to add to atlas, do not bother to try for other faces. -			ret = FALSE ; -			//invalidateAtlas(); -			break ;  -		} -		 -		//update texture scale		 -		slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ; -		slot_infop->setTexCoordScale(xscale, yscale) ; -		slot_infop->setValid() ; -		slot_infop->setUpdatedTime(gFrameCount) ; - -		//make the face to switch to the atlas. -		facep->setAtlasInUse(TRUE) ; -	} -	 -	return ret ; -}  //----------------------------------------------------------------------------------------------  //end of LLViewerFetchedTexture @@ -3305,13 +3157,16 @@ BOOL LLViewerMediaTexture::findFaces()  	LLViewerTexture* tex = gTextureList.findImage(mID) ;  	if(tex) //this media is a parcel media for tex.  	{ -		const ll_face_list_t* face_list = tex->getFaceList() ; -		U32 end = tex->getNumFaces() ; +		for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) +		{ +			const ll_face_list_t* face_list = tex->getFaceList(ch) ; +			U32 end = tex->getNumFaces(ch) ;  		for(U32 i = 0 ; i < end ; i++)  		{  			mMediaFaceList.push_back((*face_list)[i]) ;  		}  	} +	}  	if(!mMediaImplp)  	{ @@ -3374,7 +3229,7 @@ void LLViewerMediaTexture::addMediaToFace(LLFace* facep)  		return ; //no need to add the face because the media is not in playing.  	} -	switchTexture(facep) ; +	switchTexture(LLRender::DIFFUSE_MAP, facep) ;  }  void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep)  @@ -3391,19 +3246,19 @@ void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep)  	}	  	mIsPlaying = FALSE ; //set to remove the media from the face. -	switchTexture(facep) ; +	switchTexture(LLRender::DIFFUSE_MAP, facep) ;  	mIsPlaying = TRUE ; //set the flag back. -	if(getNumFaces() < 1) //no face referencing to this media +	if(getTotalNumFaces() < 1) //no face referencing to this media  	{  		stopPlaying() ;  	}  }  //virtual  -void LLViewerMediaTexture::addFace(LLFace* facep)  +void LLViewerMediaTexture::addFace(U32 ch, LLFace* facep)   { -	LLViewerTexture::addFace(facep) ; +	LLViewerTexture::addFace(ch, facep) ;  	const LLTextureEntry* te = facep->getTextureEntry() ;  	if(te && te->getID().notNull()) @@ -3430,9 +3285,9 @@ void LLViewerMediaTexture::addFace(LLFace* facep)  }  //virtual  -void LLViewerMediaTexture::removeFace(LLFace* facep)  +void LLViewerMediaTexture::removeFace(U32 ch, LLFace* facep)   { -	LLViewerTexture::removeFace(facep) ; +	LLViewerTexture::removeFace(ch, facep) ;  	const LLTextureEntry* te = facep->getTextureEntry() ;  	if(te && te->getID().notNull()) @@ -3450,24 +3305,35 @@ void LLViewerMediaTexture::removeFace(LLFace* facep)  				}  			} +			std::vector<const LLTextureEntry*> te_list; +			 +			for (U32 ch = 0; ch < 3; ++ch) +			{  			//  			//we have some trouble here: the texture of the face is changed.  			//we need to find the former texture, and remove it from the list to avoid memory leaking. -			if(!mNumFaces) +				 +				llassert(mNumFaces[ch] <= mFaceList[ch].size()); + +				for(U32 j = 0 ; j < mNumFaces[ch] ; j++) +				{ +					te_list.push_back(mFaceList[ch][j]->getTextureEntry());//all textures are in use. +				} +			} + +			if (te_list.empty())  			{  				mTextureList.clear() ;  				return ;  			} -			S32 end = getNumFaces() ; -			std::vector<const LLTextureEntry*> te_list(end) ; -			S32 i = 0 ;			 -			for(U32 j = 0 ; j < mNumFaces ; j++) -			{ -				te_list[i++] = mFaceList[j]->getTextureEntry() ;//all textures are in use. -			} + +			S32 end = te_list.size(); +  			for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();  				iter != mTextureList.end(); ++iter)  			{ +				S32 i = 0; +  				for(i = 0 ; i < end ; i++)  				{  					if(te_list[i] && te_list[i]->getID() == (*iter)->getID())//the texture is in use. @@ -3512,7 +3378,7 @@ void LLViewerMediaTexture::stopPlaying()  	mIsPlaying = FALSE ;			  } -void LLViewerMediaTexture::switchTexture(LLFace* facep) +void LLViewerMediaTexture::switchTexture(U32 ch, LLFace* facep)  {  	if(facep)  	{ @@ -3528,7 +3394,7 @@ void LLViewerMediaTexture::switchTexture(LLFace* facep)  		if(mIsPlaying) //old textures switch to the media texture  		{ -			facep->switchTexture(this) ; +			facep->switchTexture(ch, this) ;  		}  		else //switch to old textures.  		{ @@ -3544,7 +3410,7 @@ void LLViewerMediaTexture::switchTexture(LLFace* facep)  				{  					tex = LLViewerFetchedTexture::sDefaultImagep ;  				} -				facep->switchTexture(tex) ; +				facep->switchTexture(ch, tex) ;  			}  		}  	} @@ -3583,14 +3449,17 @@ void LLViewerMediaTexture::setPlaying(BOOL playing)  		for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)  		{ -			switchTexture(*iter) ; +			switchTexture(LLRender::DIFFUSE_MAP, *iter) ;  		}  	}  	else //stop playing this media  	{ -		for(U32 i = mNumFaces ; i ; i--) +		U32 ch = LLRender::DIFFUSE_MAP; +		 +		llassert(mNumFaces[ch] <= mFaceList[ch].size()); +		for(U32 i = mNumFaces[ch] ; i ; i--)  		{ -			switchTexture(mFaceList[i - 1]) ; //current face could be removed in this function. +			switchTexture(ch, mFaceList[ch][i - 1]) ; //current face could be removed in this function.  		}  	}  	return ; @@ -3612,15 +3481,19 @@ F32 LLViewerMediaTexture::getMaxVirtualSize()  	if(mIsPlaying) //media is playing  	{ -		for(U32 i = 0 ; i < mNumFaces ; i++) +		for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)  		{ -			LLFace* facep = mFaceList[i] ; +			llassert(mNumFaces[ch] <= mFaceList[ch].size()); +			for(U32 i = 0 ; i < mNumFaces[ch] ; i++) +			{ +				LLFace* facep = mFaceList[ch][i] ;  			if(facep->getDrawable()->isRecentlyVisible())  			{  				addTextureStats(facep->getVirtualSize()) ;  			}  		}		  	} +	}  	else //media is not in playing  	{  		findFaces() ; diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 529b812f41..6948c6699b 100755 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -34,7 +34,6 @@  #include "llgltypes.h"  #include "llrender.h"  #include "llmetricperformancetester.h" -#include "llunit.h"  #include <map>  #include <list> @@ -42,7 +41,6 @@  extern const LLUnit<S32, LLUnits::Mibibytes> gMinVideoRam;  extern const LLUnit<S32, LLUnits::Mibibytes> gMaxVideoRam; -class LLFace;  class LLImageGL ;  class LLImageRaw;  class LLViewerObject; @@ -99,11 +97,10 @@ public:  		DYNAMIC_TEXTURE,  		FETCHED_TEXTURE,  		LOD_TEXTURE, -		ATLAS_TEXTURE,  		INVALID_TEXTURE_TYPE  	}; -	typedef std::vector<LLFace*> ll_face_list_t; +	typedef std::vector<class LLFace*> ll_face_list_t;  	typedef std::vector<LLVOVolume*> ll_volume_list_t; @@ -143,12 +140,15 @@ public:  	LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;} +	S32 getFullWidth() const { return mFullWidth; } +	S32 getFullHeight() const { return mFullHeight; }	  	/*virtual*/ void setKnownDrawSize(S32 width, S32 height); -	virtual void addFace(LLFace* facep) ; -	virtual void removeFace(LLFace* facep) ;  -	S32 getNumFaces() const; -	const ll_face_list_t* getFaceList() const {return &mFaceList;} +	virtual void addFace(U32 channel, LLFace* facep) ; +	virtual void removeFace(U32 channel, LLFace* facep) ;  +	S32 getTotalNumFaces() const; +	S32 getNumFaces(U32 ch) const; +	const ll_face_list_t* getFaceList(U32 channel) const {llassert(channel < LLRender::NUM_TEXTURE_CHANNELS); return &mFaceList[channel];}  	virtual void addVolume(LLVOVolume* volumep);  	virtual void removeVolume(LLVOVolume* volumep); @@ -185,8 +185,8 @@ protected:  	mutable F32 mAdditionalDecodePriority;  // priority add to mDecodePriority.  	LLFrameTimer mLastReferencedTimer;	 -	ll_face_list_t    mFaceList ; //reverse pointer pointing to the faces using this image as texture -	U32               mNumFaces ; +	ll_face_list_t    mFaceList[LLRender::NUM_TEXTURE_CHANNELS]; //reverse pointer pointing to the faces using this image as texture +	U32               mNumFaces[LLRender::NUM_TEXTURE_CHANNELS];  	LLFrameTimer      mLastFaceListUpdateTimer ;  	ll_volume_list_t  mVolumeList; @@ -217,7 +217,6 @@ public:  	static S32 sMaxSmallImageSize ;  	static BOOL sFreezeImageScalingDown ;//do not scale down image res if set.  	static F32  sCurrentTime ; -	static BOOL sUseTextureAtlas ;  	enum EDebugTexels  	{ @@ -406,17 +405,12 @@ protected:  	S32 getCurrentDiscardLevelForFetching() ;  private: -	void init(bool firstinit) ; +	void init(bool firstinit) ;	  	void cleanup() ;  	void saveRawImage() ;  	void setCachedRawImage() ; -	//for atlas -	void resetFaceAtlas() ; -	void invalidateAtlas(BOOL rebuild_geom) ; -	BOOL insertToAtlas() ; -  private:  	BOOL  mFullyLoaded;  	BOOL  mInDebug; @@ -453,7 +447,7 @@ protected:  	S8  mHasFetcher;				// We've made a fecth request  	S8  mIsFetching;				// Fetch request is active  	bool mCanUseHTTP ;              //This texture can be fetched through http if true. -	 +  	FTType mFTType; // What category of image is this - map tile, server bake, etc?  	mutable S8 mIsMissingAsset;		// True if we know that there is no image asset with this image id in the database.		 @@ -502,6 +496,7 @@ public:  	static LLPointer<LLViewerFetchedTexture> sWhiteImagep;	// Texture to show NOTHING (whiteness)  	static LLPointer<LLViewerFetchedTexture> sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local.  	static LLPointer<LLViewerFetchedTexture> sSmokeImagep; // Old "Default" translucent texture +	static LLPointer<LLViewerFetchedTexture> sFlatNormalImagep; // Flat normal map denoting no bumpiness on a surface  };  // @@ -559,12 +554,12 @@ public:  	void addMediaToFace(LLFace* facep) ;  	void removeMediaFromFace(LLFace* facep) ; -	/*virtual*/ void addFace(LLFace* facep) ; -	/*virtual*/ void removeFace(LLFace* facep) ;  +	/*virtual*/ void addFace(U32 ch, LLFace* facep) ; +	/*virtual*/ void removeFace(U32 ch, LLFace* facep) ;   	/*virtual*/ F32  getMaxVirtualSize() ;  private: -	void switchTexture(LLFace* facep) ; +	void switchTexture(U32 ch, LLFace* facep) ;  	BOOL findFaces() ;  	void stopPlaying() ; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index f3b3a6086d..431a3b330c 100755 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -112,6 +112,9 @@ void LLViewerTextureList::doPreloadImages()  	LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();  	LLUIImageList* image_list = LLUIImageList::getInstance(); +	// Set the default flat normal map +	LLViewerFetchedTexture::sFlatNormalImagep = LLViewerTextureManager::getFetchedTextureFromFile("flatnormal.tga", FTT_LOCAL_FILE, MIPMAP_NO, LLViewerFetchedTexture::BOOST_BUMP); +	  	image_list->initFromFile();  	// turn off clamping and bilinear filtering for uv picking images @@ -317,7 +320,7 @@ void LLViewerTextureList::restoreGL()  /////////////////////////////////////////////////////////////////////////////// -LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename,												    +LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename,  												   FTType f_type,  												   BOOL usemipmaps,  												   LLViewerTexture::EBoostLevel boost_priority, @@ -369,7 +372,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&  	}  	LLPointer<LLViewerFetchedTexture> imagep = findImage(new_id); -	 +  	if (!imagep.isNull())  	{  		LLViewerFetchedTexture *texture = imagep.get(); @@ -425,7 +428,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&  } -LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,											        +LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,  												   FTType f_type,  												   BOOL usemipmaps,  												   LLViewerTexture::EBoostLevel boost_priority, @@ -468,7 +471,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,  		{  			llwarns << "FTType mismatch: requested " << f_type << " image has " << imagep->getFTType() << llendl;  		} -	 +		  	}  	if (imagep.isNull())  	{ @@ -481,7 +484,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,  }  //when this function is called, there is no such texture in the gTextureList with image_id. -LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,											        +LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,  												   FTType f_type,  												   BOOL usemipmaps,  												   LLViewerTexture::EBoostLevel boost_priority, @@ -668,8 +671,8 @@ void LLViewerTextureList::updateImages(F32 max_time)  		sample(NUM_RAW_IMAGES, LLImageRaw::sRawImageCount);  		sample(GL_TEX_MEM, LLImageGL::sGlobalTextureMemory);  		sample(GL_BOUND_MEM, LLImageGL::sBoundTextureMemory); -		sample(RAW_MEM, LLTrace::Bytes(LLImageRaw::sGlobalRawMemory)); -		sample(FORMATTED_MEM, LLTrace::Bytes(LLImageFormatted::sGlobalFormattedMemory)); +		sample(RAW_MEM, LLUnit<F64, LLUnits::Bytes>(LLImageRaw::sGlobalRawMemory)); +		sample(FORMATTED_MEM, LLUnit<F64, LLUnits::Bytes>(LLImageFormatted::sGlobalFormattedMemory));  	}  	{ @@ -761,7 +764,7 @@ void LLViewerTextureList::updateImagesDecodePriorities()  			max_inactive_time = 20000.f;  		} -		static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities");         // default: 32 +        static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities");         // default: 32  		const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds.value()) + 1, MAX_PRIO_UPDATES);  		S32 update_counter = llmin(max_update_count, mUUIDMap.size());  		uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateUUID); @@ -1371,7 +1374,7 @@ void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_d  	{  		received_size = msg->getReceiveSize() ;		  	} -	add(LLStatViewer::TEXTURE_KBIT, LLTrace::Bytes(received_size)); +	add(LLStatViewer::TEXTURE_KBIT, LLUnit<F64, LLUnits::Bytes>(received_size));  	add(LLStatViewer::TEXTURE_PACKETS, 1);  	U8 codec; @@ -1445,7 +1448,7 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d  		received_size = msg->getReceiveSize() ;		  	} -	add(LLStatViewer::TEXTURE_KBIT, LLTrace::Bytes(received_size)); +	add(LLStatViewer::TEXTURE_KBIT, LLUnit<F64, LLUnits::Bytes>(received_size));  	add(LLStatViewer::TEXTURE_PACKETS, 1);  	//llprintline("Start decode, image header..."); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 97f7baa98d..85e4e6bc08 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -229,13 +229,13 @@ LLFrameTimer	gAwayTriggerTimer;  BOOL			gShowOverlayTitle = FALSE;  LLViewerObject*  gDebugRaycastObject = NULL; -LLVector3       gDebugRaycastIntersection; +LLVector4a       gDebugRaycastIntersection;  LLVector2       gDebugRaycastTexCoord; -LLVector3       gDebugRaycastNormal; -LLVector3       gDebugRaycastBinormal; +LLVector4a       gDebugRaycastNormal; +LLVector4a       gDebugRaycastTangent;  S32				gDebugRaycastFaceHit; -LLVector3		gDebugRaycastStart; -LLVector3		gDebugRaycastEnd; +LLVector4a		 gDebugRaycastStart; +LLVector4a		 gDebugRaycastEnd;  // HUD display lines in lower right  BOOL				gDisplayWindInfo = FALSE; @@ -583,9 +583,9 @@ public:  			gPipeline.mMatrixOpCount = 0;   			if (last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize) > 0) -  			{ +			{   				addText(xpos, ypos, llformat("Batch min/max/mean: %d/%d/%d", last_frame_recording.getMin(LLPipeline::sStatBatchSize), last_frame_recording.getMax(LLPipeline::sStatBatchSize), last_frame_recording.getMean(LLPipeline::sStatBatchSize))); -  			} +			}              ypos += y_inc;  			addText(xpos, ypos, llformat("UI Verts/Calls: %d/%d", LLRender::sUIVerts, LLRender::sUICalls)); @@ -2840,7 +2840,7 @@ void LLViewerWindow::updateUI()  											  &gDebugRaycastIntersection,  											  &gDebugRaycastTexCoord,  											  &gDebugRaycastNormal, -											  &gDebugRaycastBinormal, +											  &gDebugRaycastTangent,  											  &gDebugRaycastStart,  											  &gDebugRaycastEnd);  	} @@ -3738,7 +3738,7 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot,  BOOL pick_trans  }  LLHUDIcon* LLViewerWindow::cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth, -										   LLVector3* intersection) +										   LLVector4a* intersection)  {  	S32 x = mouse_x;  	S32 y = mouse_y; @@ -3750,14 +3750,17 @@ LLHUDIcon* LLViewerWindow::cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 dep  	}  	// world coordinates of mouse +	// VECTORIZE THIS  	LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y);  	LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin();  	LLVector3 mouse_world_start = mouse_point_global;  	LLVector3 mouse_world_end   = mouse_point_global + mouse_direction_global * depth; -	return LLHUDIcon::lineSegmentIntersectAll(mouse_world_start, mouse_world_end, intersection); - +	LLVector4a start, end; +	start.load3(mouse_world_start.mV); +	end.load3(mouse_world_end.mV); +	return LLHUDIcon::lineSegmentIntersectAll(start, end, intersection);  }  LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 depth, @@ -3765,12 +3768,12 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de  												S32 this_face,  												BOOL pick_transparent,  												S32* face_hit, -												LLVector3 *intersection, +												LLVector4a *intersection,  												LLVector2 *uv, -												LLVector3 *normal, -												LLVector3 *binormal, -												LLVector3* start, -												LLVector3* end) +												LLVector4a *normal, +												LLVector4a *tangent, +												LLVector4a* start, +												LLVector4a* end)  {  	S32 x = mouse_x;  	S32 y = mouse_y; @@ -3805,17 +3808,27 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de  	if (!LLViewerJoystick::getInstance()->getOverrideCamera())  	{ //always set raycast intersection to mouse_world_end unless  		//flycam is on (for DoF effect) -		gDebugRaycastIntersection = mouse_world_end; +		gDebugRaycastIntersection.load3(mouse_world_end.mV);  	} +	LLVector4a mw_start; +	mw_start.load3(mouse_world_start.mV); +	LLVector4a mw_end; +	mw_end.load3(mouse_world_end.mV); + +	LLVector4a mh_start; +	mh_start.load3(mouse_hud_start.mV); +	LLVector4a mh_end; +	mh_end.load3(mouse_hud_end.mV); +  	if (start)  	{ -		*start = mouse_world_start; +		*start = mw_start;  	}  	if (end)  	{ -		*end = mouse_world_end; +		*end = mw_end;  	}  	LLViewerObject* found = NULL; @@ -3824,16 +3837,16 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de  	{  		if (this_object->isHUDAttachment()) // is a HUD object?  		{ -			if (this_object->lineSegmentIntersect(mouse_hud_start, mouse_hud_end, this_face, pick_transparent, -												  face_hit, intersection, uv, normal, binormal)) +			if (this_object->lineSegmentIntersect(mh_start, mh_end, this_face, pick_transparent, +												  face_hit, intersection, uv, normal, tangent))  			{  				found = this_object;  			}  		}  		else // is a world object  		{ -			if (this_object->lineSegmentIntersect(mouse_world_start, mouse_world_end, this_face, pick_transparent, -												  face_hit, intersection, uv, normal, binormal)) +			if (this_object->lineSegmentIntersect(mw_start, mw_end, this_face, pick_transparent, +												  face_hit, intersection, uv, normal, tangent))  			{  				found = this_object;  			} @@ -3841,13 +3854,13 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de  	}  	else // check ALL objects  	{ -		found = gPipeline.lineSegmentIntersectInHUD(mouse_hud_start, mouse_hud_end, pick_transparent, -													face_hit, intersection, uv, normal, binormal); +		found = gPipeline.lineSegmentIntersectInHUD(mh_start, mh_end, pick_transparent, +													face_hit, intersection, uv, normal, tangent);  		if (!found) // if not found in HUD, look in world:  		{ -			found = gPipeline.lineSegmentIntersectInWorld(mouse_world_start, mouse_world_end, pick_transparent, -														  face_hit, intersection, uv, normal, binormal); +			found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent, +														  face_hit, intersection, uv, normal, tangent);  			if (found && !pick_transparent)  			{  				gDebugRaycastIntersection = *intersection; @@ -5111,6 +5124,7 @@ LLPickInfo::LLPickInfo()  	  mXYCoords(-1, -1),  	  mIntersection(),  	  mNormal(), +	  mTangent(),  	  mBinormal(),  	  mHUDIcon(NULL),  	  mPickTransparent(FALSE) @@ -5132,6 +5146,7 @@ LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos,  	  mSTCoords(-1.f, -1.f),  	  mXYCoords(-1, -1),  	  mNormal(), +	  mTangent(),  	  mBinormal(),  	  mHUDIcon(NULL),  	  mPickTransparent(pick_transparent) @@ -5142,19 +5157,26 @@ void LLPickInfo::fetchResults()  {  	S32 face_hit = -1; -	LLVector3 intersection, normal, binormal; +	LLVector4a intersection, normal; +	LLVector4a tangent; +  	LLVector2 uv;  	LLHUDIcon* hit_icon = gViewerWindow->cursorIntersectIcon(mMousePt.mX, mMousePt.mY, 512.f, &intersection); +	LLVector4a origin; +	origin.load3(LLViewerCamera::getInstance()->getOrigin().mV);  	F32 icon_dist = 0.f;  	if (hit_icon)  	{ -		icon_dist = (LLViewerCamera::getInstance()->getOrigin()-intersection).magVec(); +		LLVector4a delta; +		delta.setSub(intersection, origin); +		icon_dist = delta.getLength3().getF32();  	} +  	LLViewerObject* hit_object = gViewerWindow->cursorIntersect(mMousePt.mX, mMousePt.mY, 512.f,  									NULL, -1, mPickTransparent, &face_hit, -									&intersection, &uv, &normal, &binormal); +									&intersection, &uv, &normal, &tangent);  	mPickPt = mMousePt; @@ -5164,9 +5186,13 @@ void LLPickInfo::fetchResults()  	LLViewerObject* objectp = hit_object; + +	LLVector4a delta; +	delta.setSub(origin, intersection); +  	if (hit_icon &&   		(!objectp ||  -		icon_dist < (LLViewerCamera::getInstance()->getOrigin()-intersection).magVec())) +		icon_dist < delta.getLength3().getF32()))  	{  		// was this name referring to a hud icon?  		mHUDIcon = hit_icon; @@ -5203,11 +5229,16 @@ void LLPickInfo::fetchResults()  			{  				mPickType = PICK_OBJECT;  			} -			mObjectOffset = gAgentCamera.calcFocusOffset(objectp, intersection, mPickPt.mX, mPickPt.mY); + +			LLVector3 v_intersection(intersection.getF32ptr()); + +			mObjectOffset = gAgentCamera.calcFocusOffset(objectp, v_intersection, mPickPt.mX, mPickPt.mY);  			mObjectID = objectp->mID;  			mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset; -			mPosGlobal = gAgent.getPosGlobalFromAgent(intersection); +			 + +			mPosGlobal = gAgent.getPosGlobalFromAgent(v_intersection);  			if (mWantSurfaceInfo)  			{ @@ -5251,6 +5282,15 @@ void LLPickInfo::getSurfaceInfo()  	mIntersection = LLVector3(0,0,0);  	mNormal       = LLVector3(0,0,0);  	mBinormal     = LLVector3(0,0,0); +	mTangent	  = LLVector4(0,0,0,0); +	 +	LLVector4a tangent; +	LLVector4a intersection; +	LLVector4a normal; + +	tangent.clear(); +	normal.clear(); +	intersection.clear();  	LLViewerObject* objectp = getObject(); @@ -5259,10 +5299,10 @@ void LLPickInfo::getSurfaceInfo()  		if (gViewerWindow->cursorIntersect(llround((F32)mMousePt.mX), llround((F32)mMousePt.mY), 1024.f,  										   objectp, -1, mPickTransparent,  										   &mObjectFace, -										   &mIntersection, +										   &intersection,  										   &mSTCoords, -										   &mNormal, -										   &mBinormal)) +										   &normal, +										   &tangent))  		{  			// if we succeeded with the intersect above, compute the texture coordinates: @@ -5271,10 +5311,26 @@ void LLPickInfo::getSurfaceInfo()  				LLFace* facep = objectp->mDrawable->getFace(mObjectFace);  				if (facep)  				{ -					mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal); -				} +					mUVCoords = facep->surfaceToTexture(mSTCoords, intersection, normal); +			}  			} +			mIntersection.set(intersection.getF32ptr()); +			mNormal.set(normal.getF32ptr()); +			mTangent.set(tangent.getF32ptr()); + +			//extrapoloate binormal from normal and tangent +			 +			LLVector4a binormal; +			binormal.setCross3(normal, tangent); +			binormal.mul(tangent.getF32ptr()[3]); + +			mBinormal.set(binormal.getF32ptr()); + +			mBinormal.normalize(); +			mNormal.normalize(); +			mTangent.normalize(); +  			// and XY coords:  			updateXYCoords(); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index e0943d9825..930ed9d5a9 100755 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -115,6 +115,7 @@ public:  	LLVector2       mSTCoords;  	LLCoordScreen	mXYCoords;  	LLVector3		mNormal; +	LLVector4		mTangent;  	LLVector3		mBinormal;  	BOOL			mPickTransparent;  	void		    getSurfaceInfo(); @@ -357,19 +358,19 @@ public:  	void			pickAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback)(const LLPickInfo& pick_info), BOOL pick_transparent = FALSE);  	LLPickInfo		pickImmediate(S32 x, S32 y, BOOL pick_transparent);  	LLHUDIcon* cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth, -										   LLVector3* intersection); +										   LLVector4a* intersection);  	LLViewerObject* cursorIntersect(S32 mouse_x = -1, S32 mouse_y = -1, F32 depth = 512.f,  									LLViewerObject *this_object = NULL,  									S32 this_face = -1,  									BOOL pick_transparent = FALSE,  									S32* face_hit = NULL, -									LLVector3 *intersection = NULL, +									LLVector4a *intersection = NULL,  									LLVector2 *uv = NULL, -									LLVector3 *normal = NULL, -									LLVector3 *binormal = NULL, -									LLVector3* start = NULL, -									LLVector3* end = NULL); +									LLVector4a *normal = NULL, +									LLVector4a *tangent = NULL, +									LLVector4a* start = NULL, +									LLVector4a* end = NULL);  	// Returns a pointer to the last object hit @@ -500,13 +501,13 @@ extern LLFrameTimer		gAwayTimer;				// tracks time before setting the avatar awa  extern LLFrameTimer		gAwayTriggerTimer;		// how long the avatar has been away  extern LLViewerObject*  gDebugRaycastObject; -extern LLVector3        gDebugRaycastIntersection; +extern LLVector4a       gDebugRaycastIntersection;  extern LLVector2        gDebugRaycastTexCoord; -extern LLVector3        gDebugRaycastNormal; -extern LLVector3        gDebugRaycastBinormal; +extern LLVector4a       gDebugRaycastNormal; +extern LLVector4a       gDebugRaycastTangent;  extern S32				gDebugRaycastFaceHit; -extern LLVector3		gDebugRaycastStart; -extern LLVector3		gDebugRaycastEnd; +extern LLVector4a		gDebugRaycastStart; +extern LLVector4a		gDebugRaycastEnd;  extern BOOL			gDisplayCameraPos;  extern BOOL			gDisplayWindInfo; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index d4c31fd4b0..11b027a417 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -251,7 +251,7 @@ struct LLAppearanceMessageContents  	std::vector<F32> mParamWeights;  	std::vector<LLVisualParam*> mParams;  }; -	 +  struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoint>  	{  	Alternative<Lazy<struct LLVOAvatarBoneInfo, IS_A_BLOCK> >	bone; @@ -1202,7 +1202,7 @@ void LLVOAvatar::initInstance(void)  		registerMotion( ANIM_AGENT_TARGET,					LLTargetingMotion::create );  		registerMotion( ANIM_AGENT_WALK_ADJUST,				LLWalkAdjustMotion::create );  	} -	 +  	LLAvatarAppearance::initInstance();  	// preload specific motions here @@ -1394,19 +1394,20 @@ void LLVOAvatar::renderCollisionVolumes()  	if (mNameText.notNull())  	{ -		LLVector3 unused; -		mNameText->lineSegmentIntersect(LLVector3(0,0,0), LLVector3(0,0,1), unused, TRUE); +		LLVector4a unused; +	 +		mNameText->lineSegmentIntersect(unused, unused, unused, TRUE);  	}  } -BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  									  S32 face,  									  BOOL pick_transparent,  									  S32* face_hit, -									  LLVector3* intersection, +									  LLVector4a* intersection,  									  LLVector2* tex_coord, -									  LLVector3* normal, -									  LLVector3* bi_normal) +									  LLVector4a* normal, +									  LLVector4a* tangent)  {  	if ((isSelf() && !gAgent.needsRenderAvatar()) || !LLPipeline::sPickAvatar)  	{ @@ -1423,8 +1424,8 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  			glh::matrix4f inverse = mat.inverse();  			glh::matrix4f norm_mat = inverse.transpose(); -			glh::vec3f p1(start.mV); -			glh::vec3f p2(end.mV); +			glh::vec3f p1(start.getF32ptr()); +			glh::vec3f p2(end.getF32ptr());  			inverse.mult_matrix_vec(p1);  			inverse.mult_matrix_vec(p2); @@ -1443,12 +1444,12 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  				if (intersection)  				{ -					*intersection = LLVector3(res_pos.v); +					intersection->load3(res_pos.v);  				}  				if (normal)  				{ -					*normal = LLVector3(res_norm.v); +					normal->load3(res_norm.v);  				}  				return TRUE; @@ -1484,7 +1485,7 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e -	LLVector3 position; +	LLVector4a position;  	if (mNameText.notNull() && mNameText->lineSegmentIntersect(start, end, position))  	{  		if (intersection) @@ -1498,14 +1499,14 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  	return FALSE;  } -LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end, +LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end,  									  S32 face,  									  BOOL pick_transparent,  									  S32* face_hit, -									  LLVector3* intersection, +									  LLVector4a* intersection,  									  LLVector2* tex_coord, -									  LLVector3* normal, -									  LLVector3* bi_normal) +									  LLVector4a* normal, +									  LLVector4a* tangent)  {  	if (isSelf() && !gAgent.needsRenderAvatar())  	{ @@ -1516,8 +1517,8 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector  	if (lineSegmentBoundingBox(start, end))  	{ -		LLVector3 local_end = end; -		LLVector3 local_intersection; +		LLVector4a local_end = end; +		LLVector4a local_intersection;  		for (attachment_map_t::iterator iter = mAttachmentPoints.begin();   			iter != mAttachmentPoints.end(); @@ -1531,7 +1532,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector  			{  				LLViewerObject* attached_object = (*attachment_iter); -				if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, bi_normal)) +				if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, tangent))  				{  					local_end = local_intersection;  					if (intersection) @@ -1548,7 +1549,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector  	return hit;  } - +	  LLVOAvatar* LLVOAvatar::asAvatar()  {  	return this; @@ -2547,7 +2548,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)  		mVisibleChat = visible_chat;  		new_name = TRUE;  	} -		 +  	if (sRenderGroupTitles != mRenderGroupTitles)  	{  		mRenderGroupTitles = sRenderGroupTitles; @@ -2752,7 +2753,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)  		mNameText->setFont(LLFontGL::getFontSansSerif());  		mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT);  		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); -			 +  		std::deque<LLChat>::iterator chat_iter = mChats.begin();  		mNameText->clearString(); @@ -3875,61 +3876,61 @@ U32 LLVOAvatar::renderSkinned()  	// render all geometry attached to the skeleton  	//-------------------------------------------------------------------- -	bool should_alpha_mask = shouldAlphaMask(); -	LLGLState test(GL_ALPHA_TEST, should_alpha_mask); -	 -	if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction) -	{ -		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); -	} -	 -	BOOL first_pass = TRUE; -	if (!LLDrawPoolAvatar::sSkipOpaque) -	{ -		if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender) +		bool should_alpha_mask = shouldAlphaMask(); +		LLGLState test(GL_ALPHA_TEST, should_alpha_mask); +		 +		if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction)  		{ -			if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy) +			gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); +		} +		 +		BOOL first_pass = TRUE; +		if (!LLDrawPoolAvatar::sSkipOpaque) +		{ +			if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)  			{ -				LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD); -				if (head_mesh) +				if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy)  				{ -					num_indices += head_mesh->render(mAdjustedPixelArea, TRUE, mIsDummy); +					LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD); +					if (head_mesh) +					{ +						num_indices += head_mesh->render(mAdjustedPixelArea, TRUE, mIsDummy); +					} +					first_pass = FALSE; +				} +			} +			if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy) +			{ +				LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY); +				if (upper_mesh) +				{ +					num_indices += upper_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);  				}  				first_pass = FALSE;  			} -		} -		if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy) -		{ -			LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY); -			if (upper_mesh) +			 +			if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy)  			{ -				num_indices += upper_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); +				LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY); +				if (lower_mesh) +				{ +					num_indices += lower_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); +				} +				first_pass = FALSE;  			} -			first_pass = FALSE;  		} -		 -		if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy) + +		if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction)  		{ -			LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY); -			if (lower_mesh) -			{ -				num_indices += lower_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); -			} -			first_pass = FALSE; +			gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); +		} + +		if (!LLDrawPoolAvatar::sSkipTransparent || LLPipeline::sImpostorRender) +		{ +			LLGLState blend(GL_BLEND, !mIsDummy); +			LLGLState test(GL_ALPHA_TEST, !mIsDummy); +			num_indices += renderTransparent(first_pass);  		} -	} -	 -	if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction) -	{ -		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); -	} -	 -	if (!LLDrawPoolAvatar::sSkipTransparent || LLPipeline::sImpostorRender) -	{ -		LLGLState blend(GL_BLEND, !mIsDummy); -		LLGLState test(GL_ALPHA_TEST, !mIsDummy); -		num_indices += renderTransparent(first_pass); -	}  	return num_indices;  } @@ -5101,7 +5102,7 @@ BOOL LLVOAvatar::loadSkeletonNode ()  	{  		return FALSE;  	} -	 +  	// ATTACHMENTS  	{  		LLAvatarXmlInfo::attachment_info_list_t::iterator iter; @@ -5836,6 +5837,8 @@ BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const + +  // virtual  void LLVOAvatar::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_result )  { @@ -6075,7 +6078,7 @@ void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapse  	record["grid_y"] = LLSD::Integer(grid_y);  	record["is_using_server_bakes"] = ((bool) isUsingServerBakes());  	record["is_self"] = isSelf(); -		 +	  	if (isAgentAvatarValid())  	{  		gAgentAvatarp->addMetricsTimerRecord(record); @@ -6283,11 +6286,11 @@ void LLVOAvatar::updateMeshTextures()  										   use_lkg_baked_layer[i],  										   last_id_string.c_str());  	} - +	  	for (U32 i=0; i < mBakedTextureDatas.size(); i++)  	{  		debugColorizeSubMeshes(i, LLColor4::white); -	 +  		LLViewerTexLayerSet* layerset = getTexLayerSet(i);  		if (use_lkg_baked_layer[i] && !isUsingLocalAppearance() )  		{ @@ -6469,6 +6472,7 @@ void LLVOAvatar::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_com  } +  // returns TRUE if morph masks are present and not valid for a given baked texture, FALSE otherwise  BOOL LLVOAvatar::morphMaskNeedsUpdate(LLAvatarAppearanceDefines::EBakedTextureIndex index)  { @@ -6747,7 +6751,7 @@ void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value)  //					param_location_name(vparam->getParamLocation()).c_str()  		);  } -	 +  void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix,  	const LLAppearanceMessageContents& contents) @@ -6814,7 +6818,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe  		// For future use:  		//mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0);  	} -	 +  	// Parse visual params, if any.  	S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);  	bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing @@ -7238,7 +7242,7 @@ void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTextu  	LLUUID *avatar_idp = (LLUUID *)userdata;  	LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp); -	 +  	if (selfp)  	{  		LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << LL_ENDL; @@ -7376,6 +7380,10 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara  	}  	if (outprefix.empty())  	{ +		outprefix = getFullname() + (isSelf()?"_s":"_o"); +	} +	if (outprefix.empty()) +	{  		outprefix = std::string("new_archetype");  	}  	std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml"); @@ -7441,7 +7449,6 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara  		for (U8 te = 0; te < TEX_NUM_INDICES; te++)  		{ -			{  				// MULTIPLE_WEARABLES: extend to multiple wearables?  				LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);  				if( te_image ) @@ -7453,7 +7460,6 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara  			}  		} -	}  	apr_file_printf( file, "\t</archetype>\n" );  	apr_file_printf( file, "\n</linden_genepool>\n" ); @@ -7612,7 +7618,7 @@ void LLVOAvatar::setIsUsingServerBakes(BOOL newval)  // virtual  void LLVOAvatar::removeMissingBakedTextures() -{ +{	  }  //virtual diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index c814d4c129..0544d7395d 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -163,22 +163,22 @@ public:  	/*virtual*/ void   	 	 	updateRegion(LLViewerRegion *regionp);  	/*virtual*/ void   	 	 	updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax);  	/*virtual*/ void   	 	 	getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); -	/*virtual*/ BOOL   	 	 	lineSegmentIntersect(const LLVector3& start, const LLVector3& end, +	/*virtual*/ BOOL   	 	 	lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,  												 S32 face = -1,                    // which face to check, -1 = ALL_SIDES  												 BOOL pick_transparent = FALSE,  												 S32* face_hit = NULL,             // which face was hit -												 LLVector3* intersection = NULL,   // return the intersection point +												 LLVector4a* intersection = NULL,   // return the intersection point  												 LLVector2* tex_coord = NULL,      // return the texture coordinates of the intersection point -												 LLVector3* normal = NULL,         // return the surface normal at the intersection point -												 LLVector3* bi_normal = NULL);     // return the surface bi-normal at the intersection point -	LLViewerObject*	lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end, +												 LLVector4a* normal = NULL,         // return the surface normal at the intersection point +												 LLVector4a* tangent = NULL);     // return the surface tangent at the intersection point +	LLViewerObject*	lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end,  												 S32 face = -1,                    // which face to check, -1 = ALL_SIDES  												 BOOL pick_transparent = FALSE,  												 S32* face_hit = NULL,             // which face was hit -												 LLVector3* intersection = NULL,   // return the intersection point +												 LLVector4a* intersection = NULL,   // return the intersection point  												 LLVector2* tex_coord = NULL,      // return the texture coordinates of the intersection point -												 LLVector3* normal = NULL,         // return the surface normal at the intersection point -												 LLVector3* bi_normal = NULL);     // return the surface bi-normal at the intersection point +												 LLVector4a* normal = NULL,         // return the surface normal at the intersection point +												 LLVector4a* tangent = NULL);     // return the surface tangent at the intersection point  	//--------------------------------------------------------------------  	// LLCharacter interface and related diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 9ab910f7fd..67da311c5a 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -792,7 +792,7 @@ U32  LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys,  		// unpack the texture UUIDs to the texture slots  		if(mesgsys != NULL)  		{ -			retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num); +		retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num);  		}  		// need to trigger a few operations to get the avatar to use the new bakes @@ -900,7 +900,7 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)  		if (mLastRegionHandle != 0)  		{  			++mRegionCrossingCount; -			LLTrace::Seconds delta = mRegionCrossingTimer.getElapsedTimeF32(); +			LLUnit<F64, LLUnits::Seconds> delta = mRegionCrossingTimer.getElapsedTimeF32();  			record(LLStatViewer::REGION_CROSSING_TIME, delta);  			// Diagnostics @@ -2584,7 +2584,7 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe  			{  				F32 desired_pixels;  				desired_pixels = llmin(mPixelArea, (F32)getTexImageArea()); - +				  				imagep->setBoostLevel(getAvatarBoostLevel());  				imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;  				imagep->resetTextureStats(); diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index e9efc7db9a..88ce6df916 100755 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -766,8 +766,8 @@ void LLVOGrass::updateDrawable(BOOL force_damped)  }  // virtual  -BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp, -									  LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +BOOL LLVOGrass::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp, +									  LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)  {  	BOOL ret = FALSE; @@ -778,7 +778,8 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en  		return FALSE;  	} -	LLVector3 dir = end-start; +	LLVector4a dir; +	dir.setSub(end, start);  	mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion()); @@ -846,23 +847,31 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en  		U32 idx0 = 0,idx1 = 0,idx2 = 0; -		if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE)) +		LLVector4a v0a,v1a,v2a,v3a; + +		v0a.load3(v[0].mV); +		v1a.load3(v[1].mV); +		v2a.load3(v[2].mV); +		v3a.load3(v[3].mV); + +		 +		if (LLTriangleRayIntersect(v0a, v1a, v2a, start, dir, a, b, t))  		{  			hit = TRUE;  			idx0 = 0; idx1 = 1; idx2 = 2;  		} -		else if (LLTriangleRayIntersect(v[1], v[3], v[2], start, dir, a, b, t, FALSE)) +		else if (LLTriangleRayIntersect(v1a, v3a, v2a, start, dir, a, b, t))  		{  			hit = TRUE;  			idx0 = 1; idx1 = 3; idx2 = 2;  		} -		else if (LLTriangleRayIntersect(v[2], v[1], v[0], start, dir, a, b, t, FALSE)) +		else if (LLTriangleRayIntersect(v2a, v1a, v0a, start, dir, a, b, t))  		{  			normal1 = -normal1;  			hit = TRUE;  			idx0 = 2; idx1 = 1; idx2 = 0;  		} -		else if (LLTriangleRayIntersect(v[2], v[3], v[1], start, dir, a, b, t, FALSE)) +		else if (LLTriangleRayIntersect(v2a, v3a, v1a, start, dir, a, b, t))  		{  			normal1 = -normal1;  			hit = TRUE; @@ -885,7 +894,8 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en  					closest_t = t;  					if (intersection != NULL)  					{ -						*intersection = start+dir*closest_t; +						dir.mul(closest_t); +						intersection->setAdd(start, dir);  					}  					if (tex_coord != NULL) @@ -895,7 +905,7 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en  					if (normal != NULL)  					{ -						*normal    = normal1; +						normal->load3(normal1.mV);  					}  					ret = TRUE;  				} diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h index b9835b8802..122806766d 100755 --- a/indra/newview/llvograss.h +++ b/indra/newview/llvograss.h @@ -75,14 +75,14 @@ public:  	/*virtual*/ BOOL    isActive() const; // Whether this object needs to do an idleUpdate.  	/*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); -	/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  +	/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,   										  S32 face = -1,                        // which face to check, -1 = ALL_SIDES  										  BOOL pick_transparent = FALSE,  										  S32* face_hit = NULL,                 // which face was hit -										  LLVector3* intersection = NULL,       // return the intersection point +										  LLVector4a* intersection = NULL,       // return the intersection point  										  LLVector2* tex_coord = NULL,          // return the texture coordinates of the intersection point -										  LLVector3* normal = NULL,             // return the surface normal at the intersection point -										  LLVector3* bi_normal = NULL           // return the surface bi-normal at the intersection point +										  LLVector4a* normal = NULL,             // return the surface normal at the intersection point +										  LLVector4a* tangent = NULL           // return the surface tangent at the intersection point  		);  	static S32 sMaxGrassSpecies; diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 41b306007d..87f6f5c4a4 100755 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -65,7 +65,9 @@ void LLVOPartGroup::initClass()  //static  void LLVOPartGroup::restoreGL()  { -	sVB = new LLVertexBuffer(VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); + +	//TODO: optimize out binormal mask here.  Specular and normal coords as well. +	sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, GL_STREAM_DRAW_ARB);  	U32 count = LL_MAX_PARTICLE_COUNT;  	sVB->allocateBuffer(count*4, count*6, true); @@ -410,6 +412,7 @@ void LLVOPartGroup::getGeometry(S32 idx,  	right.setCross3(at, up);  	right.normalize3fast(); +  	up.setCross3(right, at);  	up.normalize3fast(); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 5b7aee2427..4633b62bfb 100755 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -97,10 +97,10 @@ public:  			glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));  			glClientActiveTextureARB(GL_TEXTURE0_ARB);  		} -		if (data_mask & MAP_BINORMAL) +		if (data_mask & MAP_TANGENT)  		{  			glClientActiveTextureARB(GL_TEXTURE2_ARB); -			glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); +			glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT]));  			glClientActiveTextureARB(GL_TEXTURE0_ARB);  		}  		if (data_mask & MAP_TEXCOORD0) @@ -936,8 +936,8 @@ void LLVOSurfacePatch::getGeomSizesEast(const S32 stride, const S32 east_stride,  	}  } -BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp, -									  LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp, +									  LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)  { @@ -946,7 +946,9 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect  		return FALSE;  	} -	LLVector3 delta = end-start; +	LLVector4a da; +	da.setSub(end, start); +	LLVector3 delta(da.getF32ptr());  	LLVector3 pdelta = delta;  	pdelta.mV[2] = 0; @@ -955,7 +957,9 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect  	F32 tdelta = 1.f/plength; -	LLVector3 origin = start - mRegionp->getOriginAgent(); +	LLVector3 v_start(start.getF32ptr()); + +	LLVector3 origin = v_start - mRegionp->getOriginAgent();  	if (mRegionp->getLandHeightRegion(origin) > origin.mV[2])  	{ @@ -1010,12 +1014,12 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect  					{  						sample.mV[2] = mRegionp->getLandHeightRegion(sample);  					} -					*intersection = sample + mRegionp->getOriginAgent(); +					intersection->load3((sample + mRegionp->getOriginAgent()).mV);  				}  				if (normal)  				{ -					*normal = mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample)); +					normal->load3((mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample))).mV);  				}  				return TRUE; diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index 21693e85e1..3383b16dd9 100755 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -81,14 +81,14 @@ public:  	void dirtyPatch();  	void dirtyGeom(); -	/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  +	/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,   										  S32 face = -1,                        // which face to check, -1 = ALL_SIDES  										  BOOL pick_transparent = FALSE,  										  S32* face_hit = NULL,                 // which face was hit -										  LLVector3* intersection = NULL,       // return the intersection point +										  LLVector4a* intersection = NULL,       // return the intersection point  										  LLVector2* tex_coord = NULL,          // return the texture coordinates of the intersection point -										  LLVector3* normal = NULL,             // return the surface normal at the intersection point -										  LLVector3* bi_normal = NULL           // return the surface bi-normal at the intersection point +										  LLVector4a* normal = NULL,             // return the surface normal at the intersection point +										  LLVector4a* tangent = NULL           // return the surface tangent at the intersection point  		);  	BOOL			mDirtiedPatch; diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 9a044968d2..dc20d348c0 100755 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -1085,132 +1085,6 @@ void LLVOTree::calcNumVerts(U32& vert_count, U32& index_count, S32 trunk_LOD, S3  	}  } -U32 LLVOTree::drawBranchPipeline(LLMatrix4& matrix, U16* indicesp, S32 trunk_LOD, S32 stop_level, U16 depth, U16 trunk_depth,  F32 scale, F32 twist, F32 droop,  F32 branches, F32 alpha) -{ -	U32 ret = 0; -	// -	//  Draws a tree by recursing, drawing branches and then a 'leaf' texture. -	//  If stop_level = -1, simply draws the whole tree as a billboarded texture -	// -	 -	static F32 constant_twist; -	static F32 width = 0; - -	//F32 length = ((scale == 1.f)? mTrunkLength:mBranchLength); -	//F32 aspect = ((scale == 1.f)? mTrunkAspect:mBranchAspect); -	F32 length = ((trunk_depth || (scale == 1.f))? mTrunkLength:mBranchLength); -	F32 aspect = ((trunk_depth || (scale == 1.f))? mTrunkAspect:mBranchAspect); -	 -	constant_twist = 360.f/branches; - -	if (!LLPipeline::sReflectionRender && stop_level >= 0) -	{ -		// -		//  Draw the tree using recursion -		// -		if (depth > stop_level) -		{ -			{ -				llassert(sLODIndexCount[trunk_LOD] > 0); -				width = scale * length * aspect; -				LLMatrix4 scale_mat; -				scale_mat.mMatrix[0][0] = width; -				scale_mat.mMatrix[1][1] = width; -				scale_mat.mMatrix[2][2] = scale*length; -				scale_mat *= matrix; - -				gGL.loadMatrix((F32*) scale_mat.mMatrix); -				gGL.syncMatrices(); - 				glDrawElements(GL_TRIANGLES, sLODIndexCount[trunk_LOD], GL_UNSIGNED_SHORT, indicesp + sLODIndexOffset[trunk_LOD]); -				gPipeline.addTrianglesDrawn(LEAF_INDICES); -				stop_glerror(); -				ret += sLODIndexCount[trunk_LOD]; -			} -			 -			// Recurse to create more branches -			for (S32 i=0; i < (S32)branches; i++)  -			{ -				LLMatrix4 trans_mat; -				trans_mat.setTranslation(0,0,scale*length); -				trans_mat *= matrix; - -				LLQuaternion rot =  -					LLQuaternion(20.f*DEG_TO_RAD, LLVector4(0.f, 0.f, 1.f)) * -					LLQuaternion(droop*DEG_TO_RAD, LLVector4(0.f, 1.f, 0.f)) * -					LLQuaternion(((constant_twist + ((i%2==0)?twist:-twist))*i)*DEG_TO_RAD, LLVector4(0.f, 0.f, 1.f)); -				 -				LLMatrix4 rot_mat(rot); -				rot_mat *= trans_mat; - -				ret += drawBranchPipeline(rot_mat, indicesp, trunk_LOD, stop_level, depth - 1, 0, scale*mScaleStep, twist, droop, branches, alpha); -			} -			//  Recurse to continue trunk -			if (trunk_depth) -			{ -				LLMatrix4 trans_mat; -				trans_mat.setTranslation(0,0,scale*length); -				trans_mat *= matrix; - -				LLMatrix4 rot_mat(70.5f*DEG_TO_RAD, LLVector4(0,0,1)); -				rot_mat *= trans_mat; // rotate a bit around Z when ascending  -				ret += drawBranchPipeline(rot_mat, indicesp, trunk_LOD, stop_level, depth, trunk_depth-1, scale*mScaleStep, twist, droop, branches, alpha); -			} -		} -		else -		{ -			// -			//  Draw leaves as two 90 deg crossed quads with leaf textures -			// -			{ -				LLMatrix4 scale_mat; -				scale_mat.mMatrix[0][0] =  -					scale_mat.mMatrix[1][1] = -					scale_mat.mMatrix[2][2] = scale*mLeafScale; - -				scale_mat *= matrix; - -			 -				gGL.loadMatrix((F32*) scale_mat.mMatrix); -				gGL.syncMatrices(); -				glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_SHORT, indicesp); -				gPipeline.addTrianglesDrawn(LEAF_INDICES);							 -				stop_glerror(); -				ret += LEAF_INDICES; -			} -		} -	} -	else -	{ -		// -		//  Draw the tree as a single billboard texture  -		// - -		LLMatrix4 scale_mat; -		scale_mat.mMatrix[0][0] =  -			scale_mat.mMatrix[1][1] = -			scale_mat.mMatrix[2][2] = mBillboardScale*mBillboardRatio; - -		scale_mat *= matrix; -	 -		gGL.matrixMode(LLRender::MM_TEXTURE); -		gGL.translatef(0.0, -0.5, 0.0); -		gGL.matrixMode(LLRender::MM_MODELVIEW); -					 -		gGL.loadMatrix((F32*) scale_mat.mMatrix); -		gGL.syncMatrices(); -		glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_SHORT, indicesp); -		gPipeline.addTrianglesDrawn(LEAF_INDICES); -		stop_glerror(); -		ret += LEAF_INDICES; - -		gGL.matrixMode(LLRender::MM_TEXTURE); -		gGL.loadIdentity(); -		gGL.matrixMode(LLRender::MM_MODELVIEW); -	} - -	return ret; -} -  void LLVOTree::updateRadius()  {  	if (mDrawable.isNull()) @@ -1238,8 +1112,8 @@ void LLVOTree::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)  	mDrawable->setPositionGroup(pos);  } -BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp, -									  LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +BOOL LLVOTree::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp, +									  LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)  { @@ -1268,16 +1142,19 @@ BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end  	LLVector3 pos, norm; -	if (linesegment_tetrahedron(start, end, center, size, quat, pos, norm)) +	LLVector3 start3(start.getF32ptr()); +	LLVector3 end3(end.getF32ptr()); + +	if (linesegment_tetrahedron(start3, end3, center, size, quat, pos, norm))  	{  		if (intersection)  		{ -			*intersection = pos; +			intersection->load3(pos.mV);  		}  		if (normal)  		{ -			*normal = norm; +			normal->load3(norm.mV);  		}  		return TRUE;  	} diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h index 52debc85ab..2ecb0303a1 100755 --- a/indra/newview/llvotree.h +++ b/indra/newview/llvotree.h @@ -104,19 +104,16 @@ public:  								 F32 twist,   								 F32 droop,    								 F32 branches,  -								 F32 alpha); +								 F32 alpha);  -	U32 drawBranchPipeline(LLMatrix4& matrix, U16* indicesp, S32 trunk_LOD, S32 stop_level, U16 depth, U16 trunk_depth,  F32 scale, F32 twist, F32 droop,  F32 branches, F32 alpha); -  - -	 /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  +	 /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,   										  S32 face = -1,                        // which face to check, -1 = ALL_SIDES  										  BOOL pick_transparent = FALSE,  										  S32* face_hit = NULL,                 // which face was hit -										  LLVector3* intersection = NULL,       // return the intersection point +										  LLVector4a* intersection = NULL,       // return the intersection point  										  LLVector2* tex_coord = NULL,          // return the texture coordinates of the intersection point -										  LLVector3* normal = NULL,             // return the surface normal at the intersection point -										  LLVector3* bi_normal = NULL           // return the surface bi-normal at the intersection point +										  LLVector4a* normal = NULL,             // return the surface normal at the intersection point +										  LLVector4a* tangent = NULL           // return the surface tangent at the intersection point  		);  	static S32 sMaxTreeSpecies; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 126055c8fb..eeb6c48b04 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -36,6 +36,7 @@  #include "lldir.h"  #include "llflexibleobject.h"  #include "llfloatertools.h" +#include "llmaterialid.h"  #include "llmaterialtable.h"  #include "llprimitive.h"  #include "llvolume.h" @@ -76,6 +77,7 @@  #include "llviewershadermgr.h"  #include "llvoavatar.h"  #include "llvocache.h" +#include "llmaterialmgr.h"  const S32 MIN_QUIET_FRAMES_COALESCE = 30;  const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; @@ -554,36 +556,8 @@ void LLVOVolume::animateTextures()  				tex_mat.setIdentity();  				LLVector3 trans ; -				if(facep->isAtlasInUse()) -				{ -					// -					//if use atlas for animated texture -					//apply the following transform to the animation matrix. -					// - -					F32 tcoord_xoffset = 0.f ; -					F32 tcoord_yoffset = 0.f ; -					F32 tcoord_xscale = 1.f ; -					F32 tcoord_yscale = 1.f ;			 -					if(facep->isAtlasInUse()) -					{ -						const LLVector2* tmp = facep->getTexCoordOffset() ; -						tcoord_xoffset = tmp->mV[0] ;  -						tcoord_yoffset = tmp->mV[1] ; - -						tmp = facep->getTexCoordScale() ; -						tcoord_xscale = tmp->mV[0] ;  -						tcoord_yscale = tmp->mV[1] ;	 -					} -					trans.set(LLVector3(tcoord_xoffset + tcoord_xscale * (off_s+0.5f), tcoord_yoffset + tcoord_yscale * (off_t+0.5f), 0.f)); - -					tex_mat.translate(LLVector3(-(tcoord_xoffset + tcoord_xscale * 0.5f), -(tcoord_yoffset + tcoord_yscale * 0.5f), 0.f)); -				} -				else	//non atlas -				{  					trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));			  					tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); -				}  				LLVector3 scale(scale_s, scale_t, 1.f);			  				LLQuaternion quat; @@ -918,6 +892,12 @@ LLFace* LLVOVolume::addFace(S32 f)  {  	const LLTextureEntry* te = getTE(f);  	LLViewerTexture* imagep = getTEImage(f); +	if (te->getMaterialParams().notNull()) +	{ +		LLViewerTexture* normalp = getTENormalMap(f); +		LLViewerTexture* specularp = getTESpecularMap(f); +		return mDrawable->addFace(te, imagep, normalp, specularp); +	}  	return mDrawable->addFace(te, imagep);  } @@ -1066,7 +1046,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo  				{ //already cached  					break;  				} -				volume->genBinormals(i); +				volume->genTangents(i);  				LLFace::cacheFaceInVRAM(face);  			}  		} @@ -1143,7 +1123,7 @@ void LLVOVolume::sculpt()  			{	// Log first time, then every 100 afterwards otherwise this can flood the logs  				llwarns << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID()   					<< " at " << current_discard  -				<< " is less than -2." << llendl; +					<< " is less than -2." << llendl;  				low_sculpty_discard_warning_count = 0;  			} @@ -1157,7 +1137,7 @@ void LLVOVolume::sculpt()  			{	// Log first time, then every 100 afterwards otherwise this can flood the logs  				llwarns << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID()   					<< " at " << current_discard  -				<< " is more than than allowed max of " << MAX_DISCARD_LEVEL << llendl; +					<< " is more than than allowed max of " << MAX_DISCARD_LEVEL << llendl;  				high_sculpty_discard_warning_count = 0;  			} @@ -1415,6 +1395,11 @@ void LLVOVolume::regenFaces()  		facep->setTEOffset(i);  		facep->setTexture(getTEImage(i)); +		if (facep->getTextureEntry()->getMaterialParams().notNull()) +		{ +			facep->setNormalMap(getTENormalMap(i)); +			facep->setSpecularMap(getTESpecularMap(i)); +		}  		facep->setViewerObject(this);  		// If the face had media on it, this will have broken the link between the LLViewerMediaTexture and the face. @@ -1876,7 +1861,7 @@ S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color)  	const LLTextureEntry *tep = getTE(te);  	if (!tep)  	{ -		llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl; +		LL_WARNS("MaterialTEs") << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;  	}  	else if (color != tep->getColor())  	{ @@ -1988,6 +1973,62 @@ S32 LLVOVolume::setTEGlow(const U8 te, const F32 glow)  	return  res;  } +void LLVOVolume::setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID &pMaterialID, const LLMaterialPtr pMaterialParams, U32 te) +{ +	LLVOVolume* pVol = (LLVOVolume*)gObjectList.findObject(objectID); +	if (pVol) +	{ +		LL_DEBUGS("MaterialTEs") << "materialid " << pMaterialID.asString() << " to TE " << te << LL_ENDL; +		if (te >= pVol->getNumTEs()) +			return; + +		LLTextureEntry* texture_entry = pVol->getTE(te); +		if (texture_entry && (texture_entry->getMaterialID() == pMaterialID)) +		{ +			pVol->setTEMaterialParams(te, pMaterialParams); +		} +	} +} + +S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) +{ +	S32 res = LLViewerObject::setTEMaterialID(te, pMaterialID); +	LL_DEBUGS("MaterialTEs") << "te "<< (S32)te << " materialid " << pMaterialID.asString() << " res " << res +								<< ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" ) +								<< LL_ENDL; +		 +	LL_DEBUGS("MaterialTEs") << " " << pMaterialID.asString() << LL_ENDL; +	if (res) +	{ +		LLMaterialMgr::instance().getTE(getRegion()->getRegionID(), pMaterialID, te, boost::bind(&LLVOVolume::setTEMaterialParamsCallbackTE, getID(), _1, _2, _3)); + +		setChanged(ALL_CHANGED); +		if (!mDrawable.isNull()) +		{ +			gPipeline.markTextured(mDrawable); +			gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL); +		} +		mFaceMappingChanged = TRUE; +	} +	return res; +} + +S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) +{ +	S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams); +	LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res +							 << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" ) +							 << LL_ENDL; +	setChanged(ALL_CHANGED); +	if (!mDrawable.isNull()) +	{ +		gPipeline.markTextured(mDrawable); +		gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL); +	} +	mFaceMappingChanged = TRUE; +	return TEM_CHANGE_TEXTURE; +} +  S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t)  {  	S32 res = LLViewerObject::setTEScale(te, s, t); @@ -3573,8 +3614,8 @@ LLVector3 LLVOVolume::volumeDirectionToAgent(const LLVector3& dir) const  } -BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp, -									  LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) +BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp, +									  LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)  {  	if (!mbCanSelect  @@ -3606,23 +3647,25 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  	if (volume)  	{	 -		LLVector3 v_start, v_end, v_dir; +		LLVector4a local_start = start; +		LLVector4a local_end = end;  		if (transform)  		{ -			v_start = agentPositionToVolume(start); -			v_end = agentPositionToVolume(end); -		} -		else -		{ -			v_start = start; -			v_end = end; +			LLVector3 v_start(start.getF32ptr()); +			LLVector3 v_end(end.getF32ptr()); +		 +			v_start = agentPositionToVolume(v_start); +			v_end = agentPositionToVolume(v_end); + +			local_start.load3(v_start.mV); +			local_end.load3(v_end.mV);  		} -		LLVector3 p; -		LLVector3 n; +		LLVector4a p; +		LLVector4a n;  		LLVector2 tc; -		LLVector3 bn; +		LLVector4a tn;  		if (intersection != NULL)  		{ @@ -3639,9 +3682,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  			n = *normal;  		} -		if (bi_normal != NULL) +		if (tangent != NULL)  		{ -			bn = *bi_normal; +			tn = *tangent;  		}  		S32 face_hit = -1; @@ -3667,8 +3710,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  				continue;  			} -			face_hit = volume->lineSegmentIntersect(v_start, v_end, i, -													&p, &tc, &n, &bn); +			face_hit = volume->lineSegmentIntersect(local_start, local_end, i, +													&p, &tc, &n, &tn);  			if (face_hit >= 0 && mDrawable->getNumFaces() > face_hit)  			{ @@ -3677,7 +3720,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  				if (face &&  					(pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))))  				{ -					v_end = p; +					local_end = p;  					if (face_hitp != NULL)  					{  						*face_hitp = face_hit; @@ -3687,7 +3730,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  					{  						if (transform)  						{ -							*intersection = volumePositionToAgent(p);  // must map back to agent space +							LLVector3 v_p(p.getF32ptr()); + +							intersection->load3(volumePositionToAgent(v_p).mV);  // must map back to agent space  						}  						else  						{ @@ -3699,27 +3744,36 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e  					{  						if (transform)  						{ -							*normal = volumeDirectionToAgent(n); +							LLVector3 v_n(n.getF32ptr()); +							normal->load3(volumeDirectionToAgent(v_n).mV);  						}  						else  						{  							*normal = n;  						} - -						(*normal).normVec(); +						(*normal).normalize3fast();  					} -					if (bi_normal != NULL) +					if (tangent != NULL)  					{  						if (transform)  						{ -							*bi_normal = volumeDirectionToAgent(bn); +							LLVector3 v_tn(tn.getF32ptr()); + +							LLVector4a trans_tangent; +							trans_tangent.load3(volumeDirectionToAgent(v_tn).mV); + +							LLVector4Logical mask; +							mask.clear(); +							mask.setElement<3>(); + +							tangent->setSelectWithMask(mask, tn, trans_tangent);  						}  						else  						{ -							*bi_normal = bn; +							*tangent = tn;  						} -						(*bi_normal).normVec(); +						(*tangent).normalize3fast();  					}  					if (tex_coord != NULL) @@ -3976,6 +4030,11 @@ bool can_batch_texture(LLFace* facep)  		return false;  	} +	if (facep->getTextureEntry()->getMaterialParams().notNull()) +	{ //materials don't work with texture batching yet +		return false; +	} +  	if (facep->getTexture() && facep->getTexture()->getPrimaryFormat() == GL_ALPHA)  	{ //can't batch invisiprims  		return false; @@ -3994,6 +4053,10 @@ static LLFastTimer::DeclareTimer FTM_REGISTER_FACE("Register Face");  void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type)  {  	LLFastTimer t(FTM_REGISTER_FACE); +	if (type == LLRenderPass::PASS_ALPHA && facep->getTextureEntry()->getMaterialParams().notNull() && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT)) +	{ +		LL_WARNS("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL; +	}  	if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects)  	{ @@ -4007,7 +4070,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  	BOOL fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) ||  		(type == LLRenderPass::PASS_INVISIBLE) || -		(type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)); +		(type == LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK) || +		(type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)) || +		(facep->getTextureEntry()->getFullbright());  	if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_NORMAL))  	{ @@ -4041,16 +4106,39 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  	//drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD)));  	U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? facep->getTextureEntry()->getBumpmap() : 0; +	U8 shiny = facep->getTextureEntry()->getShiny();  	LLViewerTexture* tex = facep->getTexture();  	U8 index = facep->getTextureIndex(); +	LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get();  +	LLMaterialID mat_id = facep->getTextureEntry()->getMaterialID(); +  	bool batchable = false; +	U32 shader_mask = 0xFFFFFFFF; //no shader + +	if (mat) +	{ +		if (type == LLRenderPass::PASS_ALPHA) +		{ +			shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND); +		} +		else +		{ +			shader_mask = mat->getShaderMask(); +		} +	} + +  	if (index < 255 && idx >= 0)  	{ -		if (index < draw_vec[idx]->mTextureList.size()) +		if (mat || draw_vec[idx]->mMaterial) +		{ //can't batch textures when materials are present (yet) +			batchable = false; +		} +		else if (index < draw_vec[idx]->mTextureList.size())  		{  			if (draw_vec[idx]->mTextureList[index].isNull())  			{ @@ -4076,16 +4164,20 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange &&  		draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&  #endif +		draw_vec[idx]->mMaterial == mat && +		draw_vec[idx]->mMaterialID == mat_id &&  		draw_vec[idx]->mFullbright == fullbright &&  		draw_vec[idx]->mBump == bump && +		(!mat || (draw_vec[idx]->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different  		draw_vec[idx]->mTextureMatrix == tex_mat && -		draw_vec[idx]->mModelMatrix == model_mat) +		draw_vec[idx]->mModelMatrix == model_mat && +		draw_vec[idx]->mShaderMask == shader_mask)  	{  		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()) +		if (index < 255 && index >= draw_vec[idx]->mTextureList.size())  		{  			draw_vec[idx]->mTextureList.resize(index+1);  			draw_vec[idx]->mTextureList[index] = tex; @@ -4107,6 +4199,60 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		draw_vec.push_back(draw_info);  		draw_info->mTextureMatrix = tex_mat;  		draw_info->mModelMatrix = model_mat; +		 +		draw_info->mBump  = bump; +		draw_info->mShiny = shiny; + +		float alpha[4] = +		{ +			0.00f, +			0.25f, +			0.5f, +			0.75f +		}; +		float spec = alpha[shiny & TEM_SHINY_MASK]; +		LLVector4 specColor(spec, spec, spec, spec); +		draw_info->mSpecColor = specColor; +		draw_info->mEnvIntensity = spec; +		draw_info->mSpecularMap = NULL; +		draw_info->mMaterial = mat; +		draw_info->mShaderMask = shader_mask; + +		if (mat) +		{ +				draw_info->mMaterialID = mat_id; + +				// We have a material.  Update our draw info accordingly. +				 +				if (!mat->getSpecularID().isNull()) +				{ +					LLVector4 specColor; +					specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f); +					specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f); +					specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f); +					specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f); +					draw_info->mSpecColor = specColor; +					draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f); +					draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset()); +				} + +				draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f); +				draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode(); +				draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset()); +				 +		} +		else  +		{ +			if (type == LLRenderPass::PASS_GRASS) +			{ +				draw_info->mAlphaMaskCutoff = 0.5f; +			} +			else +			{ +				draw_info->mAlphaMaskCutoff = 0.33f; +			} +		} +		  		if (type == LLRenderPass::PASS_ALPHA)  		{ //for alpha sorting  			facep->setDrawInfo(draw_info); @@ -4224,6 +4370,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	std::vector<LLFace*> fullbright_faces;  	std::vector<LLFace*> bump_faces; +	std::vector<LLFace*> norm_faces; +	std::vector<LLFace*> spec_faces; +	std::vector<LLFace*> normspec_faces;  	std::vector<LLFace*> simple_faces;  	std::vector<LLFace*> alpha_faces; @@ -4263,7 +4412,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  			}  			if (vobj->isMesh() && -				(vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled())) +				((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled()))  			{  				continue;  			} @@ -4390,6 +4539,66 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  						LLViewerTexture* tex = facep->getTexture();  						U32 type = gPipeline.getPoolTypeFromTE(te, tex); + +						if (te->getGlow()) +						{ +							pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW); +						} + +						LLMaterial* mat = te->getMaterialParams().get(); + +						if (mat && LLPipeline::sRenderDeferred) +						{ +							U8 alpha_mode = mat->getDiffuseAlphaMode(); + +							bool is_alpha = type == LLDrawPool::POOL_ALPHA && +								(alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND || +								te->getColor().mV[3] < 0.999f); + +							if (is_alpha) +							{ //this face needs alpha blending, override alpha mode +								alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; +							} + +							if (!is_alpha || te->getColor().mV[3] > 0.f)  // //only add the face if it will actually be visible +							{  +								U32 mask = mat->getShaderMask(alpha_mode); +								pool->addRiggedFace(facep, mask); +							} +						} +						else if (mat) +						{ +							bool fullbright = te->getFullbright(); +							bool is_alpha = type == LLDrawPool::POOL_ALPHA; +							U8 mode = mat->getDiffuseAlphaMode(); +							bool can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE || +												mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE; +							 +							if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && te->getColor().mV[3] >= 0.999f) +							{ +								pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE); +							} +							else if (is_alpha || (te->getColor().mV[3] < 0.999f)) +							{ +								if (te->getColor().mV[3] > 0.f) +								{ +									pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA : LLDrawPoolAvatar::RIGGED_ALPHA); +								} +							} +							else if (gPipeline.canUseVertexShaders() +								&& LLPipeline::sRenderBump  +								&& te->getShiny()  +								&& can_be_shiny) +							{ +								pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY : LLDrawPoolAvatar::RIGGED_SHINY); +							} +							else +							{ +								pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE); +							} +						} +						else +						{  						if (type == LLDrawPool::POOL_ALPHA)  						{  							if (te->getColor().mV[3] > 0.f) @@ -4434,10 +4643,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  							}  						} -						if (te->getGlow()) -						{ -							pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW); -						}  						if (LLPipeline::sRenderDeferred)  						{ @@ -4454,6 +4659,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  							}  						}  					} +					}  					continue;  				} @@ -4559,8 +4765,31 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  						if (gPipeline.canUseWindLightShadersOnObjects()  							&& LLPipeline::sRenderBump)  						{ -							if (te->getBumpmap()) -							{ //needs normal + binormal +							if (LLPipeline::sRenderDeferred && te->getMaterialParams().notNull()  && !te->getMaterialID().isNull()) +							{ +								LLMaterial* mat = te->getMaterialParams().get(); +								if (mat->getNormalID().notNull()) +								{ +									if (mat->getSpecularID().notNull()) +									{ //has normal and specular maps (needs texcoord1, texcoord2, and tangent) +										normspec_faces.push_back(facep); +									} +									else +									{ //has normal map (needs texcoord1 and tangent) +										norm_faces.push_back(facep); +									} +								} +								else if (mat->getSpecularID().notNull()) +								{ //has specular map but no normal map, needs texcoord2 +									spec_faces.push_back(facep); +								} +								else +								{ //has neither specular map nor normal map, only needs texcoord0 +									simple_faces.push_back(facep); +								}									 +							} +							else if (te->getBumpmap()) +							{ //needs normal + tangent  								bump_faces.push_back(facep);  							}  							else if (te->getShiny() || !te->getFullbright()) @@ -4576,7 +4805,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  						else  						{  							if (te->getBumpmap() && LLPipeline::sRenderBump) -							{ //needs normal + binormal +							{ //needs normal + tangent  								bump_faces.push_back(facep);  							}  							else if ((te->getShiny() && LLPipeline::sRenderBump) || @@ -4617,32 +4846,38 @@ 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; +	U32 norm_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TANGENT; +	U32 normspec_mask = norm_mask | LLVertexBuffer::MAP_TEXCOORD2; +	U32 spec_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD2; +  	if (emissive)  	{ //emissive faces are present, include emissive byte to preserve batching  		simple_mask = simple_mask | LLVertexBuffer::MAP_EMISSIVE;  		alpha_mask = alpha_mask | LLVertexBuffer::MAP_EMISSIVE;  		bump_mask = bump_mask | LLVertexBuffer::MAP_EMISSIVE;  		fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_EMISSIVE; +		norm_mask = norm_mask | LLVertexBuffer::MAP_EMISSIVE; +		normspec_mask = normspec_mask | LLVertexBuffer::MAP_EMISSIVE; +		spec_mask = spec_mask | LLVertexBuffer::MAP_EMISSIVE;  	} -	bool batch_textures = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1; +	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); +		bump_mask = bump_mask | LLVertexBuffer::MAP_TANGENT; +		simple_mask = simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX; +		alpha_mask = alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2; +		fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX;  	} +	genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, FALSE, batch_textures, FALSE); +	genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, FALSE, batch_textures); +	genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, TRUE, batch_textures); +	genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, FALSE, FALSE); +	genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, norm_faces, FALSE, FALSE); +	genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, spec_faces, FALSE, FALSE); +	genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, normspec_faces, FALSE, FALSE);  	if (!LLPipeline::sDelayVBUpdate)  	{ @@ -4801,11 +5036,18 @@ struct CompareBatchBreakerModified  		{  			return lte->getFullbright() < rte->getFullbright();  		} +		else if (LLPipeline::sRenderDeferred && lte->getMaterialParams() != rte->getMaterialParams()) +		{ +			return lte->getMaterialParams() < rte->getMaterialParams(); +		} +		else if (LLPipeline::sRenderDeferred && (lte->getMaterialParams() == rte->getMaterialParams()) && (lte->getShiny() != rte->getShiny())) +		{ +			return lte->getShiny() < rte->getShiny(); +		}  		else  		{  			return lhs->getTexture() < rhs->getTexture();  		} -		  	}  }; @@ -4819,7 +5061,7 @@ static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB"); -void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures) +void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures, BOOL no_materials)  {  	LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); @@ -4889,6 +5131,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  		//pull off next face  		LLFace* facep = *face_iter;  		LLViewerTexture* tex = facep->getTexture(); +		LLMaterialPtr mat = facep->getTextureEntry()->getMaterialParams();  		if (distance_sort)  		{ @@ -4934,6 +5177,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  						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 +							facep->setTextureIndex(0);  							break;  						} @@ -4984,13 +5228,20 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  						facep->setTextureIndex(cur_tex);  					}  				} +				else +				{ +					facep->setTextureIndex(0); +				}  				tex = texture_list[0];  			}  			else  			{  				while (i != faces.end() &&  -					(LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) +					(LLPipeline::sTextureBindTest ||  +						(distance_sort ||  +							((*i)->getTexture() == tex && +							((*i)->getTextureEntry()->getMaterialParams() == mat)))))  				{  					facep = *i; @@ -5077,7 +5328,6 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  			index_offset += facep->getGeomCount();  			indices_index += facep->getIndicesCount(); -  			//append face to appropriate render batch  			BOOL force_simple = facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA; @@ -5097,7 +5347,130 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  			BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE; -			if (is_alpha) +			LLMaterial* mat = te->getMaterialParams().get(); + +			bool can_be_shiny = true; +			if (mat) +			{ +				U8 mode = mat->getDiffuseAlphaMode(); +				can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE || +								mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE; +			} + +			bool use_legacy_bump = te->getBumpmap() && (!mat || mat->getNormalID().isNull()); + +			if (mat && LLPipeline::sRenderDeferred && !hud_group) +			{ +				bool material_pass = false; + +				if (fullbright) +				{ +					if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) +					{ +						if (te->getColor().mV[3] >= 0.999f) +						{ +							material_pass = true; +						} +						else +						{ +							registerFace(group, facep, LLRenderPass::PASS_ALPHA); +						} +					} +					else if (is_alpha) +					{ +						registerFace(group, facep, LLRenderPass::PASS_ALPHA); +					} +					else +					{ +						if (mat->getEnvironmentIntensity() > 0 || +							te->getShiny() > 0) +						{ +							material_pass = true; +						} +						else +						{ +							registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); +						} +					} +				} +				else if (no_materials) +				{ +					registerFace(group, facep, LLRenderPass::PASS_SIMPLE); +				} +				else if (te->getColor().mV[3] < 0.999f) +				{ +					registerFace(group, facep, LLRenderPass::PASS_ALPHA); +				} +				else if (use_legacy_bump) +				{ +					// we have a material AND legacy bump settings, but no normal map +					registerFace(group, facep, LLRenderPass::PASS_BUMP); +				} +				else +				{ +					material_pass = true; +				} + +				if (material_pass) +				{ +					U32 pass[] =  +					{ +						LLRenderPass::PASS_MATERIAL, +						LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_MATERIAL_ALPHA, +						LLRenderPass::PASS_MATERIAL_ALPHA_MASK, +						LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, +						LLRenderPass::PASS_SPECMAP, +						LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_SPECMAP_BLEND, +						LLRenderPass::PASS_SPECMAP_MASK, +						LLRenderPass::PASS_SPECMAP_EMISSIVE, +						LLRenderPass::PASS_NORMMAP, +						LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMMAP_BLEND, +						LLRenderPass::PASS_NORMMAP_MASK, +						LLRenderPass::PASS_NORMMAP_EMISSIVE, +						LLRenderPass::PASS_NORMSPEC, +						LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMSPEC_BLEND, +						LLRenderPass::PASS_NORMSPEC_MASK, +						LLRenderPass::PASS_NORMSPEC_EMISSIVE, +					}; + +					U32 mask = mat->getShaderMask(); + +					llassert(mask < sizeof(pass)/sizeof(U32)); + +					mask = llmin(mask, (U32)(sizeof(pass)/sizeof(U32)-1)); + +					registerFace(group, facep, pass[mask]); +				} +			} +			else if (mat) +			{ +				U8 mode = mat->getDiffuseAlphaMode(); +				if (te->getColor().mV[3] < 0.999f) +				{ +					mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; +				} + +				if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) +				{ +					registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK : LLRenderPass::PASS_ALPHA_MASK); +				} +				else if (is_alpha || (te->getColor().mV[3] < 0.999f)) +				{ +					registerFace(group, facep, LLRenderPass::PASS_ALPHA); +				} +				else if (gPipeline.canUseVertexShaders() +					&& LLPipeline::sRenderBump  +					&& te->getShiny()  +					&& can_be_shiny) +				{ +					registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_SHINY); +				} +				else +				{ +					registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT : LLRenderPass::PASS_SIMPLE); +				} +			} +			else if (is_alpha)  			{  				// can we safely treat this as an alpha mask?  				if (facep->getFaceColor().mV[3] <= 0.f) @@ -5122,7 +5495,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  			}  			else if (gPipeline.canUseVertexShaders()  				&& LLPipeline::sRenderBump  -				&& te->getShiny()) +				&& te->getShiny()  +				&& can_be_shiny)  			{ //shiny  				if (tex->getPrimaryFormat() == GL_ALPHA)  				{ //invisiprim+shiny @@ -5139,7 +5513,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  							registerFace(group, facep, LLRenderPass::PASS_POST_BUMP);  						}  					} -					else if (te->getBumpmap()) +					else if (use_legacy_bump)  					{ //register in deferred bump pass  						registerFace(group, facep, LLRenderPass::PASS_BUMP);  					} @@ -5166,24 +5540,38 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  				}  				else if (fullbright || bake_sunlight)  				{ //fullbright +					if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) +					{ +						registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); +					} +					else +					{  					registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); -					if (LLPipeline::sRenderDeferred && !hud_group && LLPipeline::sRenderBump && te->getBumpmap()) +					} +					if (LLPipeline::sRenderDeferred && !hud_group && LLPipeline::sRenderBump && use_legacy_bump)  					{ //if this is the deferred render and a bump map is present, register in post deferred bump  						registerFace(group, facep, LLRenderPass::PASS_POST_BUMP);  					}  				}  				else  				{ -					if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && te->getBumpmap()) +					if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && use_legacy_bump)  					{ //non-shiny or fullbright deferred bump  						registerFace(group, facep, LLRenderPass::PASS_BUMP);  					}  					else  					{ //all around simple  						llassert(mask & LLVertexBuffer::MAP_NORMAL); +						if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) +						{ //material alpha mask can be respected in non-deferred +							registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK); +						} +						else +						{  						registerFace(group, facep, LLRenderPass::PASS_SIMPLE);  					}  				} +				}  				if (!gPipeline.canUseVertexShaders() &&  @@ -5201,7 +5589,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  				llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright);  				facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE); -				if (!force_simple && te->getBumpmap() && LLPipeline::sRenderBump) +				if (!force_simple && LLPipeline::sRenderBump && use_legacy_bump)  				{  					registerFace(group, facep, LLRenderPass::PASS_BUMP);  				} @@ -5290,4 +5678,3 @@ void LLHUDPartition::shift(const LLVector4a &offset)  	//HUD objects don't shift with region crossing.  That would be silly.  } - diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 5482c80f2b..7503f8c5aa 100755 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -31,12 +31,14 @@  #include "llviewertexture.h"  #include "llviewermedia.h"  #include "llframetimer.h" +#include "lllocalbitmaps.h"  #include "m3math.h"		// LLMatrix3  #include "m4math.h"		// LLMatrix4  #include <map>  class LLViewerTextureAnim;  class LLDrawPool; +class LLMaterialID;  class LLSelectNode;  class LLObjectMediaDataClient;  class LLObjectMediaNavigateClient; @@ -135,14 +137,14 @@ public:  	/*virtual*/ U32		getTriangleCount(S32* vcount = NULL) const;  	/*virtual*/ U32		getHighLODTriangleCount(); -	/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,  +	/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,   										  S32 face = -1,                        // which face to check, -1 = ALL_SIDES  										  BOOL pick_transparent = FALSE,  										  S32* face_hit = NULL,                 // which face was hit -										  LLVector3* intersection = NULL,       // return the intersection point +										  LLVector4a* intersection = NULL,       // return the intersection point  										  LLVector2* tex_coord = NULL,          // return the texture coordinates of the intersection point -										  LLVector3* normal = NULL,             // return the surface normal at the intersection point -										  LLVector3* bi_normal = NULL           // return the surface bi-normal at the intersection point +										  LLVector4a* normal = NULL,             // return the surface normal at the intersection point +										  LLVector4a* tangent = NULL           // return the surface tangent at the intersection point  		);  				LLVector3 agentPositionToVolume(const LLVector3& pos) const; @@ -157,6 +159,7 @@ public:  				const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const;  				void	markForUpdate(BOOL priority)			{ LLViewerObject::markForUpdate(priority); mVolumeChanged = TRUE; } +				void    faceMappingChanged()                    { mFaceMappingChanged=TRUE; };  	/*virtual*/ void	onShift(const LLVector4a &shift_vector); // Called when the drawable shifts @@ -185,6 +188,11 @@ public:  	/*virtual*/ S32		setTEBumpShinyFullbright(const U8 te, const U8 bump);  	/*virtual*/ S32		setTEMediaFlags(const U8 te, const U8 media_flags);  	/*virtual*/ S32		setTEGlow(const U8 te, const F32 glow); +	/*virtual*/ S32		setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); +	 +	static void	setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID& pMaterialID, const LLMaterialPtr pMaterialParams, U32 te); + +	/*virtual*/ S32		setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);  	/*virtual*/ S32		setTEScale(const U8 te, const F32 s, const F32 t);  	/*virtual*/ S32		setTEScaleS(const U8 te, const F32 s);  	/*virtual*/ S32		setTEScaleT(const U8 te, const F32 t); @@ -378,3 +386,4 @@ protected:  };  #endif // LL_LLVOVOLUME_H + diff --git a/indra/newview/llwlparamset.cpp b/indra/newview/llwlparamset.cpp index b04d30db55..dba3970635 100755 --- a/indra/newview/llwlparamset.cpp +++ b/indra/newview/llwlparamset.cpp @@ -33,6 +33,7 @@  #include "llglslshader.h"  #include "lluictrlfactory.h"  #include "llsliderctrl.h" +#include "pipeline.h"  #include <llgl.h> @@ -127,6 +128,13 @@ void LLWLParamSet::update(LLGLSLShader * shader) const  			}  		}  	} +	 +	if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && !LLPipeline::sUnderWaterRender) +	{ +		shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2); +	} else { +		shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0); +	}  }  void LLWLParamSet::set(const std::string& paramName, float x)  diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 42a0be9e2f..a95adbf442 100755 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -278,6 +278,8 @@ void LLWorld::removeRegion(const LLHost &host)  	mCulledRegionList.remove(regionp);  	mVisibleRegionList.remove(regionp); +	mRegionRemovedSignal(regionp); +  	delete regionp;  	updateWaterObjects(); @@ -405,6 +407,19 @@ LLViewerRegion* LLWorld::getRegionFromHandle(const U64 &handle)  	return NULL;  } +LLViewerRegion* LLWorld::getRegionFromID(const LLUUID& region_id) +{ +	for (region_list_t::iterator iter = mRegionList.begin(); +		 iter != mRegionList.end(); ++iter) +	{ +		LLViewerRegion* regionp = *iter; +		if (regionp->getRegionID() == region_id) +		{ +			return regionp; +		} +	} +	return NULL; +}  void LLWorld::updateAgentOffset(const LLVector3d &offset_global)  { @@ -717,9 +732,9 @@ void LLWorld::updateNetStats()  	S32 actual_in_bits = gMessageSystem->mPacketRing.getAndResetActualInBits();  	S32 actual_out_bits = gMessageSystem->mPacketRing.getAndResetActualOutBits(); -	add(LLStatViewer::ACTUAL_IN_KBIT, LLTrace::Bits(actual_in_bits)); -	add(LLStatViewer::ACTUAL_OUT_KBIT, LLTrace::Bits(actual_out_bits)); -	add(LLStatViewer::KBIT, LLTrace::Bits(bits)); +	add(LLStatViewer::ACTUAL_IN_KBIT, LLUnit<F64, LLUnits::Bits>(actual_in_bits)); +	add(LLStatViewer::ACTUAL_OUT_KBIT, LLUnit<F64, LLUnits::Bits>(actual_out_bits)); +	add(LLStatViewer::KBIT, LLUnit<F64, LLUnits::Bits>(bits));  	add(LLStatViewer::PACKETS_IN, packets_in);  	add(LLStatViewer::PACKETS_OUT, packets_out);  	add(LLStatViewer::PACKETS_LOST, packets_lost); @@ -1257,6 +1272,11 @@ bool LLWorld::isRegionListed(const LLViewerRegion* region) const  	return it != mRegionList.end();  } +boost::signals2::connection LLWorld::setRegionRemovedCallback(const region_remove_signal_t::slot_type& cb) +{ +	return mRegionRemovedSignal.connect(cb); +} +  LLHTTPRegistration<LLEstablishAgentCommunication>  	gHTTPRegistrationEstablishAgentCommunication(  							"/message/EstablishAgentCommunication"); diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index 8187142b2b..d94c27c428 100755 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -76,6 +76,7 @@ public:  	LLViewerRegion*			getRegionFromPosGlobal(const LLVector3d &pos);  	LLViewerRegion*			getRegionFromPosAgent(const LLVector3 &pos);  	LLViewerRegion*			getRegionFromHandle(const U64 &handle); +	LLViewerRegion*			getRegionFromID(const LLUUID& region_id);  	BOOL					positionRegionValidGlobal(const LLVector3d& pos);			// true if position is in valid region  	LLVector3d				clipToVisibleRegions(const LLVector3d &start_pos, const LLVector3d &end_pos); @@ -150,6 +151,9 @@ public:  	typedef std::list<LLViewerRegion*> region_list_t;  	const region_list_t& getRegionList() const { return mActiveRegionList; } +	typedef boost::signals2::signal<void(LLViewerRegion*)> region_remove_signal_t; +	boost::signals2::connection setRegionRemovedCallback(const region_remove_signal_t::slot_type& cb); +  	// Returns lists of avatar IDs and their world-space positions within a given distance of a point.  	// All arguments are optional. Given containers will be emptied and then filled.  	// Not supplying origin or radius input returns data on all avatars in the known regions. @@ -169,6 +173,8 @@ private:  	region_list_t	mVisibleRegionList;  	region_list_t	mCulledRegionList; +	region_remove_signal_t mRegionRemovedSignal; +  	// Number of points on edge  	static const U32 mWidth; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 7cf30e1661..c2f5b9b861 100755 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -236,6 +236,7 @@ LLFastTimer::DeclareTimer FTM_RENDER_WL_SKY("Windlight Sky");  LLFastTimer::DeclareTimer FTM_RENDER_ALPHA("Alpha Objects");  LLFastTimer::DeclareTimer FTM_RENDER_CHARACTERS("Avatars");  LLFastTimer::DeclareTimer FTM_RENDER_BUMP("Bump"); +LLFastTimer::DeclareTimer FTM_RENDER_MATERIALS("Materials");  LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT("Fullbright");  LLFastTimer::DeclareTimer FTM_RENDER_GLOW("Glow");  LLFastTimer::DeclareTimer FTM_GEO_UPDATE("Geo Update"); @@ -265,10 +266,13 @@ std::string gPoolNames[] =  	"POOL_GROUND",  	"POOL_FULLBRIGHT",  	"POOL_BUMP", +	"POOL_MATERIALS",  	"POOL_TERRAIN,"	  	"POOL_SKY",  	"POOL_WL_SKY",  	"POOL_TREE", +	"POOL_ALPHA_MASK", +	"POOL_FULLBRIGHT_ALPHA_MASK",  	"POOL_GRASS",  	"POOL_INVISIBLE",  	"POOL_AVATAR", @@ -355,6 +359,7 @@ BOOL	LLPipeline::sRenderParticleBeacons = FALSE;  BOOL	LLPipeline::sRenderSoundBeacons = FALSE;  BOOL	LLPipeline::sRenderBeacons = FALSE;  BOOL	LLPipeline::sRenderHighlight = TRUE; +LLRender::eTexIndex LLPipeline::sRenderHighlightTextureChannel = LLRender::DIFFUSE_MAP;  BOOL	LLPipeline::sForceOldBakedUpload = FALSE;  S32		LLPipeline::sUseOcclusion = 0;  BOOL	LLPipeline::sDelayVBUpdate = TRUE; @@ -380,6 +385,7 @@ BOOL	LLPipeline::sRenderDeferred = FALSE;  BOOL    LLPipeline::sMemAllocationThrottled = FALSE;  S32		LLPipeline::sVisibleLightCount = 0;  F32		LLPipeline::sMinRenderSize = 0.f; +BOOL	LLPipeline::sRenderingHUDs;  // EventHost API LLPipeline listener.  static LLPipelineListener sPipelineListener; @@ -401,8 +407,8 @@ void validate_framebuffer_object();  bool addDeferredAttachments(LLRenderTarget& target)  { -	return target.addColorAttachment(GL_RGBA) && //specular -			target.addColorAttachment(GL_RGBA); //normal+z	 +	return target.addColorAttachment(GL_SRGB8_ALPHA8) && //specular +			target.addColorAttachment(GL_RGB10_A2); //normal+z  }  LLPipeline::LLPipeline() : @@ -430,10 +436,14 @@ LLPipeline::LLPipeline() :  	mWaterPool(NULL),  	mGroundPool(NULL),  	mSimplePool(NULL), +	mGrassPool(NULL), +	mAlphaMaskPool(NULL), +	mFullbrightAlphaMaskPool(NULL),  	mFullbrightPool(NULL),  	mInvisiblePool(NULL),  	mGlowPool(NULL),  	mBumpPool(NULL), +	mMaterialsPool(NULL),  	mWLSkyPool(NULL),  	mLightMask(0),  	mLightMovingMask(0), @@ -480,10 +490,13 @@ void LLPipeline::init()  	//create render pass pools  	getPool(LLDrawPool::POOL_ALPHA);  	getPool(LLDrawPool::POOL_SIMPLE); +	getPool(LLDrawPool::POOL_ALPHA_MASK); +	getPool(LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK);  	getPool(LLDrawPool::POOL_GRASS);  	getPool(LLDrawPool::POOL_FULLBRIGHT);  	getPool(LLDrawPool::POOL_INVISIBLE);  	getPool(LLDrawPool::POOL_BUMP); +	getPool(LLDrawPool::POOL_MATERIALS);  	getPool(LLDrawPool::POOL_GLOW);  	resetFrameStats(); @@ -911,11 +924,22 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  		BOOL ssao = RenderDeferredSSAO;  		//allocate deferred rendering color buffers -		if (!mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; +		if (!mDeferredScreen.allocate(resX, resY, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;  		if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;  		if (!addDeferredAttachments(mDeferredScreen)) return false; -		if (!mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; +		GLuint screenFormat = GL_RGBA16; +		if (gGLManager.mIsATI) +		{ +			screenFormat = GL_RGBA12; +		} + +		if (gGLManager.mGLVersion < 4.f && gGLManager.mIsNVIDIA) +		{ +			screenFormat = GL_RGBA16F_ARB; +		} +		 +		if (!mScreen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;  		if (samples > 0)  		{  			if (!mFXAABuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; @@ -1006,11 +1030,18 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  }  //static +void LLPipeline::updateRenderBump() +{ +	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); +} + +//static  void LLPipeline::updateRenderDeferred()  {  	BOOL deferred = ((RenderDeferred &&   					 LLRenderTarget::sUseFBO &&  					 LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&	  +					 LLPipeline::sRenderBump &&  					 VertexShaderEnable &&   					 RenderAvatarVP &&  					 WindLightUseAtmosShaders) ? TRUE : FALSE) && @@ -1153,7 +1184,7 @@ void LLPipeline::releaseLUTBuffers()  {  	if (mLightFunc)  	{ -		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_R8, 0, 1, &mLightFunc); +		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_R16F, 0, 1, &mLightFunc);  		mLightFunc = 0;  	}  } @@ -1258,13 +1289,18 @@ void LLPipeline::createGLBuffers()  	gBumpImageList.restoreGL();  } +F32 lerpf(F32 a, F32 b, F32 w) +{ +	return a + w * (b - a); +} +  void LLPipeline::createLUTBuffers()  {  	if (sRenderDeferred)  	{  		if (!mLightFunc)  		{ -			U32 lightResX = gSavedSettings.getU32("RenderSpecularResX"); +			/*U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");  			U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");  			U8* ls = new U8[lightResX*lightResY];  			F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); @@ -1300,11 +1336,58 @@ void LLPipeline::createLUTBuffers()  					// Combined with a bit of noise and trilinear filtering, the banding is hardly noticable.  					ls[y*lightResX+x] = (U8)(llclamp(spec * (1.f / 6), 0.f, 1.f) * 255);  				} +			}*/ +		 + +			U32 lightResX = gSavedSettings.getU32("RenderSpecularResX"); +			U32 lightResY = gSavedSettings.getU32("RenderSpecularResY"); +			F32* ls = new F32[lightResX*lightResY]; +			//F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); // Note: only use this when creating new specular lighting functions. +            // Calculate the (normalized) blinn-phong specular lookup texture. (with a few tweaks) +			for (U32 y = 0; y < lightResY; ++y) +			{ +				for (U32 x = 0; x < lightResX; ++x) +				{ +					ls[y*lightResX+x] = 0; +					F32 sa = (F32) x/(lightResX-1); +					F32 spec = (F32) y/(lightResY-1); +					F32 n = spec * spec * 368; +					 +					// Nothing special here.  Just your typical blinn-phong term. +					spec = powf(sa, n); +					 +					// Apply our normalization function. +					// Note: This is the full equation that applies the full normalization curve, not an approximation. +					// This is fine, given we only need to create our LUT once per buffer initialization. +					spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n))); + +					// Since we use R16F, we no longer have a dynamic range issue we need to work around here. +					// Though some older drivers may not like this, newer drivers shouldn't have this problem. +					ls[y*lightResX+x] = spec; + +					 +					//beckmann distribution +					/*F32 alpha = acosf((F32) x/(lightResX-1)); +					F32 m = 1.f - (F32) y/(lightResY-1); + +					F32 cos4_alpha = cosf(alpha); +					cos4_alpha *= cos4_alpha; +					cos4_alpha *= cos4_alpha; + +					F32 tan_alpha = tanf(alpha); +					F32 tan2_alpha = tan_alpha*tan_alpha; + +					F32 k = expf(-(tan2_alpha)/(m*m)) / +						(3.14159f*m*m*cos4_alpha); + +					ls[y*lightResX+x] = k;*/ +				}  			} -			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R8, 1, &mLightFunc); +			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R16F, 1, &mLightFunc);  			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); -			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false); +			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R16F, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false); +			//LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_UNSIGNED_BYTE, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false);  			gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);  			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); @@ -1510,6 +1593,14 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)  		poolp = mGrassPool;  		break; +	case LLDrawPool::POOL_ALPHA_MASK: +		poolp = mAlphaMaskPool; +		break; + +	case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK: +		poolp = mFullbrightAlphaMaskPool; +		break; +  	case LLDrawPool::POOL_FULLBRIGHT:  		poolp = mFullbrightPool;  		break; @@ -1533,7 +1624,9 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)  	case LLDrawPool::POOL_BUMP:  		poolp = mBumpPool;  		break; - +	case LLDrawPool::POOL_MATERIALS: +		poolp = mMaterialsPool; +		break;  	case LLDrawPool::POOL_ALPHA:  		poolp = mAlphaPool;  		break; @@ -1597,20 +1690,44 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima  		return 0;  	} -	bool alpha = te->getColor().mV[3] < 0.999f; +	LLMaterial* mat = te->getMaterialParams().get(); + +	bool color_alpha = te->getColor().mV[3] < 0.999f; +	bool alpha = color_alpha;  	if (imagep)  	{  		alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2);  	} +	if (alpha && mat) +	{ +		switch (mat->getDiffuseAlphaMode()) +		{ +			case 1: +				alpha = true; // Material's alpha mode is set to blend.  Toss it into the alpha draw pool. +				break; +			case 0: //alpha mode set to none, never go to alpha pool +			case 3: //alpha mode set to emissive, never go to alpha pool +				alpha = color_alpha; +				break; +			default: //alpha mode set to "mask", go to alpha pool if fullbright +				alpha = color_alpha; // Material's alpha mode is set to none, mask, or emissive.  Toss it into the opaque material draw pool. +				break; +		} +	} +	  	if (alpha)  	{  		return LLDrawPool::POOL_ALPHA;  	} -	else if ((te->getBumpmap() || te->getShiny())) +	else if ((te->getBumpmap() || te->getShiny()) && (!mat || mat->getNormalID().isNull()))  	{  		return LLDrawPool::POOL_BUMP;  	} +	else if (mat && !alpha) +	{ +		return LLDrawPool::POOL_MATERIALS; +	}  	else  	{  		return LLDrawPool::POOL_SIMPLE; @@ -3571,8 +3688,8 @@ void LLPipeline::postSort(LLCamera& camera)  	for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)  	{  		LLSpatialGroup* group = *i; -		if (sUseOcclusion &&  -			group->isOcclusionState(LLSpatialGroup::OCCLUDED) || +		if ((sUseOcclusion &&  +			group->isOcclusionState(LLSpatialGroup::OCCLUDED)) ||  			(RenderAutoHideSurfaceAreaLimit > 0.f &&   			group->mSurfaceArea > RenderAutoHideSurfaceAreaLimit*llmax(group->mObjectBoxSize, 10.f)))  		{ @@ -3739,6 +3856,8 @@ void LLPipeline::postSort(LLCamera& camera)  	{  		mSelectedFaces.clear(); +		LLPipeline::setRenderHighlightTextureChannel(LLSelectMgr::getInstance()->getTextureChannel()); +  		// Draw face highlights for selected faces.  		if (LLSelectMgr::getInstance()->getTEMode())  		{ @@ -3934,13 +4053,14 @@ void LLPipeline::renderHighlights()  		gGL.diffuseColor4f(1,1,1,0.5f);  	} -	if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED)) -	{ -		// Make sure the selection image gets downloaded and decoded -		if (!mFaceSelectImagep) +	if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && !mFaceSelectImagep)  		{  			mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT);  		} + +	if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::DIFFUSE_MAP)) +	{ +		// Make sure the selection image gets downloaded and decoded  		mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);  		U32 count = mSelectedFaces.size(); @@ -3978,6 +4098,67 @@ void LLPipeline::renderHighlights()  	{  		gHighlightProgram.unbind();  	} + + +	if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP)) +	{ +		color.setVec(1.0f, 0.5f, 0.5f, 0.5f); +		if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) +		{ +			gHighlightNormalProgram.bind(); +			gGL.diffuseColor4f(1,1,1,0.5f); +		} + +		mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); + +		U32 count = mSelectedFaces.size(); +		for (U32 i = 0; i < count; i++) +		{ +			LLFace *facep = mSelectedFaces[i]; +			if (!facep || facep->getDrawable()->isDead()) +			{ +				llerrs << "Bad face on selection" << llendl; +				return; +			} + +			facep->renderSelected(mFaceSelectImagep, color); +		} + +		if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) +		{ +			gHighlightNormalProgram.unbind(); +		} +	} + +	if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP)) +	{ +		color.setVec(0.0f, 0.3f, 1.0f, 0.8f); +		if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) +		{ +			gHighlightSpecularProgram.bind(); +			gGL.diffuseColor4f(1,1,1,0.5f); +		} + +		mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); + +		U32 count = mSelectedFaces.size(); +		for (U32 i = 0; i < count; i++) +		{ +			LLFace *facep = mSelectedFaces[i]; +			if (!facep || facep->getDrawable()->isDead()) +			{ +				llerrs << "Bad face on selection" << llendl; +				return; +			} + +			facep->renderSelected(mFaceSelectImagep, color); +		} + +		if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) +		{ +			gHighlightSpecularProgram.unbind(); +		} +	}  }  //debug use @@ -4965,8 +5146,8 @@ void LLPipeline::renderDebug()  			LLSpatialPartition* part = region->getSpatialPartition(i);  			if (part)  			{ -				if ( hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES) || -					 !hud_only && hasRenderType(part->mDrawableType) ) +				if ( (hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES)) || +					 (!hud_only && hasRenderType(part->mDrawableType)) )  				{  					part->renderDebug();  				} @@ -5281,6 +5462,32 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )  		}  		break; +	case LLDrawPool::POOL_ALPHA_MASK: +		if (mAlphaMaskPool) +		{ +			llassert(0); +			llwarns << "Ignoring duplicate alpha mask pool." << llendl; +			break; +		} +		else +		{ +			mAlphaMaskPool = (LLRenderPass*) new_poolp; +		} +		break; + +	case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK: +		if (mFullbrightAlphaMaskPool) +		{ +			llassert(0); +			llwarns << "Ignoring duplicate alpha mask pool." << llendl; +			break; +		} +		else +		{ +			mFullbrightAlphaMaskPool = (LLRenderPass*) new_poolp; +		} +		break; +		  	case LLDrawPool::POOL_GRASS:  		if (mGrassPool)  		{ @@ -5348,7 +5555,17 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )  			mBumpPool = new_poolp;  		}  		break; - +	case LLDrawPool::POOL_MATERIALS: +		if (mMaterialsPool) +		{ +			llassert(0); +			llwarns << "Ignorning duplicate materials pool." << llendl; +		} +		else +		{ +			mMaterialsPool = new_poolp; +		} +		break;  	case LLDrawPool::POOL_ALPHA:  		if( mAlphaPool )  		{ @@ -5357,7 +5574,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )  		}  		else  		{ -			mAlphaPool = new_poolp; +			mAlphaPool = (LLDrawPoolAlpha*) new_poolp;  		}  		break; @@ -5437,6 +5654,16 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )  		mSimplePool = NULL;  		break; +	case LLDrawPool::POOL_ALPHA_MASK: +		llassert(mAlphaMaskPool == poolp); +		mAlphaMaskPool = NULL; +		break; + +	case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK: +		llassert(mFullbrightAlphaMaskPool == poolp); +		mFullbrightAlphaMaskPool = NULL; +		break; +  	case LLDrawPool::POOL_GRASS:  		llassert(mGrassPool == poolp);  		mGrassPool = NULL; @@ -5489,6 +5716,11 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )  		mBumpPool = NULL;  		break; +	case LLDrawPool::POOL_MATERIALS: +		llassert(poolp == mMaterialsPool); +		mMaterialsPool = NULL; +		break; +			  	case LLDrawPool::POOL_ALPHA:  		llassert( poolp == mAlphaPool );  		mAlphaPool = NULL; @@ -5551,6 +5783,13 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)  		LLLightState* light = gGL.getLight(1); +		if (LLPipeline::sRenderDeferred) +		{ +			diffuse.mV[0] = powf(diffuse.mV[0], 2.2f); +			diffuse.mV[1] = powf(diffuse.mV[1], 2.2f); +			diffuse.mV[2] = powf(diffuse.mV[2], 2.2f); +		} +  		mHWLightColors[1] = diffuse;  		light->setDiffuse(diffuse); @@ -5591,6 +5830,13 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)  		}  		backlight_diffuse *= backlight_mag / max_component; +		if (LLPipeline::sRenderDeferred) +		{ +			backlight_diffuse.mV[0] = powf(backlight_diffuse.mV[0], 2.2f); +			backlight_diffuse.mV[1] = powf(backlight_diffuse.mV[1], 2.2f); +			backlight_diffuse.mV[2] = powf(backlight_diffuse.mV[2], 2.2f); +		} +  		mHWLightColors[1] = backlight_diffuse;  		LLLightState* light = gGL.getLight(1); @@ -5797,6 +6043,14 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)  		LLVector4 light_pos(mSunDir, 0.0f);  		LLColor4 light_diffuse = mSunDiffuse; + +		if (LLPipeline::sRenderDeferred) +		{ +			light_diffuse.mV[0] = powf(light_diffuse.mV[0], 2.2f); +			light_diffuse.mV[1] = powf(light_diffuse.mV[1], 2.2f); +			light_diffuse.mV[2] = powf(light_diffuse.mV[2], 2.2f); +		} +  		mHWLightColors[0] = light_diffuse;  		LLLightState* light = gGL.getLight(0); @@ -5865,6 +6119,13 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)  			F32 x = (3.f * (1.f + light->getLightFalloff())); // why this magic?  probably trying to match a historic behavior.  			float linatten = x / (light_radius); // % of brightness at radius +			if (LLPipeline::sRenderDeferred) +			{ +				light_color.mV[0] = powf(light_color.mV[0], 2.2f); +				light_color.mV[1] = powf(light_color.mV[1], 2.2f); +				light_color.mV[2] = powf(light_color.mV[2], 2.2f); +			} +  			mHWLightColors[cur_light] = light_color;  			LLLightState* light_state = gGL.getLight(cur_light); @@ -5938,6 +6199,13 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)  			F32 x = 3.f;  		float linatten = x / (light_radius); // % of brightness at radius +		if (LLPipeline::sRenderDeferred) +		{ +			light_color.mV[0] = powf(light_color.mV[0], 2.2f); +			light_color.mV[1] = powf(light_color.mV[1], 2.2f); +			light_color.mV[2] = powf(light_color.mV[2], 2.2f); +		} +  		mHWLightColors[2] = light_color;  		LLLightState* light = gGL.getLight(2); @@ -6578,20 +6846,26 @@ BOOL LLPipeline::getRenderHighlights(void*)  	return sRenderHighlight;  } -LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end, +// static +void LLPipeline::setRenderHighlightTextureChannel(LLRender::eTexIndex channel) +{ +	sRenderHighlightTextureChannel = channel; +} + +LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,  														BOOL pick_transparent,												  														S32* face_hit, -														LLVector3* intersection,         // return the intersection point +														LLVector4a* intersection,         // return the intersection point  														LLVector2* tex_coord,            // return the texture coordinates of the intersection point -														LLVector3* normal,               // return the surface normal at the intersection point -														LLVector3* bi_normal             // return the surface bi-normal at the intersection point +														LLVector4a* normal,               // return the surface normal at the intersection point +														LLVector4a* tangent             // return the surface tangent at the intersection point  	)  {  	LLDrawable* drawable = NULL; -	LLVector3 local_end = end; +	LLVector4a local_end = end; -	LLVector3 position; +	LLVector4a position;  	sPickAvatar = FALSE; //LLToolMgr::getInstance()->inBuildMode() ? FALSE : TRUE; @@ -6611,7 +6885,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,  				LLSpatialPartition* part = region->getSpatialPartition(j);  				if (part && hasRenderType(part->mDrawableType))  				{ -					LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal); +					LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent);  					if (hit)  					{  						drawable = hit; @@ -6626,8 +6900,8 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,  	{  		//save hit info in case we need to restore  		//due to attachment override -		LLVector3 local_normal; -		LLVector3 local_binormal; +		LLVector4a local_normal; +		LLVector4a local_tangent;  		LLVector2 local_texcoord;  		S32 local_face_hit = -1; @@ -6639,14 +6913,22 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,  		{  			local_texcoord = *tex_coord;  		} -		if (bi_normal) +		if (tangent) +		{ +			local_tangent = *tangent; +		} +		else  		{ -			local_binormal = *bi_normal; +			local_tangent.clear();  		}  		if (normal)  		{  			local_normal = *normal;  		} +		else +		{ +			local_normal.clear(); +		}  		const F32 ATTACHMENT_OVERRIDE_DIST = 0.1f; @@ -6660,12 +6942,15 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,  			LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE);  			if (part && hasRenderType(part->mDrawableType))  			{ -				LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal); +				LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent);  				if (hit)  				{ +					LLVector4a delta; +					delta.setSub(position, local_end); +  					if (!drawable ||   						!drawable->getVObj()->isAttachment() || -						(position-local_end).magVec() > ATTACHMENT_OVERRIDE_DIST) +						delta.getLength3().getF32() > ATTACHMENT_OVERRIDE_DIST)  					{ //avatar overrides if previously hit drawable is not an attachment or   					  //attachment is far enough away from detected intersection  						drawable = hit; @@ -6683,9 +6968,9 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,  						{  							*tex_coord = local_texcoord;  						} -						if (bi_normal) +						if (tangent)  						{ -							*bi_normal = local_binormal; +							*tangent = local_tangent;  						}  						if (normal)  						{ @@ -6719,13 +7004,13 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,  	return drawable ? drawable->getVObj().get() : NULL;  } -LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end, +LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end,  													  BOOL pick_transparent,													  													  S32* face_hit, -													  LLVector3* intersection,         // return the intersection point +													  LLVector4a* intersection,         // return the intersection point  													  LLVector2* tex_coord,            // return the texture coordinates of the intersection point -													  LLVector3* normal,               // return the surface normal at the intersection point -													  LLVector3* bi_normal             // return the surface bi-normal at the intersection point +													  LLVector4a* normal,               // return the surface normal at the intersection point +													  LLVector4a* tangent				// return the surface tangent at the intersection point  	)  {  	LLDrawable* drawable = NULL; @@ -6745,7 +7030,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, co  		LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD);  		if (part)  		{ -			LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, bi_normal); +			LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, tangent);  			if (hit)  			{  				drawable = hit; @@ -6791,7 +7076,7 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable)  }  void LLPipeline::resetVertexBuffers() -{ +{	  	mResetVertexBuffers = true;  } @@ -6849,7 +7134,9 @@ void LLPipeline::doResetVertexBuffers()  	LLVertexBuffer::unbind();	 -	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); +	updateRenderBump(); +	updateRenderDeferred(); +  	sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");  	LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");  	LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO"); @@ -6875,6 +7162,17 @@ void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture, BOOL batch_text  	gGLLastMatrix = NULL;		  } +void LLPipeline::renderMaskedObjects(U32 type, U32 mask, BOOL texture, BOOL batch_texture) +{ +	assertInitialized(); +	gGL.loadMatrix(gGLModelView); +	gGLLastMatrix = NULL; +	mAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture); +	gGL.loadMatrix(gGLModelView); +	gGLLastMatrix = NULL;		 +} + +  void apply_cube_face_rotation(U32 face)  {  	switch (face) @@ -7151,13 +7449,18 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  			{  				if (LLViewerJoystick::getInstance()->getOverrideCamera())  				{ //focus on point under cursor -					focus_point = gDebugRaycastIntersection; +					focus_point.set(gDebugRaycastIntersection.getF32ptr());  				}  				else if (gAgentCamera.cameraMouselook())  				{ //focus on point under mouselook crosshairs +					LLVector4a result; +					result.clear(); +  					gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE,  													NULL, -													&focus_point); +													&result); + +					focus_point.set(result.getF32ptr());  				}  				else  				{ @@ -7318,6 +7621,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  					gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);  				} +				if (!LLViewerCamera::getInstance()->cameraUnderWater()) +				{ +					shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2); +				} else { +					shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0); +				} +  				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);  				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);  				shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width-1); @@ -7359,6 +7669,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  				mScreen.bindTexture(0, channel);  			} +			if (!LLViewerCamera::getInstance()->cameraUnderWater()) +			{ +				shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2); +			} else { +				shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0); +			} +  			gGL.begin(LLRender::TRIANGLE_STRIP);  			gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);  			gGL.vertex2f(-1,-1); @@ -7778,6 +8095,22 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n  	}  } +LLColor3 pow3f(LLColor3 v, F32 f) +{ +	v.mV[0] = powf(v.mV[0], f); +	v.mV[1] = powf(v.mV[1], f); +	v.mV[2] = powf(v.mV[2], f); +	return v; +} + +LLVector4 pow4fsrgb(LLVector4 v, F32 f) +{ +	v.mV[0] = powf(v.mV[0], f); +	v.mV[1] = powf(v.mV[1], f); +	v.mV[2] = powf(v.mV[2], f); +	return v; +} +  static LLFastTimer::DeclareTimer FTM_GI_TRACE("Trace");  static LLFastTimer::DeclareTimer FTM_GI_GATHER("Gather");  static LLFastTimer::DeclareTimer FTM_SUN_SHADOW("Shadow Map"); @@ -8110,6 +8443,10 @@ void LLPipeline::renderDeferredLighting()  								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*s); @@ -8166,6 +8503,9 @@ void LLPipeline::renderDeferredLighting()  					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*s); @@ -8215,8 +8555,12 @@ void LLPipeline::renderDeferredLighting()  					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]-sqrtf(light[count].mV[3]), far_z); - +					//col[count] = pow4fsrgb(col[count], 2.2f);  					count++;  					if (count == max_count || fullscreen_lights.empty())  					{ @@ -8258,6 +8602,10 @@ void LLPipeline::renderDeferredLighting()  					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*s);  					gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); @@ -8277,6 +8625,65 @@ void LLPipeline::renderDeferredLighting()  		gGL.setColorMask(true, true);  	} +	mScreen.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) mScreen.getWidth()*2, +				  (F32) mScreen.getHeight()*2); + +		mScreen.bindTarget(); +		// Apply gamma correction to the frame here. +		gDeferredPostGammaCorrectProgram.bind(); +		//mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +		S32 channel = 0; +		channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); +		if (channel > -1) +		{ +			mScreen.bindTexture(0,channel); +			gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +		} +		 +		gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mScreen.getWidth(), mScreen.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(mScreen.getUsage()); +		gDeferredPostGammaCorrectProgram.unbind(); +		mScreen.flush(); +	} + +	gGL.matrixMode(LLRender::MM_PROJECTION); +	gGL.popMatrix(); +	gGL.matrixMode(LLRender::MM_MODELVIEW); +	gGL.popMatrix();	 + +	mScreen.bindTarget(); +  	{ //render non-deferred geometry (alpha, fullbright, glow)  		LLGLDisable blend(GL_BLEND);  		LLGLDisable stencil(GL_STENCIL_TEST); @@ -8301,6 +8708,8 @@ void LLPipeline::renderDeferredLighting()  						 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()); @@ -8853,11 +9262,22 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera  		LLRenderPass::PASS_FULLBRIGHT,   		LLRenderPass::PASS_SHINY,   		LLRenderPass::PASS_BUMP,  -		LLRenderPass::PASS_FULLBRIGHT_SHINY  +		LLRenderPass::PASS_FULLBRIGHT_SHINY , +		LLRenderPass::PASS_MATERIAL, +		LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, +		LLRenderPass::PASS_SPECMAP, +		LLRenderPass::PASS_SPECMAP_EMISSIVE, +		LLRenderPass::PASS_NORMMAP, +		LLRenderPass::PASS_NORMMAP_EMISSIVE, +		LLRenderPass::PASS_NORMSPEC, +		LLRenderPass::PASS_NORMSPEC_EMISSIVE,  	};  	LLGLEnable cull(GL_CULL_FACE); +	//enable depth clamping if available +	LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0); +  	if (use_shader)  	{  		gDeferredShadowCubeProgram.bind(); @@ -8924,7 +9344,6 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera  	{  		LLFastTimer ftm(FTM_SHADOW_ALPHA);  		gDeferredShadowAlphaMaskProgram.bind(); -		gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f);  		gDeferredShadowAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);  		U32 mask =	LLVertexBuffer::MAP_VERTEX |  @@ -8932,10 +9351,19 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera  					LLVertexBuffer::MAP_COLOR |   					LLVertexBuffer::MAP_TEXTURE_INDEX; -		renderObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE); -		renderObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE); +		renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE); +		renderMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE); +		gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f);  		renderObjects(LLRenderPass::PASS_ALPHA, mask, TRUE, TRUE); + +		mask = mask & ~LLVertexBuffer::MAP_TEXTURE_INDEX; +  		gDeferredTreeShadowProgram.bind(); +		renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, mask); +		renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, mask); +		renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, mask); +		renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, mask); +		  		gDeferredTreeShadowProgram.setMinimumAlpha(0.598f);  		renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE);  	} @@ -9266,6 +9694,22 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  					LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,  					LLPipeline::RENDER_TYPE_PASS_SHINY,  					LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, +					LLPipeline::RENDER_TYPE_PASS_MATERIAL, +					LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA, +					LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK, +					LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE, +					LLPipeline::RENDER_TYPE_PASS_SPECMAP, +					LLPipeline::RENDER_TYPE_PASS_SPECMAP_BLEND, +					LLPipeline::RENDER_TYPE_PASS_SPECMAP_MASK, +					LLPipeline::RENDER_TYPE_PASS_SPECMAP_EMISSIVE, +					LLPipeline::RENDER_TYPE_PASS_NORMMAP, +					LLPipeline::RENDER_TYPE_PASS_NORMMAP_BLEND, +					LLPipeline::RENDER_TYPE_PASS_NORMMAP_MASK, +					LLPipeline::RENDER_TYPE_PASS_NORMMAP_EMISSIVE, +					LLPipeline::RENDER_TYPE_PASS_NORMSPEC, +					LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND, +					LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK, +					LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE,  					END_RENDER_TYPES);  	gGL.setColorMask(false, false); @@ -9785,7 +10229,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  			{  				static LLCullResult result[4]; -				//LLGLEnable enable(GL_DEPTH_CLAMP_NV);  				renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, TRUE, target_width);  			} @@ -10094,11 +10537,13 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  		LLVector4a left;  		left.load3(camera.getLeftAxis().mV);  		left.mul(left); +		llassert(left.dot3(left).getF32() > F_APPROXIMATELY_ZERO);  		left.normalize3fast();  		LLVector4a up;  		up.load3(camera.getUpAxis().mV);  		up.mul(up); +		llassert(up.dot3(up).getF32() > F_APPROXIMATELY_ZERO);  		up.normalize3fast();  		tdim.mV[0] = fabsf(half_height.dot3(left).getF32()); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 530d484dbd..ef05205844 100755 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -33,7 +33,8 @@  #include "llspatialpartition.h"  #include "m4math.h"  #include "llpointer.h" -#include "lldrawpool.h" +#include "lldrawpoolalpha.h" +#include "lldrawpoolmaterials.h"  #include "llgl.h"  #include "lldrawable.h"  #include "llrendertarget.h" @@ -47,6 +48,7 @@ class LLTextureEntry;  class LLCullResult;  class LLVOAvatar;  class LLGLSLShader; +class LLDrawPoolAlpha;  typedef enum e_avatar_skinning_method  { @@ -81,6 +83,7 @@ extern LLFastTimer::DeclareTimer FTM_RENDER_WL_SKY;  extern LLFastTimer::DeclareTimer FTM_RENDER_ALPHA;  extern LLFastTimer::DeclareTimer FTM_RENDER_CHARACTERS;  extern LLFastTimer::DeclareTimer FTM_RENDER_BUMP; +extern LLFastTimer::DeclareTimer FTM_RENDER_MATERIALS;  extern LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT;  extern LLFastTimer::DeclareTimer FTM_RENDER_GLOW;  extern LLFastTimer::DeclareTimer FTM_STATESORT; @@ -171,21 +174,21 @@ public:  	void		markMeshDirty(LLSpatialGroup* group);  	//get the object between start and end that's closest to start. -	LLViewerObject* lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end, +	LLViewerObject* lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,  												BOOL pick_transparent,  												S32* face_hit,                          // return the face hit -												LLVector3* intersection = NULL,         // return the intersection point +												LLVector4a* intersection = NULL,         // return the intersection point  												LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point -												LLVector3* normal = NULL,               // return the surface normal at the intersection point -												LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point   +												LLVector4a* normal = NULL,               // return the surface normal at the intersection point +												LLVector4a* tangent = NULL             // return the surface tangent at the intersection point    		); -	LLViewerObject* lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end, +	LLViewerObject* lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end,  											  BOOL pick_transparent,  											  S32* face_hit,                          // return the face hit -											  LLVector3* intersection = NULL,         // return the intersection point +											  LLVector4a* intersection = NULL,         // return the intersection point  											  LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point -											  LLVector3* normal = NULL,               // return the surface normal at the intersection point -											  LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point +											  LLVector4a* normal = NULL,               // return the surface normal at the intersection point +											  LLVector4a* tangent = NULL             // return the surface tangent at the intersection point  		);  	// Something about these textures has changed.  Dirty them. @@ -242,6 +245,8 @@ public:  	void forAllVisibleDrawables(void (*func)(LLDrawable*));  	void renderObjects(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_texture = FALSE); +	void renderMaskedObjects(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_texture = FALSE); +  	void renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture);  	void grabReferences(LLCullResult& result); @@ -375,12 +380,16 @@ public:  	static void setRenderHighlights(BOOL val);  	static void toggleRenderHighlights(void* data);  	static BOOL getRenderHighlights(void* data); +	static void setRenderHighlightTextureChannel(LLRender::eTexIndex channel); // sets which UV setup to display in highlight overlay +	static void updateRenderBump();  	static void updateRenderDeferred();  	static void refreshCachedSettings();  	static void throttleNewMemoryAllocation(BOOL disable); +	 +  	void addDebugBlip(const LLVector3& position, const LLColor4& color);  	void hidePermanentObjects( std::vector<U32>& restoreList ); @@ -411,8 +420,11 @@ public:  		RENDER_TYPE_TERRAIN						= LLDrawPool::POOL_TERRAIN,  		RENDER_TYPE_SIMPLE						= LLDrawPool::POOL_SIMPLE,  		RENDER_TYPE_GRASS						= LLDrawPool::POOL_GRASS, +		RENDER_TYPE_ALPHA_MASK					= LLDrawPool::POOL_ALPHA_MASK, +		RENDER_TYPE_FULLBRIGHT_ALPHA_MASK		= LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK,  		RENDER_TYPE_FULLBRIGHT					= LLDrawPool::POOL_FULLBRIGHT,  		RENDER_TYPE_BUMP						= LLDrawPool::POOL_BUMP, +		RENDER_TYPE_MATERIALS					= LLDrawPool::POOL_MATERIALS,  		RENDER_TYPE_AVATAR						= LLDrawPool::POOL_AVATAR,  		RENDER_TYPE_TREE						= LLDrawPool::POOL_TREE,  		RENDER_TYPE_INVISIBLE					= LLDrawPool::POOL_INVISIBLE, @@ -433,6 +445,22 @@ public:  		RENDER_TYPE_PASS_ALPHA					= LLRenderPass::PASS_ALPHA,  		RENDER_TYPE_PASS_ALPHA_MASK				= LLRenderPass::PASS_ALPHA_MASK,  		RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK	= LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, +		RENDER_TYPE_PASS_MATERIAL				= LLRenderPass::PASS_MATERIAL, +		RENDER_TYPE_PASS_MATERIAL_ALPHA			= LLRenderPass::PASS_MATERIAL_ALPHA, +		RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK	= LLRenderPass::PASS_MATERIAL_ALPHA_MASK, +		RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE= LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, +		RENDER_TYPE_PASS_SPECMAP				= LLRenderPass::PASS_SPECMAP, +		RENDER_TYPE_PASS_SPECMAP_BLEND			= LLRenderPass::PASS_SPECMAP_BLEND, +		RENDER_TYPE_PASS_SPECMAP_MASK			= LLRenderPass::PASS_SPECMAP_MASK, +		RENDER_TYPE_PASS_SPECMAP_EMISSIVE		= LLRenderPass::PASS_SPECMAP_EMISSIVE, +		RENDER_TYPE_PASS_NORMMAP				= LLRenderPass::PASS_NORMMAP, +		RENDER_TYPE_PASS_NORMMAP_BLEND			= LLRenderPass::PASS_NORMMAP_BLEND, +		RENDER_TYPE_PASS_NORMMAP_MASK			= LLRenderPass::PASS_NORMMAP_MASK, +		RENDER_TYPE_PASS_NORMMAP_EMISSIVE		= LLRenderPass::PASS_NORMMAP_EMISSIVE, +		RENDER_TYPE_PASS_NORMSPEC				= LLRenderPass::PASS_NORMSPEC, +		RENDER_TYPE_PASS_NORMSPEC_BLEND			= LLRenderPass::PASS_NORMSPEC_BLEND, +		RENDER_TYPE_PASS_NORMSPEC_MASK			= LLRenderPass::PASS_NORMSPEC_MASK, +		RENDER_TYPE_PASS_NORMSPEC_EMISSIVE		= LLRenderPass::PASS_NORMSPEC_EMISSIVE,  		// Following are object types (only used in drawable mRenderType)  		RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES,  		RENDER_TYPE_VOLUME, @@ -540,6 +568,7 @@ public:  	static BOOL             sMemAllocationThrottled;  	static S32				sVisibleLightCount;  	static F32				sMinRenderSize;	 +	static BOOL				sRenderingHUDs;  	static LLTrace::EventStatHandle<S64> sStatBatchSize; @@ -752,17 +781,20 @@ protected:  	// For quick-lookups into mPools (mapped by texture pointer)  	std::map<uintptr_t, LLDrawPool*>	mTerrainPools;  	std::map<uintptr_t, LLDrawPool*>	mTreePools; -	LLDrawPool*					mAlphaPool; +	LLDrawPoolAlpha*			mAlphaPool;  	LLDrawPool*					mSkyPool;  	LLDrawPool*					mTerrainPool;  	LLDrawPool*					mWaterPool;  	LLDrawPool*					mGroundPool;  	LLRenderPass*				mSimplePool;  	LLRenderPass*				mGrassPool; +	LLRenderPass*				mAlphaMaskPool; +	LLRenderPass*				mFullbrightAlphaMaskPool;  	LLRenderPass*				mFullbrightPool;  	LLDrawPool*					mInvisiblePool;  	LLDrawPool*					mGlowPool;  	LLDrawPool*					mBumpPool; +	LLDrawPool*					mMaterialsPool;  	LLDrawPool*					mWLSkyPool;  	// Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar @@ -801,6 +833,10 @@ public:  	static BOOL				sRenderBeacons;  	static BOOL				sRenderHighlight; +	// Determines which set of UVs to use in highlight display +	// +	static LLRender::eTexIndex sRenderHighlightTextureChannel; +  	//debug use  	static U32              sCurRenderPoolType ; diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 42568775d9..a9176595c7 100755 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -657,6 +657,15 @@        name="PathfindingGoodColor"        reference="LtGreen" />    <color +      name="MaterialErrorColor" +      reference="LtRed" /> +  <color +      name="MaterialWarningColor" +      reference="DrYellow" /> +  <color +      name="MaterialGoodColor" +      reference="LtGreen" /> +  <color        name="PathfindingDefaultBeaconColor"        reference="Red_80" />    <color diff --git a/indra/newview/skins/default/textures/flatnormal.tga b/indra/newview/skins/default/textures/flatnormal.tga Binary files differnew file mode 100644 index 0000000000..6d5abd1782 --- /dev/null +++ b/indra/newview/skins/default/textures/flatnormal.tga diff --git a/indra/newview/skins/default/textures/materials_ui_x_24.png b/indra/newview/skins/default/textures/materials_ui_x_24.png Binary files differnew file mode 100644 index 0000000000..6d88554914 --- /dev/null +++ b/indra/newview/skins/default/textures/materials_ui_x_24.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index fcab966dee..b0e4b71d21 100755 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -743,6 +743,7 @@ with the same filename but different name    <texture name="default_land_picture.j2c" />    <texture name="default_profile_picture.j2c" />    <texture name="locked_image.j2c" /> +  <texture name="materials_ui_x_24.png" />    <texture name="Progress_1" file_name="icons/Progress_1.png" preload="true" />    <texture name="Progress_2" file_name="icons/Progress_2.png" preload="true" /> diff --git a/indra/newview/skins/default/xui/da/menu_viewer.xml b/indra/newview/skins/default/xui/da/menu_viewer.xml index d695cd1f89..f2ed7c2e64 100755 --- a/indra/newview/skins/default/xui/da/menu_viewer.xml +++ b/indra/newview/skins/default/xui/da/menu_viewer.xml @@ -245,7 +245,7 @@  		<menu label="Gengivelse" name="Rendering">  			<menu_item_check label="Akser" name="Axes"/>  			<menu_item_check label="Wireframe" name="Wireframe"/> -			<menu_item_check label="Lys og skygger" name="Lighting and Shadows"/> +			<menu_item_check label="Lys og skygger" name="Advanced Lighting Model"/>  			<menu_item_check label="Skygger fra sol/måne/andre lyskilder" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO og skygge udjævning" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="Globalt lys (eksperimentiel)" name="Global Illumination"/> diff --git a/indra/newview/skins/default/xui/de/menu_viewer.xml b/indra/newview/skins/default/xui/de/menu_viewer.xml index 2c9d9fa7f1..47d9fec352 100755 --- a/indra/newview/skins/default/xui/de/menu_viewer.xml +++ b/indra/newview/skins/default/xui/de/menu_viewer.xml @@ -315,7 +315,7 @@  			<menu_item_call label="Texturinfo für ausgewähltes Objekt" name="Selected Texture Info Basis"/>  			<menu_item_check label="Wireframe" name="Wireframe"/>  			<menu_item_check label="Objekt-Objekt Okklusion" name="Object-Object Occlusion"/> -			<menu_item_check label="Licht und Schatten" name="Lighting and Shadows"/> +			<menu_item_check label="Uber Licht Modell" name="Advanced Lighting Model"/>  			<menu_item_check label="Schatten von Sonne-/Mond-Projektoren" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO und Schattenglättung" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="Fehler in GL beseitigen" name="Debug GL"/> @@ -393,14 +393,9 @@  				<menu_item_call label="Weiblich testen" name="Test Female"/>  				<menu_item_check label="Avatarauswahl zulassen" name="Allow Select Avatar"/>  			</menu> -			<menu label="Animationsgeschwindigkeit" name="Animation Speed"> -				<menu_item_call label="Alle Animationen 10 % schneller" name="All Animations 10 Faster"/> -				<menu_item_call label="Alle Animationen 10 % langsamer" name="All Animations 10 Slower"/> -				<menu_item_call label="Alle Animationsgeschwindigkeiten zurücksetzen" name="Reset All Animation Speed"/> -				<menu_item_check label="Zeitlupen-Animationen" name="Slow Motion Animations"/> -			</menu>  			<menu_item_call label="Param auf Standard erzwingen" name="Force Params to Default"/>  			<menu_item_check label="Animations-Info" name="Animation Info"/> +			<menu_item_check label="Zeitlupen-Animationen" name="Slow Motion Animations"/>  			<menu_item_check label="Kamerafokus anzeigen" name="Show Look At"/>  			<menu_item_check label="Klickpunkt anzeigen??" name="Show Point At"/>  			<menu_item_check label="Fehler in Landaktualisierung beseitigen" name="Debug Joint Updates"/> diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 436e9f8fed..8b9733df17 100755 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -2491,534 +2491,10 @@ even though the user gets a free copy.               width="132" />          </panel>           <panel -         border="false" -         follows="all" -         height="367"           label="Texture" -         layout="topleft" -         left_delta="0" -         mouse_opaque="false"           help_topic="toolbox_texture_tab"           name="Texture" -         top_delta="0" -         width="295"> -            <panel.string -             name="string repeats per meter"> -                Repeats Per Meter -            </panel.string> -            <panel.string -             name="string repeats per face"> -                Repeats Per Face -            </panel.string> -            <texture_picker -             can_apply_immediately="true" -             default_image_name="Default" -             fallback_image="locked_image.j2c" -             follows="left|top" -             height="80" -             label="Texture" -             layout="topleft" -             left="10" -             name="texture control" -             tool_tip="Click to choose a picture" -             top="8" -             width="64" /> -            <color_swatch -             can_apply_immediately="true" -             follows="left|top" -             height="80" -             label="Color" -             layout="topleft" -             left_pad="15" -             name="colorswatch" -             tool_tip="Click to open color picker" -             top_delta="0" -             width="64" /> -            <text -             type="string" -             length="1" -             follows="left|top" -             height="10" -             layout="topleft" -             left_pad="15" -             name="color trans" -             text_readonly_color="LabelDisabledColor" -             top="6" -             width="110"> -                Transparency % -            </text> -            <spinner -             decimal_digits="0" -             follows="left|top" -             height="19" -             increment="2" -             initial_value="0" -             layout="topleft" -             left_delta="0" -             max_val="100" -             name="ColorTrans" -             top_pad="4" -             width="80" /> -            <text -             type="string" -             length="1" -             follows="left|top" -             height="10" -             layout="topleft" -             left_delta="0" -             name="glow label" -             text_readonly_color="LabelDisabledColor" -             top_pad="8" -             width="80"> -                Glow -            </text> -            <spinner -             decimal_digits="2" -             follows="left|top" -             height="19" -             initial_value="0" -             layout="topleft" -             left_delta="0" -             name="glow" -             top_pad="4" -             width="80" /> -            <check_box -             height="19" -             label="Full Bright" -             layout="topleft" -             left_delta="-5" -             name="checkbox fullbright" -             top_pad="4" -             width="81" /> -            <text -             type="string" -             length="1" -             follows="left|top" -             height="10" -             layout="topleft" -             left="10" -             name="tex gen" -             text_readonly_color="LabelDisabledColor" -             top_pad="5" -             width="90"> -                Mapping -            </text> -            <combo_box -             height="23" -             layout="topleft" -             left_delta="0" -             name="combobox texgen" -             top_pad="4" -             width="90"> -                <combo_box.item -                 label="Default" -                 name="Default" -                 value="Default" /> -                <combo_box.item -                 label="Planar" -                 name="Planar" -                 value="Planar" /> -            </combo_box> -            <text -             type="string" -             length="1" -             follows="left|top" -             height="10" -             layout="topleft" -             name="label shininess" -             left_pad="4" -             text_readonly_color="LabelDisabledColor" -             top_pad="-37" -             width="90"> -                Shininess -            </text> -            <combo_box -             height="23" -             layout="topleft" -             left_delta="0" -             name="combobox shininess" -             top_pad="4" -             width="90"> -                <combo_box.item -                 label="None" -                 name="None" -                 value="None" /> -                <combo_box.item -                 label="Low" -                 name="Low" -                 value="Low" /> -                <combo_box.item -                 label="Medium" -                 name="Medium" -                 value="Medium" /> -                <combo_box.item -                 label="High" -                 name="High" -                 value="High" /> -            </combo_box> -            <text -             type="string" -             length="1" -             follows="left|top" -             height="10" -             layout="topleft" -             left_pad="4" -             name="label bumpiness" -             text_readonly_color="LabelDisabledColor" -             top_pad="-37" -             width="90"> -                Bumpiness -            </text> -            <combo_box -             height="23" -             layout="topleft" -             left_delta="0" -             name="combobox bumpiness" -             top_pad="4" -             width="90"> -                <combo_box.item -                 label="None" -                 name="None" -                 value="None" /> -                <combo_box.item -                 label="Brightness" -                 name="Brightness" -                 value="Brightness" /> -                <combo_box.item -                 label="Darkness" -                 name="Darkness" -                 value="Darkness" /> -                <combo_box.item -                 label="woodgrain" -                 name="woodgrain" -                 value="woodgrain" /> -                <combo_box.item -                 label="bark" -                 name="bark" -                 value="bark" /> -                <combo_box.item -                 label="bricks" -                 name="bricks" -                 value="bricks" /> -                <combo_box.item -                 label="checker" -                 name="checker" -                 value="checker" /> -                <combo_box.item -                 label="concrete" -                 name="concrete" -                 value="concrete" /> -                <combo_box.item -                 label="crustytile" -                 name="crustytile" -                 value="crustytile" /> -                <combo_box.item -                 label="cutstone" -                 name="cutstone" -                 value="cutstone" /> -                <combo_box.item -                 label="discs" -                 name="discs" -                 value="discs" /> -                <combo_box.item -                 label="gravel" -                 name="gravel" -                 value="gravel" /> -                <combo_box.item -                 label="petridish" -                 name="petridish" -                 value="petridish" /> -                <combo_box.item -                 label="siding" -                 name="siding" -                 value="siding" /> -                <combo_box.item -                 label="stonetile" -                 name="stonetile" -                 value="stonetile" /> -                <combo_box.item -                 label="stucco" -                 name="stucco" -                 value="stucco" /> -                <combo_box.item -                 label="suction" -                 name="suction" -                 value="suction" /> -                <combo_box.item -                 label="weave" -                 name="weave" -                 value="weave" /> -            </combo_box> -          <!-- -            <line_editor -             bevel_style="in" -             border_style="line" -             border_thickness="1" -             follows="left|top" -             height="16" -             layout="topleft" -             left="10" -             max_length_bytes="63" -             name="Home Url" -             select_on_focus="true" -             top="134" -             width="250" /> -            <check_box -             height="16" -             label="Media Face" -             layout="topleft" -             left_delta="0" -             name="has media" -             top_pad="6" -             width="70" /> -            <button -             follows="left|top" -             font="SansSerifSmall" -             height="20" -             label="Set Media Info" -             label_selected="Set Media Info" -             layout="topleft" -             left_pad="60" -             name="media info set" -             top_delta="-4" -             width="120" /> ---> -            <check_box -             follows="top|left" -             height="16" -             initial_value="false" -             label="Align planar faces" -             layout="topleft" -             left="17" -             name="checkbox planar align" -             tool_tip="Align textures on all selected faces with the last selected face. Requires Planar texture mapping." -             top_delta="26" -             width="140" /> -            <text -             type="string" -             length="1" -             follows="left|top" -             height="10" -             layout="topleft" -             left="10" -             name="rpt" -             text_readonly_color="LabelDisabledColor" -             top_pad="2" -             width="140"> -                Repeats / Face -            </text> -            <spinner -             follows="left|top" -             height="19" -             initial_value="0" -             label="Horizontal (U)" -             label_width="125" -             layout="topleft" -             left="20" -             max_val="100" -             name="TexScaleU" -             top_pad="5" -             width="185" /> -            <check_box -             height="19" -             label="Flip" -             layout="topleft" -             left_pad="5" -             name="checkbox flip s" -             top_delta="0" -             width="70" /> -            <spinner -             follows="left|top" -             height="19" -             initial_value="0" -             label="Vertical (V)" -             label_width="125" -             layout="topleft" -             left="20" -             max_val="100" -             name="TexScaleV" -             width="185" /> -            <check_box -             height="19" -             label="Flip" -             layout="topleft" -             left_pad="5" -             name="checkbox flip t" -             top_delta="0" -             width="70" /> -            <spinner -             decimal_digits="2" -             follows="left|top" -             height="19" -             increment="1" -             initial_value="0" -			 label="Rotation˚" -             layout="topleft" -			 label_width="135" -             left="10" -             max_val="9999" -             min_val="-9999" -             name="TexRot" -             width="195" /> - -            <spinner -             decimal_digits="1" -             follows="left|top" -             height="23" -             initial_value="1" -			 label="Repeats / Meter" -             layout="topleft" -			 label_width="135" -             left="10" -             max_val="10" -             min_val="0.1" -             name="rptctrl" -             width="195" /> -            <button -             follows="left|top" -             height="23" -             label="Apply" -             label_selected="Apply" -             layout="topleft" -             left_pad="5" -             name="button apply" -             width="75" /> -            <text -             type="string" -             length="1" -             follows="left|top" -             height="10" -             layout="topleft" -             left="10" -             name="tex offset" -             text_readonly_color="LabelDisabledColor" -             width="200"> -                Texture Offset -            </text> -            <spinner -             follows="left|top" -             height="19" -             initial_value="0" -             label="Horizontal (U)" -             label_width="125" -             layout="topleft" -             left="20" -             min_val="-1" -             name="TexOffsetU" -             width="185" /> -            <spinner -             follows="left|top" -             height="19" -             initial_value="0" -             label="Vertical (V)" -             label_width="125" -             layout="topleft" -             left_delta="0" -             min_val="-1" -             name="TexOffsetV" -             top_pad="1" -             width="185" /> -        <panel -         border="false" -         follows="left|top" -         layout="topleft" -         mouse_opaque="false" -         background_visible="true" -         bg_alpha_color="DkGray" -         name="Add_Media" -         left="0" -         height="47" -         width="290"> -            <text -             type="string" -             length="1" -             follows="left|top" -             height="18" -             layout="topleft" -             left="10" -             top_pad="3" -             name="media_tex" -             width="190"> -              Media -			</text> -			<button -			 follows="top|left" -			 height="18" -			 image_selected="AddItem_Press" -			 image_unselected="AddItem_Off" -			 image_disabled="AddItem_Disabled" -			 layout="topleft" -			 left_pad="0" -			 name="add_media" -			 tab_stop="false" -			 top_delta="0" -			 tool_tip="Add Media" -			 width="18"> -				<button.commit_callback -				function="BuildTool.AddMedia"/> -			</button> -			<button -			 follows="top|left" -			 height="18" -			 image_selected="TrashItem_Press" -			 image_unselected="TrashItem_Off" -			 layout="topleft" -			 left_pad="5" -			 name="delete_media" -			 tool_tip="Delete this media texture" -			 top_delta="0" -			 width="18"> -				<button.commit_callback -				function="BuildTool.DeleteMedia"/> -			</button> -			<button -			 follows="top|left" -			 tool_tip="Edit this Media" -			 height="12" -             image_disabled="Icon_Gear_Background" -             image_selected="Icon_Gear_Press" -             image_unselected="Icon_Gear_Foreground" -			 layout="topleft" -			 left_pad="10" -			 name="edit_media" -			 top_delta="3" -			 width="12"> -				<button.commit_callback -				function="BuildTool.EditMedia"/> -			</button> -      <text -			 follows="left|top|right" -			 height="9" -			 layout="topleft" -			 left="10" -                         use_ellipses="true" -			 read_only="true" -			 name="media_info" -			 width="180" /> -      <web_browser -        visible="false" -        enabled="false" -        border_visible="true" -        bottom_delta="0" -        follows="top|left" -        left="0" -        name="title_media" -        width="4" -        height="4" -        start_url="about:blank" -        decouple_texture_size="true" /> -     <button -			 follows="right|top" -			 height="22" -			 label="Align" -			 label_selected="Align Media" -			 layout="topleft" -			 right="-16" -			 name="button align" -			 top_delta="-4" -			 tool_tip="Align media texture (must load first)" -			 width="80" /> -		</panel> +         filename="panel_tools_texture.xml">  	   </panel>         <panel           border="false" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index d50b7b18e7..f4a9e69bf9 100755 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1300,7 +1300,7 @@               parameter="hud" />          </menu_item_call>-->  		<menu_item_separator/> - +		  		<menu_item_call               label="User’s guide"               name="User’s guide"> @@ -2381,6 +2381,12 @@                  <menu_item_check.on_click                   function="Advanced.ToggleFrameTest" />              </menu_item_check> +          <menu_item_call +             label="Frame Profile" +             name="Frame Profile"> +            <menu_item_call.on_click +             function="Advanced.ClickRenderProfile" /> +          </menu_item_call>          </menu>        <menu          create_jump_keys="true" @@ -2676,6 +2682,13 @@                  <menu_item_call.on_click                   function="Advanced.SelectedTextureInfo" />              </menu_item_call> +            <menu_item_call +             label="Selected Material Info" +             name="Selected Material Info" +             shortcut="control|alt|shift|M"> +                <menu_item_call.on_click +                 function="Advanced.SelectedMaterialInfo" /> +            </menu_item_call>              <menu_item_check               label="Wireframe"               name="Wireframe" @@ -2702,8 +2715,8 @@            <menu_item_separator />            <menu_item_check -                       label="Lighting and Shadows" -                       name="Lighting and Shadows"> +                       label="Advanced Lighting Model" +                       name="Advanced Lighting Model">              <menu_item_check.on_check               function="CheckControl"               parameter="RenderDeferred" /> @@ -2810,16 +2823,6 @@                   parameter="TextureLoadFullRes" />              </menu_item_check>              <menu_item_check -             label="Texture Atlas (experimental)" -             name="Texture Atlas"> -              <menu_item_check.on_check -               function="CheckControl" -               parameter="EnableTextureAtlas" /> -              <menu_item_check.on_click -               function="ToggleControl" -               parameter="EnableTextureAtlas" /> -            </menu_item_check> -              <menu_item_check               label="Render Attached Lights"               name="Render Attached Lights">                  <menu_item_check.on_check diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 540618ef9a..8667d0277a 100755 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -3454,7 +3454,7 @@ or you can install it now.     name="DownloadBackgroundTip"     type="notify">  We have downloaded an update to your [APP_NAME] installation. -Version [VERSION] [[INFO_URL] Information about this update] +Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update]      <tag>confirm</tag>      <usetemplate       name="okcancelbuttons" @@ -3467,7 +3467,7 @@ Version [VERSION] [[INFO_URL] Information about this update]   name="DownloadBackgroundDialog"   type="alertmodal">  We have downloaded an update to your [APP_NAME] installation. -Version [VERSION] [[INFO_URL] Information about this update] +Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update]      <tag>confirm</tag>      <usetemplate       name="okcancelbuttons" @@ -6923,7 +6923,7 @@ Do not allow access if you do not fully understand why it wants access to your a  [FOOTERTEXT]      </footer>    </notification> - +	  	<notification  	 icon="notify.tga"  	 name="UnknownScriptQuestion" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index cd243d40a4..d7db7caf66 100755 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -211,16 +211,19 @@  		 name="TransparentWater"  		 top_pad="7"  		 width="256" /> -		<check_box -		 control_name="RenderObjectBump" -		 height="16" -		 initial_value="true" -		 label="Bump mapping and shiny" -		 layout="topleft" -		 left_delta="0" -		 name="BumpShiny" -		 top_pad="1" -		width="256" /> +      <check_box +       control_name="RenderObjectBump" +       height="16" +       initial_value="true" +       label="Bump mapping and shiny" +       layout="topleft" +       left_delta="0" +       name="BumpShiny" +       top_pad="1" +      width="256"> +        <check_box.commit_callback +        function="Pref.VertexShaderEnable" /> +      </check_box>      <check_box  		control_name="RenderLocalLights"  		height="16" @@ -262,7 +265,7 @@  		 control_name="RenderDeferred"  		 height="16"  		 initial_value="true" -		 label="Lighting and Shadows" +		 label="Advanced Lighting Model"  		 layout="topleft"  		 left_delta="0"  		 name="UseLightShaders" diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml new file mode 100644 index 0000000000..5ac2ec2b20 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -0,0 +1,766 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel +         border="false" +         follows="all" +         height="420" +         label="Texture" +         layout="topleft" +         left="0" +         mouse_opaque="false" +         help_topic="toolbox_texture_tab" +         name="Texture" +         top="0" +         width="295"> +            <panel.string +             name="string repeats per meter"> +                Repeats Per Meter +            </panel.string> +            <panel.string +             name="string repeats per face"> +                Repeats Per Face +            </panel.string> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left="10" +             name="color label" +             text_readonly_color="LabelDisabledColor" +             top="6" +             width="64"> +                Color +            </text> +            <!-- label is blank because control places it below the box --> +            <color_swatch +             can_apply_immediately="true" +             follows="left|top" +             height="45" +             label="" +             layout="topleft" +             left="10" +             name="colorswatch" +             tool_tip="Click to open color picker" +             top="20" +             width="64" /> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left_pad="15" +             name="color trans" +             text_readonly_color="LabelDisabledColor" +             top="6" +             width="110"> +                Transparency % +            </text> +            <spinner +             decimal_digits="0" +             follows="left|top" +             height="19" +             increment="2" +             initial_value="0" +             layout="topleft" +             left_delta="0" +             max_val="100" +             name="ColorTrans" +             top_pad="4" +             width="80" /> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left_pad="15" +             name="glow label" +             text_readonly_color="LabelDisabledColor" +             top="6" +             width="80"> +                Glow +            </text> +            <spinner +             decimal_digits="2" +             follows="left|top" +             height="19" +             initial_value="0" +             layout="topleft" +             left_delta="0" +             name="glow" +             top_pad="4" +             width="80" /> +            <check_box +             height="19" +             label="Full Bright" +             layout="topleft" +             left="7" +             name="checkbox fullbright" +             top_pad="4" +             width="81" /> +            <combo_box +             height="23" +             layout="topleft" +             left="10" +             name="combobox matmedia" +             top_pad="5" +             width="100"> +                <combo_box.item +                 label="Materials" +                 name="Materials" +                 value="Materials" /> +                <combo_box.item +                 label="Media" +                 name="Media" +                 value="Media" /> +            </combo_box> +            <combo_box +             height="23" +             layout="topleft" +             left_pad="10" +             name="combobox mattype" +             top_delta="0" +             width="155"> +                <combo_box.item +                 label="Texture (diffuse)" +                 name="Texture (diffuse)" +                 value="Texture (diffuse)" /> +                <combo_box.item +                 label="Bumpiness (normal)" +                 name="Bumpiness (normal)" +                 value="Bumpiness (normal)" /> +                <combo_box.item +                 label="Shininess (specular)" +                 name="Shininess (specular)" +                 value="Shininess (specular)" /> +            </combo_box> +            <texture_picker +             can_apply_immediately="true" +             default_image_name="Default" +             fallback_image="materials_ui_x_24.png" +             follows="left|top" +             height="80" +             label="Texture       " +             layout="topleft" +             left="10" +             name="texture control" +             tool_tip="Click to choose a picture" +             top_pad="8" +             width="64" /> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left_pad="10" +             name="label alphamode" +             text_readonly_color="LabelDisabledColor" +             top_delta="0" +             width="90"> +                Alpha mode +            </text> +            <combo_box +             height="23" +             layout="topleft" +             left_delta="0" +             name="combobox alphamode" +             top_pad="4" +             width="120"> +                <combo_box.item +                 label="None" +                 name="None" +                 value="None" /> +                <combo_box.item +                 label="Alpha blending" +                 name="Alpha blending" +                 value="Alpha blending" /> +                <combo_box.item +                 label="Alpha masking" +                 name="Alpha masking" +                 value="Alpha masking" /> +                <combo_box.item +                 label="Emissive mask" +                 name="Emissive mask" +                 value="Emissive mask" /> +            </combo_box> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left_delta="0" +             name="label maskcutoff" +             text_readonly_color="LabelDisabledColor" +             top_pad="4" +             width="90"> +                Mask cutoff +            </text> +            <spinner +             decimal_digits="0" +             min_val="0" +             max_val="255" +             follows="left|top" +             height="19" +             initial_value="55" +             layout="topleft" +             top_pad="4" +             left_delta="0" +             increment="1" +             name="maskcutoff" +             width="80" /> +            <texture_picker +             allow_no_texture="true" +             can_apply_immediately="true" +             default_image_name="Default" +             fallback_image="materials_ui_x_24.png" +             follows="left|top" +             height="80" +             label="Texture       " +             layout="topleft" +             left="10" +             name="bumpytexture control" +             tool_tip="Click to choose a picture" +             top_delta="-55" +             width="64" /> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left_pad="10" +             name="label bumpiness" +             text_readonly_color="LabelDisabledColor" +             top_delta="0" +             width="90"> +                Bumpiness +            </text> +            <combo_box +             height="23" +             layout="topleft" +             left_delta="0" +             name="combobox bumpiness" +             top_pad="4" +             width="90"> +                <combo_box.item +                 label="None" +                 name="None" +                 value="None" /> +                <combo_box.item +                 label="Brightness" +                 name="Brightness" +                 value="Brightness" /> +                <combo_box.item +                 label="Darkness" +                 name="Darkness" +                 value="Darkness" /> +                <combo_box.item +                 label="woodgrain" +                 name="woodgrain" +                 value="woodgrain" /> +                <combo_box.item +                 label="bark" +                 name="bark" +                 value="bark" /> +                <combo_box.item +                 label="bricks" +                 name="bricks" +                 value="bricks" /> +                <combo_box.item +                 label="checker" +                 name="checker" +                 value="checker" /> +                <combo_box.item +                 label="concrete" +                 name="concrete" +                 value="concrete" /> +                <combo_box.item +                 label="crustytile" +                 name="crustytile" +                 value="crustytile" /> +                <combo_box.item +                 label="cutstone" +                 name="cutstone" +                 value="cutstone" /> +                <combo_box.item +                 label="discs" +                 name="discs" +                 value="discs" /> +                <combo_box.item +                 label="gravel" +                 name="gravel" +                 value="gravel" /> +                <combo_box.item +                 label="petridish" +                 name="petridish" +                 value="petridish" /> +                <combo_box.item +                 label="siding" +                 name="siding" +                 value="siding" /> +                <combo_box.item +                 label="stonetile" +                 name="stonetile" +                 value="stonetile" /> +                <combo_box.item +                 label="stucco" +                 name="stucco" +                 value="stucco" /> +                <combo_box.item +                 label="suction" +                 name="suction" +                 value="suction" /> +                <combo_box.item +                 label="weave" +                 name="weave" +                 value="weave" /> +              <!-- +                 NORSPEC-182, ensure item doesn't show up in menu until it should +                <combo_box.item +                 label="Use texture" +                 name="Use texture" +                 value="Use texture" /> +                 --> +            </combo_box> +            <texture_picker +             allow_no_texture="true" +             can_apply_immediately="true" +             default_image_name="Default" +             fallback_image="materials_ui_x_24.png" +             follows="left|top" +             height="80" +             label="Texture       " +             layout="topleft" +             left="10" +             name="shinytexture control" +             tool_tip="Click to choose a picture" +             top_delta="-14" +             width="64" /> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             name="label shininess" +             left_pad="10" +             text_readonly_color="LabelDisabledColor" +             top_delta="6" +             width="90"> +                Shininess +            </text> +            <combo_box +             height="23" +             layout="topleft" +             left_pad="10" +             name="combobox shininess" +             top_delta="-6" +             width="90"> +                <combo_box.item +                 label="None" +                 name="None" +                 value="None" /> +                <combo_box.item +                 label="Low" +                 name="Low" +                 value="Low" /> +                <combo_box.item +                 label="Medium" +                 name="Medium" +                 value="Medium" /> +                <combo_box.item +                 label="High" +                 name="High" +                 value="High" /> +              <!-- +                 NORSPEC-182, ensure item doesn't show up in menu until it should +                <combo_box.item +                 label="Use texture" +                 name="Use texture" +                 value="Use texture" /> +                 --> +            </combo_box> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left_delta="-100" +             name="label glossiness" +             text_readonly_color="LabelDisabledColor" +             top_pad="8" +             width="116"> +                Glossiness +            </text> +            <spinner +             decimal_digits="0" +             min_val="0" +             max_val="255" +             follows="left|top" +             height="19" +             initial_value="51" +             increment="1" +             layout="topleft" +             top_delta="-4" +             left_pad="10" +             name="glossiness" +             width="64" /> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left_delta="-126" +             name="label environment" +             text_readonly_color="LabelDisabledColor" +             top_pad="8" +             width="116"> +                Environment +            </text> +            <spinner +             decimal_digits="0" +             min_val="0" +             max_val="255" +             increment="1" +             follows="left|top" +             height="19" +             initial_value="0" +             layout="topleft" +             top_delta="-4" +             left_pad="10" +             name="environment" +             width="64" /> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left_delta="-126" +             name="label shinycolor" +             text_readonly_color="LabelDisabledColor" +             top_pad="8" +             width="116"> +                Color +            </text> +            <!-- label is blank because control places it below the box --> +            <color_swatch +             can_apply_immediately="true" +             follows="left|top" +             height="45" +             label="" +             layout="topleft" +             left_pad="10" +             name="shinycolorswatch" +             tool_tip="Click to open color picker" +             top_delta="-4" +             width="64" /> +            <text +			 follows="left|top|right" +			 height="9" +			 layout="topleft" +			 left="10" +			 top_delta="-50" +             use_ellipses="true" +			 read_only="true" +			 name="media_info" +			 width="280"> +			 URL of chosen media, if any, goes here +			 </text> +			<button +			 follows="top|left" +			 height="18" +			 layout="topleft" +			 left="10" +			 name="add_media" +			 top_pad="4" +			 tool_tip="Add Media" +			 label="Choose..." +			 width="85"> +				<button.commit_callback +				function="BuildTool.AddMedia"/> +			</button> +			<button +			 follows="top|left" +			 height="18" +			 layout="topleft" +			 left_pad="5" +			 name="delete_media" +			 tool_tip="Delete this media texture" +			 top_delta="0" +			 label="Remove" +			 width="85"> +				<button.commit_callback +				function="BuildTool.DeleteMedia"/> +			</button> +            <button +			 follows="left|top" +			 height="18" +			 label="Align" +			 label_selected="Align Media" +			 layout="topleft" +			 left_pad="5" +			 name="button align" +			 top_delta="0" +			 tool_tip="Align media texture (must load first)" +			 width="85" /> +            <text +             type="string" +             length="1" +             follows="left|top" +             height="10" +             layout="topleft" +             left="10" +             name="tex gen" +             text_readonly_color="LabelDisabledColor" +             top_pad="60" +             width="140"> +                Mapping +            </text> +            <combo_box +             height="23" +             layout="topleft" +             left_pad="0" +             name="combobox texgen" +             top_pad="-13" +             width="125"> +                <combo_box.item +                 label="Default" +                 name="Default" +                 value="Default" /> +                <combo_box.item +                 label="Planar" +                 name="Planar" +                 value="Planar" /> +            </combo_box> +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Horizontal scale" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-100" +             max_val="100" +             name="TexScaleU" +             top_pad="5" +             width="265" /> +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Vertical scale" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-100" +             max_val="100" +             name="TexScaleV" +             width="265" /> +            <spinner +             decimal_digits="1" +             follows="left|top" +             height="19" +             initial_value="" +			 label="Repeats per meter" +             layout="topleft" +			 label_width="205" +             left="10" +             max_val="100" +             min_val="0.1" +             name="rptctrl" +             width="265" /> +           <spinner +             decimal_digits="2" +             follows="left|top" +             height="19" +             increment="1" +             initial_value="0" +			 label="Rotation degrees" +             layout="topleft" +			 label_width="205" +             left="10" +             max_val="9999" +             min_val="-9999" +             name="TexRot" +             width="265" /> + +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Horizontal offset" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-1" +             name="TexOffsetU" +             width="265" /> +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Vertical offset" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-1" +             name="TexOffsetV" +             width="265" /> +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Horizontal scale" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-100" +             max_val="100" +             name="bumpyScaleU" +             top_delta="-115" +             width="265" /> +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Vertical scale" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-100" +             max_val="100" +             name="bumpyScaleV" +             width="265" /> +           <spinner +             decimal_digits="2" +             follows="left|top" +             height="19" +             top_pad="27" +             increment="1" +             initial_value="0" +			 label="Rotation degrees" +             layout="topleft" +			 label_width="205" +             left="10" +             max_val="360" +             min_val="0" +             name="bumpyRot" +             width="265" /> + +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Horizontal offset" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-1" +             name="bumpyOffsetU" +             width="265" /> +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Vertical offset" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-1" +             name="bumpyOffsetV" +             width="265" /> +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Horizontal scale" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-100" +             max_val="100" +             name="shinyScaleU" +             top_delta="-115" +             width="265" /> +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Vertical scale" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-100" +             max_val="100" +             name="shinyScaleV" +             width="265" /> +           <spinner +             decimal_digits="2" +             follows="left|top" +             height="19" +             top_pad="27" +             increment="1" +             initial_value="0" +			 label="Rotation degrees" +             layout="topleft" +			 label_width="205" +             left="10" +             max_val="360" +             min_val="0" +             name="shinyRot" +             width="265" /> + +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Horizontal offset" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-1" +             name="shinyOffsetU" +             width="265" /> +            <spinner +             follows="left|top" +             height="19" +             initial_value="0" +             label="Vertical offset" +             label_width="205" +             layout="topleft" +             left="10" +             min_val="-1" +             name="shinyOffsetV" +             width="265" /> +            <check_box +             follows="top|left" +             height="16" +             initial_value="false" +             label="Align planar faces" +             layout="topleft" +             left="7" +             name="checkbox planar align" +             tool_tip="Align textures on all selected faces with the last selected face. Requires Planar texture mapping." +             top_delta="16" +             width="260" /> +            <web_browser +             visible="false" +             enabled="false" +             border_visible="true" +             bottom_delta="0" +             follows="top|left" +             left="0" +             name="title_media" +             width="4" +             height="4" +             start_url="about:blank" +             decouple_texture_size="true" /> +	   </panel> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index e0a85877eb..29393bf749 100755 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -373,6 +373,8 @@ Please try logging in again in a minute.</string>  	<!-- build floater -->  	<string name="multiple_textures">Multiple</string> +<string name="use_texture">Use texture</string> +  	<!-- world map -->  	<string name="texture_loading">Loading...</string>  	<string name="worldmap_offline">Offline</string> @@ -416,7 +418,7 @@ Please try logging in again in a minute.</string>  	<string name="OverrideYourAnimations">Replace your default animations</string>  	<string name="ScriptReturnObjects">Return objects on your behalf</string>  	<string name="UnknownScriptPermission">(unknown)!</string> - +	  	<!-- Sim Access labels -->  	<string name="SIM_ACCESS_PG">General</string>  	<string name="SIM_ACCESS_MATURE">Moderate</string> diff --git a/indra/newview/skins/default/xui/es/menu_viewer.xml b/indra/newview/skins/default/xui/es/menu_viewer.xml index 30842f53f2..1e0ceb2220 100755 --- a/indra/newview/skins/default/xui/es/menu_viewer.xml +++ b/indra/newview/skins/default/xui/es/menu_viewer.xml @@ -293,7 +293,7 @@  		<menu label="Rendering" name="Rendering">  			<menu_item_check label="Axes" name="Axes"/>  			<menu_item_check label="Wireframe" name="Wireframe"/> -			<menu_item_check label="Luces y sombras" name="Lighting and Shadows"/> +			<menu_item_check label="Luces y sombras" name="Advanced Lighting Model"/>  			<menu_item_check label="Sombras del sol/la luna/proyectores" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO y sombras suavizadas" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="Capas alfa automáticas (deferidas)" name="Automatic Alpha Masks (deferred)"/> diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml index 457b756c7d..548f144742 100755 --- a/indra/newview/skins/default/xui/fr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml @@ -315,7 +315,7 @@  			<menu_item_call label="Base des infos de la texture sélectionnée" name="Selected Texture Info Basis"/>  			<menu_item_check label="Filaire" name="Wireframe"/>  			<menu_item_check label="Occlusion objet-objet" name="Object-Object Occlusion"/> -			<menu_item_check label="Éclairage et ombres" name="Lighting and Shadows"/> +			<menu_item_check label="Éclairage et ombres" name="Advanced Lighting Model"/>  			<menu_item_check label="Ombres du soleil/de la lune/des projecteurs" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO et lissage des ombres" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="Débogage GL" name="Debug GL"/> diff --git a/indra/newview/skins/default/xui/it/menu_viewer.xml b/indra/newview/skins/default/xui/it/menu_viewer.xml index c93b92029f..2b7bc71df7 100755 --- a/indra/newview/skins/default/xui/it/menu_viewer.xml +++ b/indra/newview/skins/default/xui/it/menu_viewer.xml @@ -294,7 +294,7 @@  		<menu label="Rendering" name="Rendering">  			<menu_item_check label="Assi" name="Axes"/>  			<menu_item_check label="Wireframe" name="Wireframe"/> -			<menu_item_check label="Luci e ombre" name="Lighting and Shadows"/> +			<menu_item_check label="Luci e ombre" name="Advanced Lighting Model"/>  			<menu_item_check label="Ombra dal sole, dalla luna e dai proiettori" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO e ombre fluide" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="Maschera alfa automatica (differita)" name="Automatic Alpha Masks (deferred)"/> diff --git a/indra/newview/skins/default/xui/ja/menu_viewer.xml b/indra/newview/skins/default/xui/ja/menu_viewer.xml index 6f650242b4..89f58d3bac 100755 --- a/indra/newview/skins/default/xui/ja/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ja/menu_viewer.xml @@ -315,7 +315,7 @@  			<menu_item_call label="選択したテクスチャ情報基底" name="Selected Texture Info Basis"/>  			<menu_item_check label="ワイヤーフレーム" name="Wireframe"/>  			<menu_item_check label="オブジェクト間オクルージョン" name="Object-Object Occlusion"/> -			<menu_item_check label="光と影" name="Lighting and Shadows"/> +			<menu_item_check label="光と影" name="Advanced Lighting Model"/>  			<menu_item_check label="太陽・月・プロジェクタからの影" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO と影の平滑化" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="GL デバッグ" name="Debug GL"/> diff --git a/indra/newview/skins/default/xui/pl/menu_viewer.xml b/indra/newview/skins/default/xui/pl/menu_viewer.xml index 24c961fa26..e1725fc308 100755 --- a/indra/newview/skins/default/xui/pl/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pl/menu_viewer.xml @@ -236,7 +236,7 @@  		<menu label="Renderowanie" name="Rendering">  			<menu_item_check label="Osie" name="Axes"/>  			<menu_item_check label="Tryb obrazu szkieletowego" name="Wireframe"/> -			<menu_item_check label="Oświetlenie i cienie" name="Lighting and Shadows"/> +			<menu_item_check label="Oświetlenie i cienie" name="Advanced Lighting Model"/>  			<menu_item_check label="Cienie Słońca/Księżyca/Projektory" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO and wygładzanie cienia" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="Globalne oświetlenie (eksperymentalne)" name="Global Illumination"/> diff --git a/indra/newview/skins/default/xui/pt/menu_viewer.xml b/indra/newview/skins/default/xui/pt/menu_viewer.xml index 703df84efb..15814fed4c 100755 --- a/indra/newview/skins/default/xui/pt/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml @@ -294,7 +294,7 @@  		<menu label="Rendering" name="Rendering">  			<menu_item_check label="Axes" name="Axes"/>  			<menu_item_check label="Wireframe" name="Wireframe"/> -			<menu_item_check label="Iluminação e sombras" name="Lighting and Shadows"/> +			<menu_item_check label="Iluminação e sombras" name="Advanced Lighting Model"/>  			<menu_item_check label="Sombras da projeção do sol/lua" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO e sombra suave" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="Máscaras alpha automáticas (adiadas)" name="Automatic Alpha Masks (deferred)"/> diff --git a/indra/newview/skins/default/xui/ru/menu_viewer.xml b/indra/newview/skins/default/xui/ru/menu_viewer.xml index d6625361c5..92a9943b93 100755 --- a/indra/newview/skins/default/xui/ru/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ru/menu_viewer.xml @@ -114,6 +114,7 @@  			<menu_item_call label="Купить" name="Menu Object Buy"/>  			<menu_item_call label="Взять" name="Menu Object Take"/>  			<menu_item_call label="Взять копию" name="Take Copy"/> +			<menu_item_call label="Сохранить в моем инвентаре" name="Save Object Back to My Inventory"/>  			<menu_item_call label="Сохранить в контенте объектов" name="Save Object Back to Object Contents"/>  			<menu_item_call label="Вернуть объект" name="Return Object back to Owner"/>  		</menu> @@ -128,7 +129,6 @@  			<menu_item_call label="Наборы связей..." name="pathfinding_linksets_menu_item"/>  			<menu_item_call label="Персонажи..." name="pathfinding_characters_menu_item"/>  			<menu_item_call label="Просмотр/тестирование..." name="pathfinding_console_menu_item"/> -			<menu_item_call label="Восстановить регион" name="pathfinding_rebake_navmesh_item"/>  		</menu>  		<menu label="Параметры" name="Options">  			<menu_item_check label="Показать расширенные разрешения" name="DebugPermissions"/> @@ -158,13 +158,6 @@  	<menu label="Справка" name="Help">  		<menu_item_call label="Инструкции..." name="How To"/>  		<menu_item_call label="Справка по [SECOND_LIFE]" name="Second Life Help"/> -		<menu_item_call label="Руководство пользователя" name="User’s guide"/> -		<menu_item_call label="База знаний" name="Knowledge Base"/> -		<menu_item_call label="Wiki" name="Wiki"/> -		<menu_item_call label="Форумы сообщества" name="Community Forums"/> -		<menu_item_call label="Портал поддержки" name="Support portal"/> -		<menu_item_call label="Новости [SECOND_LIFE]" name="Second Life News"/> -		<menu_item_call label="Блоги [SECOND_LIFE]" name="Second Life Blogs"/>  		<menu_item_call label="Жалоба" name="Report Abuse"/>  		<menu_item_call label="Сообщить об ошибке" name="Report Bug"/>  		<menu_item_call label="О [APP_NAME]" name="About Second Life"/> @@ -313,7 +306,7 @@  			<menu_item_call label="Выбранная текстура в основе" name="Selected Texture Info Basis"/>  			<menu_item_check label="Каркас" name="Wireframe"/>  			<menu_item_check label="Смыкание объектов" name="Object-Object Occlusion"/> -			<menu_item_check label="Освещение и тени" name="Lighting and Shadows"/> +			<menu_item_check label="Освещение и тени" name="Advanced Lighting Model"/>  			<menu_item_check label="Тени от солнца, луны и прожекторов" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO и сглаживание теней" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="Отладка GL" name="Debug GL"/> @@ -391,14 +384,9 @@  				<menu_item_call label="Проверка женщины" name="Test Female"/>  				<menu_item_check label="Разрешить выбор аватара" name="Allow Select Avatar"/>  			</menu> -			<menu label="Скорость анимации" name="Animation Speed"> -				<menu_item_call label="Ускорить все анимации на 10%" name="All Animations 10 Faster"/> -				<menu_item_call label="Замедлить все анимации на 10%" name="All Animations 10 Slower"/> -				<menu_item_call label="Восстановить скорость анимаций" name="Reset All Animation Speed"/> -				<menu_item_check label="Анимация медленных движений" name="Slow Motion Animations"/> -			</menu>  			<menu_item_call label="Скинуть параметры" name="Force Params to Default"/>  			<menu_item_check label="Данные об анимации" name="Animation Info"/> +			<menu_item_check label="Анимация медленных движений" name="Slow Motion Animations"/>  			<menu_item_check label="Показать взгляд" name="Show Look At"/>  			<menu_item_check label="Показать указание" name="Show Point At"/>  			<menu_item_check label="Отладка обновленных движений суставов" name="Debug Joint Updates"/> diff --git a/indra/newview/skins/default/xui/tr/menu_viewer.xml b/indra/newview/skins/default/xui/tr/menu_viewer.xml index c465966fc7..35485bb292 100755 --- a/indra/newview/skins/default/xui/tr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/tr/menu_viewer.xml @@ -313,7 +313,7 @@  			<menu_item_call label="Seçilen Doku Bilgi Temeli" name="Selected Texture Info Basis"/>  			<menu_item_check label="Telkafes" name="Wireframe"/>  			<menu_item_check label="Görünen Nesneler İçin Gölgeleme" name="Object-Object Occlusion"/> -			<menu_item_check label="Işıklandırma ve Gölgeler" name="Lighting and Shadows"/> +			<menu_item_check label="Işıklandırma ve Gölgeler" name="Advanced Lighting Model"/>  			<menu_item_check label="Güneş/Ay/Projektörlerden Gelen Gölgeler" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="SSAO ve Gölge Yumuşatma" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="GL Hata Ayıklama" name="Debug GL"/> diff --git a/indra/newview/skins/default/xui/zh/menu_viewer.xml b/indra/newview/skins/default/xui/zh/menu_viewer.xml index 09bdc57819..d4844b191b 100755 --- a/indra/newview/skins/default/xui/zh/menu_viewer.xml +++ b/indra/newview/skins/default/xui/zh/menu_viewer.xml @@ -313,7 +313,7 @@  			<menu_item_call label="已選取材質資訊基礎" name="Selected Texture Info Basis"/>  			<menu_item_check label="線框" name="Wireframe"/>  			<menu_item_check label="物件導向的遮蔽" name="Object-Object Occlusion"/> -			<menu_item_check label="光線和陰影" name="Lighting and Shadows"/> +			<menu_item_check label="光線和陰影" name="Advanced Lighting Model"/>  			<menu_item_check label="來自日/月/投影物的陰影" name="Shadows from Sun/Moon/Projectors"/>  			<menu_item_check label="屏幕空間環境光遮蔽和陰影平滑技術" name="SSAO and Shadow Smoothing"/>  			<menu_item_check label="GL 除錯" name="Debug GL"/> diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp index 41cb344808..3e55336f2d 100755 --- a/indra/newview/tests/llmediadataclient_test.cpp +++ b/indra/newview/tests/llmediadataclient_test.cpp @@ -39,6 +39,7 @@  #include "../llvovolume.h"  #include "../../llprimitive/llmediaentry.cpp" +#include "../../llprimitive/llmaterialid.cpp"  #include "../../llprimitive/lltextureentry.cpp"  #include "../../llmessage/tests/llcurl_stub.cpp" diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp index 50266cd117..b9712e5e9c 100755 --- a/indra/newview/tests/llviewerassetstats_test.cpp +++ b/indra/newview/tests/llviewerassetstats_test.cpp @@ -380,7 +380,7 @@ namespace tut  		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false);  		LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false); - +		  		LLViewerAssetStatsFF::set_region(region2_handle);  		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 2578c81224..35451c9621 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -729,7 +729,7 @@ class DarwinManifest(ViewerManifest):                                  'SLVoice',                                  ):                       self.path2basename(libdir, libfile) - +                                  # our apps                  for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"),                                           # plugin launcher @@ -1038,9 +1038,6 @@ class Linux_i686Manifest(LinuxManifest):              self.path("libboost_signals-mt.so.*")              self.path("libboost_system-mt.so.*")              self.path("libboost_thread-mt.so.*") -            self.path("libbreakpad_client.so.0.0.0") -            self.path("libbreakpad_client.so.0") -            self.path("libbreakpad_client.so")              self.path("libcollada14dom.so")              self.path("libdb*.so")              self.path("libcrypto.so.*")  | 
