diff options
Diffstat (limited to 'indra/newview')
146 files changed, 7894 insertions, 2421 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 6e0bb161af..ff260e6040 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -173,6 +173,7 @@ set(viewer_SOURCE_FILES lldrawpoolavatar.cpp lldrawpoolbump.cpp lldrawpoolground.cpp + lldrawpoolmaterials.cpp lldrawpoolsimple.cpp lldrawpoolsky.cpp lldrawpoolterrain.cpp @@ -357,6 +358,7 @@ set(viewer_SOURCE_FILES llmaniptranslate.cpp llmarketplacefunctions.cpp llmarketplacenotifications.cpp + llmaterialmgr.cpp llmediactrl.cpp llmediadataclient.cpp llmenuoptionpathfindingrebakenavmesh.cpp @@ -753,6 +755,7 @@ set(viewer_HEADER_FILES lldrawpoolalpha.h lldrawpoolavatar.h lldrawpoolbump.h + lldrawpoolmaterials.h lldrawpoolground.h lldrawpoolsimple.h lldrawpoolsky.h @@ -937,6 +940,7 @@ set(viewer_HEADER_FILES llmaniptranslate.h llmarketplacefunctions.h llmarketplacenotifications.h + llmaterialmgr.h llmediactrl.h llmediadataclient.h llmenuoptionpathfindingrebakenavmesh.h @@ -2133,6 +2137,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/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 31c730e0bc..06f1b32fe2 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3336,17 +3336,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> @@ -8429,7 +8418,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> @@ -8570,7 +8559,7 @@ <key>Type</key> <string>U32</string> <key>Value</key> - <real>512</real> + <real>1024</real> </map> <key>RenderSpecularResY</key> @@ -8582,7 +8571,7 @@ <key>Type</key> <string>U32</string> <key>Value</key> - <real>128</real> + <real>256</real> </map> <key>RenderSpecularExponent</key> @@ -8600,7 +8589,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> @@ -8788,7 +8777,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> @@ -8799,7 +8788,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> @@ -14458,6 +14447,49 @@ <key>Value</key> <integer>0</integer> </map> + <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> + <key>FMODExProfilerEnable</key> + <map> + <key>Comment</key> + <string>Enable profiler tool if using FMOD Ex</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>FMODExDecodeBufferSize</key> + <map> + <key>Comment</key> + <string>Sets the streaming decode buffer size (in milliseconds)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>1000</integer> + </map> + <key>FMODExStreamBufferSize</key> + <map> + <key>Comment</key> + <string>Sets the streaming buffer size (in milliseconds)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>7000</integer> + </map> <key>DisablePrecacheDelayAfterTeleporting</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl index 43ed41a205..2745d5fd95 100755 --- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl @@ -26,7 +26,7 @@ ATTRIBUTE vec4 weight4; -uniform mat4 matrixPalette[32]; +uniform mat4 matrixPalette[64]; mat4 getObjectSkinnedTransform() { diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index dd87ddb330..50b43f6a8d 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,117 @@ 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.rgb; + color.rgb += diff.rgb * vary_pointlight_col * col.rgb; 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..cccc7275ab 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,31 @@ 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.rgb; + color.rgb += diff.rgb * vary_pointlight_col * light_col; 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..77d02b36ff 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,28 @@ 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) +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 +119,103 @@ 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))); + 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..c030c23515 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -64,11 +64,23 @@ vec4 getPosition(vec2 pos_screen) return pos; } +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; +} + 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/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..8d76485886 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -42,7 +42,8 @@ void main() { float shadow = 1.0; - vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color; + vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color; + color.rgb = pow(color.rgb,vec3(2.2f,2.2f,2.2f)); color.rgb = fullbrightAtmosTransport(color.rgb); diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl index 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..a4eaac8483 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -0,0 +1,632 @@ +/** + * @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 + + +#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) +{ + //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); + col += lit*scol*light_col.rgb*spec.rgb; + //col += spec.rgb; + } + } + } + + return max(col, vec3(0.0,0.0,0.0)); + +} + +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; +} + +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; +} + +#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; + +#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; + +vec2 encode_normal(vec3 n) +{ + float f = sqrt(8 * n.z + 8); + return n.xy / f + 0.5; +} + +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) + diffcol.rgb = pow(diffcol.rgb, vec3(2.2)); +#endif + +#if HAS_SPECULAR_MAP + vec4 spec = texture2D(specularMap, vary_texcoord2.xy); +#else + vec4 spec = specular_color; +#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 = 0; +#endif + + vec4 final_specular = spec; +#if HAS_SPECULAR_MAP + //final_color.rgb *= 1 - spec.a * env_intensity; + final_specular.rgb *= specular_color.rgb; + + vec4 final_normal = vec4(encode_normal(normalize(tnorm)), spec.a * env_intensity, 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); + col.rgb = col.rgb + atmosAffectDirectionalLight(final_da * 2.6); + col.rgb *= diffuse.rgb; + + + 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; + col += spec_contrib; + } + + if (envIntensity > 0.0) + { + //add environmentmap + vec3 env_vec = env_mat * refnormpersp; + col = mix(col.rgb, pow(textureCube(environmentMap, env_vec).rgb, vec3(2.2)) * 2.2, + max(envIntensity-diffuse.a*2.0, 0.0)); + } + + col = atmosLighting(col); + col = scaleSoftClip(col); + + vec3 npos = normalize(-pos.xyz); + + #define LIGHT_LOOP(i) col.rgb = col.rgb + calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); + + LIGHT_LOOP(1) + LIGHT_LOOP(2) + LIGHT_LOOP(3) + LIGHT_LOOP(4) + LIGHT_LOOP(5) + LIGHT_LOOP(6) + LIGHT_LOOP(7) + + frag_color.rgb = col.rgb; + frag_color.a = diffcol.a*vertex_color.a; + +#else + frag_data[0] = final_color; + +#ifdef UGLY_MAC_HACK + // magic spec exp clamp fixes rendering artifacts on older mac GF drivers + // + final_specular = min(final_specular, vec4(1.0f, 1.0f, 1.0f, 0.125f)); +#endif + + 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..0638dcfa55 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl @@ -0,0 +1,143 @@ +/** + * @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 vec3 binormal; +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 b = normalize((mat*vec4(binormal.xyz+position.xyz,1.0)).xyz-pos.xyz); + vec3 t = cross(b, n); + + vary_mat0 = vec3(t.x, b.x, n.x); + vary_mat1 = vec3(t.y, b.y, n.y); + vary_mat2 = vec3(t.z, b.z, n.z); +#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 b = normalize(normal_matrix * binormal); + vec3 t = cross(b, n); + + vary_mat0 = vec3(t.x, b.x, n.x); + vary_mat1 = vec3(t.y, b.y, n.y); + vary_mat2 = vec3(t.z, b.z, n.z); +#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..338532e71d 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -56,6 +56,17 @@ uniform float far_z; uniform mat4 inv_proj; +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; +} + vec4 getPosition(vec2 pos_screen) { float depth = texture2DRect(depthMap, pos_screen.xy).r; @@ -79,7 +90,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 +121,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..6675bfde69 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,26 @@ uniform vec2 screen_res; uniform mat4 inv_proj; +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; +} + +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,7 +102,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); @@ -101,7 +120,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); @@ -142,7 +162,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 +179,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 +192,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 +211,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 +226,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 +275,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 +285,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..69cdb2ce71 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -54,6 +54,17 @@ uniform vec2 screen_res; uniform mat4 inv_proj; uniform vec4 viewport; +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; +} + vec4 getPosition(vec2 pos_screen) { float depth = texture2DRect(depthMap, pos_screen.xy).r; @@ -84,7 +95,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 +111,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..2d6bce02c9 --- /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.0)); +} + 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..49ad064364 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,0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 89448e2167..a1dff9188f 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,17 @@ vec3 vary_AtmosAttenuation; uniform mat4 inv_proj; uniform vec2 screen_res; +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; +} + vec4 getPosition_d(vec2 pos_screen, float depth) { vec2 sc = pos_screen.xy*2.0; @@ -116,7 +128,6 @@ vec3 getAtmosAttenuation() return vary_AtmosAttenuation; } - void setPositionEye(vec3 v) { vary_PositionEye = v; @@ -220,9 +231,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)) * 2.2); + setAmblitColor(pow(vec3(tmpAmbient * .25), vec3(global_gamma)) * 2.2); + setAdditiveColor(pow(getAdditiveColor() * vec3(1.0 - temp1), vec3(global_gamma)) * 2.2); } vec3 atmosLighting(vec3 light) @@ -276,55 +287,55 @@ 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)); + col += atmosAffectDirectionalLight(max(min(da, 1.0) * 2.6, diffuse.a)); 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 - vec3 env_vec = env_mat * refnormpersp; - col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb, - max(spec.a-diffuse.a*2.0, 0.0)); } + if (envIntensity > 0.0) + { //add environmentmap + vec3 env_vec = env_mat * refnormpersp; + col = mix(col.rgb, pow(textureCube(environmentMap, env_vec).rgb, vec3(2.2)) * 2.2, + envIntensity); + } + col = atmosLighting(col); col = scaleSoftClip(col); col = mix(col.rgb, diffuse.rgb, diffuse.a); } - else - { - col = diffuse.rgb; - } - + frag_color.rgb = col; - frag_color.a = bloom; + //frag_color.a = bloom; + frag_color.a = 0.0; } 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..c918a42c73 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,36 @@ 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; +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; +} + +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 +100,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 +118,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 +158,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 +177,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 +191,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 +228,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 +279,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 +289,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..1470239a71 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -49,6 +49,17 @@ VARYING vec2 vary_fragcoord; uniform mat4 inv_proj; uniform vec2 screen_res; +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; +} + vec4 getPosition(vec2 pos_screen) { float depth = texture2DRect(depthMap, pos_screen.xy).r; @@ -123,7 +134,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/lighting/lightFullbrightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl index 6c34643aab..e130ef5d91 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); @@ -45,7 +46,7 @@ void fullbright_lighting() { discard; } - + 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/lightFullbrightNonIndexedAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl index f4477bd29a..56ad658696 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); @@ -47,7 +48,7 @@ void fullbright_lighting() { discard; } - + 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/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/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/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/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..127c1709b8 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,13 @@ uniform vec3 light_direction[8]; uniform vec3 light_attenuation[8]; uniform vec3 light_diffuse[8]; -float calcDirectionalLight(vec3 n, vec3 l) +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 +116,100 @@ 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))); + 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..a6b0f7e7c1 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,28 @@ uniform vec2 screen_res; uniform mat4 inv_proj; +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; +} + +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 +104,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 +122,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 +175,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 +193,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 +202,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 +218,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 +248,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 +295,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 +305,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..10a598a85c 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/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 vec4 shadow_clip; @@ -79,6 +80,17 @@ vec3 vary_AmblitColor; vec3 vary_AdditiveColor; vec3 vary_AtmosAttenuation; +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; +} + vec4 getPosition_d(vec2 pos_screen, float depth) { vec2 sc = pos_screen.xy*2.0; @@ -222,9 +234,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) @@ -278,17 +290,16 @@ 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); float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); - + vec4 diffuse = texture2DRect(diffuseRect, tc); vec3 col; float bloom = 0.0; - if (diffuse.a < 0.9) { vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); @@ -299,38 +310,39 @@ void main() calcAtmospherics(pos.xyz, ambocc); col = atmosAmbient(vec3(0)); - col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a)); + col += atmosAffectDirectionalLight(max(min(da, scol) * 2.6, diffuse.a)); 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 + 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)); + col = mix(col.rgb, pow(textureCube(environmentMap, env_vec).rgb, vec3(2.2)) * 2.2, + envIntensity); } col = atmosLighting(col); col = scaleSoftClip(col); - col = mix(col, diffuse.rgb, diffuse.a); - } - else - { - col = diffuse.rgb; + col = mix(col.rgb, diffuse.rgb, diffuse.a); } + 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..91ff1f1e76 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,26 @@ uniform vec2 screen_res; uniform mat4 inv_proj; +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; +} + +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 +103,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 +121,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 +174,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 +190,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 +204,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 +215,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 +245,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 +292,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 +302,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..fa2f415e15 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -65,6 +65,17 @@ uniform float shadow_offset; uniform float spot_shadow_bias; uniform float spot_shadow_offset; +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; +} + vec4 getPosition(vec2 pos_screen) { float depth = texture2DRect(depthMap, pos_screen.xy).r; @@ -125,11 +136,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 +147,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..847fea6c08 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -66,6 +66,17 @@ uniform float shadow_offset; uniform float spot_shadow_bias; uniform float spot_shadow_offset; +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; +} + vec4 getPosition(vec2 pos_screen) { float depth = texture2DRect(depthMap, pos_screen.xy).r; @@ -186,11 +197,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 +208,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..c1eff73bc8 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) { @@ -131,9 +132,9 @@ void calcAtmospherics(vec3 inPositionEye) { + 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/gpu_table.txt b/indra/newview/gpu_table.txt index 4c39014c8b..c64e11929d 100755 --- a/indra/newview/gpu_table.txt +++ b/indra/newview/gpu_table.txt @@ -32,20 +32,20 @@ // 1 - We claim to support this card. // -3Dfx .*3Dfx.* 0 0 0 0 -3Dlabs .*3Dlabs.* 0 0 0 0 -ATI 3D-Analyze .*ATI.*3D-Analyze.* 0 0 0 0 -ATI All-in-Wonder 7500 .*ATI.*All-in-Wonder 75.* 0 1 0 0 -ATI All-in-Wonder 8500 .*ATI.*All-in-Wonder 85.* 0 1 0 0 -ATI All-in-Wonder 9200 .*ATI.*All-in-Wonder 92.* 0 1 0 0 +3Dfx .*3Dfx.* 0 0 0 0 +3Dlabs .*3Dlabs.* 0 0 0 0 +ATI 3D-Analyze .*ATI.*3D-Analyze.* 0 0 0 0 +ATI All-in-Wonder 7500 .*ATI.*All-in-Wonder 75.* 0 1 0 0 +ATI All-in-Wonder 8500 .*ATI.*All-in-Wonder 85.* 0 1 0 0 +ATI All-in-Wonder 9200 .*ATI.*All-in-Wonder 92.* 0 1 0 0 ATI All-in-Wonder 9xxx .*ATI.*All-in-Wonder 9.* 1 1 0 0 -ATI All-in-Wonder HD .*ATI.*All-in-Wonder HD.* 1 1 1 3.3 -ATI All-in-Wonder X600 .*ATI.*All-in-Wonder X6.* 1 1 0 0 -ATI All-in-Wonder X800 .*ATI.*All-in-Wonder X8.* 1 1 1 2.1 -ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3 1 0 0 -ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3 1 0 0 -ATI All-in-Wonder PCI-E .*ATI.*All-in-Wonder.*PCI-E.* 1 1 0 0 -ATI All-in-Wonder Radeon .*ATI.*All-in-Wonder Radeon.* 0 1 0 0 +ATI All-in-Wonder HD .*ATI.*All-in-Wonder HD.* 1 1 1 3.3 +ATI All-in-Wonder X600 .*ATI.*All-in-Wonder X6.* 1 1 0 0 +ATI All-in-Wonder X800 .*ATI.*All-in-Wonder X8.* 1 1 1 2.1 +ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3 1 0 0 +ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3 1 0 0 +ATI All-in-Wonder PCI-E .*ATI.*All-in-Wonder.*PCI-E.* 1 1 0 0 +ATI All-in-Wonder Radeon .*ATI.*All-in-Wonder Radeon.* 0 1 0 0 ATI ASUS ARES .*ATI.*ASUS.*ARES.* 3 1 0 0 ATI ASUS A9xxx .*ATI.*ASUS.*A9.* 1 1 0 0 ATI ASUS AH24xx .*ATI.*ASUS.*AH24.* 1 1 1 3.3 @@ -79,30 +79,30 @@ ATI ASUS Radeon X1xxx .*ATI.*ASUS.*X1.* 2 1 1 2.1 ATI Radeon X7xx .*ATI.*ASUS.*X7.* 1 1 0 0 ATI Radeon X19xx .*ATI.*(Radeon|Diamond) X19.* ?.* 2 1 1 2.1 ATI Radeon X18xx .*ATI.*(Radeon|Diamond) X18.* ?.* 3 1 1 2.1 -ATI Radeon X17xx .*ATI.*(Radeon|Diamond) X17.* ?.* 1 1 1 2.1 +ATI Radeon X17xx .*ATI.*(Radeon|Diamond) X17.* ?.* 1 1 1 2.1 ATI Radeon X16xx .*ATI.*(Radeon|Diamond) X16.* ?.* 1 1 1 2.1 ATI Radeon X15xx .*ATI.*(Radeon|Diamond) X15.* ?.* 1 1 1 2.1 ATI Radeon X13xx .*ATI.*(Radeon|Diamond) X13.* ?.* 1 1 1 2.1 ATI Radeon X1xxx .*ATI.*(Radeon|Diamond) X1.. ?.* 0 1 1 2.1 ATI Radeon X2xxx .*ATI.*(Radeon|Diamond) X2.. ?.* 1 1 1 2.1 -ATI Display Adapter .*ATI.*display adapter.* 1 1 1 4.1 -ATI FireGL 5200 .*ATI.*FireGL V52.* 1 1 1 2.1 -ATI FireGL 5xxx .*ATI.*FireGL V5.* 2 1 1 3.3 -ATI FireGL .*ATI.*Fire.*GL.* 4 1 1 4.2 +ATI Display Adapter .*ATI.*display adapter.* 1 1 1 4.1 +ATI FireGL 5200 .*ATI.*FireGL V52.* 1 1 1 2.1 +ATI FireGL 5xxx .*ATI.*FireGL V5.* 2 1 1 3.3 +ATI FireGL .*ATI.*Fire.*GL.* 4 1 1 4.2 ATI FirePro M3900 .*ATI.*FirePro.*M39.* 2 1 0 0 -ATI FirePro M5800 .*ATI.*FirePro.*M58.* 3 1 0 0 -ATI FirePro M7740 .*ATI.*FirePro.*M77.* 3 1 0 0 -ATI FirePro M7820 .*ATI.*FirePro.*M78.* 5 1 1 4.2 +ATI FirePro M5800 .*ATI.*FirePro.*M58.* 3 1 0 0 +ATI FirePro M7740 .*ATI.*FirePro.*M77.* 3 1 0 0 +ATI FirePro M7820 .*ATI.*FirePro.*M78.* 5 1 1 4.2 ATI FireMV .*ATI.*FireMV.* 0 1 1 1.3 -ATI Generic .*ATI.*Generic.* 0 0 0 0 -ATI Hercules 9800 .*ATI.*Hercules.*9800.* 1 1 0 0 +ATI Generic .*ATI.*Generic.* 0 0 0 0 +ATI Hercules 9800 .*ATI.*Hercules.* 9800.* 1 1 0 0 ATI IGP 340M .*ATI.*IGP.*340M.* 0 0 0 0 -ATI M52 .*ATI.*M52.* 1 1 0 0 -ATI M54 .*ATI.*M54.* 1 1 0 0 -ATI M56 .*ATI.*M56.* 1 1 0 0 -ATI M71 .*ATI.*M71.* 1 1 0 0 -ATI M72 .*ATI.*M72.* 1 1 0 0 -ATI M76 .*ATI.*M76.* 3 1 0 0 +ATI M52 .*ATI.*M52.* 1 1 0 0 +ATI M54 .*ATI.*M54.* 1 1 0 0 +ATI M56 .*ATI.*M56.* 1 1 0 0 +ATI M71 .*ATI.*M71.* 1 1 0 0 +ATI M72 .*ATI.*M72.* 1 1 0 0 +ATI M76 .*ATI.*M76.* 3 1 0 0 ATI Radeon HD 64xx .*ATI.*AMD Radeon.* HD [67]4..[MG] 2 1 1 4.2 ATI Radeon HD 65xx .*ATI.*AMD Radeon.* HD [67]5..[MG] 2 1 1 4.2 ATI Radeon HD 66xx .*ATI.*AMD Radeon.* HD [67]6..[MG] 3 1 1 4.2 @@ -124,12 +124,12 @@ ATI ASUS HD7600 .*ATI.*ASUS.* HD76.* 3 1 0 0 ATI ASUS HD7700 .*ATI.*ASUS.* HD77.* 4 1 1 4.2 ATI ASUS HD7800 .*ATI.*ASUS.* HD78.* 5 1 1 4.2 ATI ASUS HD7900 .*ATI.*ASUS.* HD79.* 5 1 1 4.2 -ATI Mobility Radeon 4100 .*ATI.*Mobility.*41.. 1 1 1 3.3 -ATI Mobility Radeon 7xxx .*ATI.*Mobility.*Radeon 7.* 0 1 1 1.3 -ATI Mobility Radeon 8xxx .*ATI.*Mobility.*Radeon 8.* 0 1 0 0 -ATI Mobility Radeon 9800 .*ATI.*Mobility.*98.* 1 1 0 0 -ATI Mobility Radeon 9700 .*ATI.*Mobility.*97.* 0 1 1 2.1 -ATI Mobility Radeon 9600 .*ATI.*Mobility.*96.* 1 1 1 2.1 +ATI Mobility Radeon 4100 .*ATI.*Mobility.* 41.. 1 1 1 3.3 +ATI Mobility Radeon 7xxx .*ATI.*Mobility.*Radeon 7.* 0 1 1 1.3 +ATI Mobility Radeon 8xxx .*ATI.*Mobility.*Radeon 8.* 0 1 0 0 +ATI Mobility Radeon 9800 .*ATI.*Mobility.* 98.* 1 1 0 0 +ATI Mobility Radeon 9700 .*ATI.*Mobility.* 97.* 0 1 1 2.1 +ATI Mobility Radeon 9600 .*ATI.*Mobility.* 96.* 1 1 1 2.1 ATI Mobility Radeon HD 530v .*ATI.*Mobility.*HD *530v.* 1 1 1 3.3 ATI Mobility Radeon HD 540v .*ATI.*Mobility.*HD *540v.* 1 1 1 3.3 ATI Mobility Radeon HD 545v .*ATI.*Mobility.*HD *545v.* 2 1 1 4 @@ -176,7 +176,7 @@ ATI Radeon HD 3400 .*ATI.*Radeon HD *34.. 1 1 1 4 ATI Radeon HD 3500 .*ATI.*Radeon HD *35.. 2 1 0 0 ATI Radeon HD 3600 .*ATI.*Radeon HD *36.. 3 1 1 3.3 ATI Radeon HD 3700 .*ATI.*Radeon HD *37.. 3 1 0 0 -ATI HD3700 .*ATI.* HD37.. 3 1 0 3.3 +ATI HD3700 .*ATI.* HD37.. 3 1 0 3.3 ATI Radeon HD 3800 .*ATI.*Radeon HD *38.. 3 1 1 4 ATI Radeon HD 4100 .*ATI.*Radeon HD *41.. 1 1 0 0 ATI Radeon HD 4200 .*ATI.*Radeon HD *42.. 1 1 1 4 @@ -202,128 +202,128 @@ ATI Radeon HD 6600 .*ATI.*Radeon HD *66.. 3 1 1 4.2 ATI Radeon HD 6700 .*ATI.*Radeon HD *67.. 3 1 1 4.2 ATI Radeon HD 6800 .*ATI.*Radeon HD *68.. 4 1 1 4.2 ATI Radeon HD 6900 .*ATI.*Radeon HD *69.. 5 1 1 4.2 -ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 0 0 0 0 -ATI Radeon 2100 .*ATI.*Radeon 21.. 0 1 1 2.1 -ATI Radeon 3000 .*ATI.*Radeon 30.. 1 1 1 4 -ATI Radeon 3100 .*ATI.*Radeon 31.. 0 1 1 3.3 -ATI Radeon 5xxx .*ATI.*Radeon 5... 3 1 0 0 -ATI Radeon 7xxx .*ATI.*Radeon 7... 0 1 1 2 -ATI Radeon 8xxx .*ATI.*Radeon 8... 0 1 0 0 -ATI Radeon 9000 .*ATI.*Radeon 90.. 0 1 1 1.3 -ATI Radeon 9100 .*ATI.*Radeon 91.. 0 1 0 0 -ATI Radeon 9200 .*ATI.*Radeon 92.. 0 1 1 1.3 -ATI Radeon 9500 .*ATI.*Radeon 95.. 0 1 1 2.1 -ATI Radeon 9600 .*ATI.*Radeon 96.. 0 1 1 2.1 -ATI Radeon 9700 .*ATI.*Radeon 97.. 1 1 0 0 -ATI Radeon 9800 .*ATI.*Radeon 98.. 1 1 1 2.1 -ATI Radeon RV250 .*ATI.*RV250.* 0 1 0 0 -ATI Radeon RV600 .*ATI.*RV6.* 1 1 0 0 -ATI Radeon RX700 .*ATI.*RX70.* 1 1 0 0 +ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 0 0 0 0 +ATI Radeon 2100 .*ATI.*Radeon 21.. 0 1 1 2.1 +ATI Radeon 3000 .*ATI.*Radeon 30.. 1 1 1 4 +ATI Radeon 3100 .*ATI.*Radeon 31.. 0 1 1 3.3 +ATI Radeon 5xxx .*ATI.*Radeon 5... 3 1 0 0 +ATI Radeon 7xxx .*ATI.*Radeon 7... 0 1 1 2 +ATI Radeon 8xxx .*ATI.*Radeon 8... 0 1 0 0 +ATI Radeon 9000 .*ATI.*Radeon 90.. 0 1 1 1.3 +ATI Radeon 9100 .*ATI.*Radeon 91.. 0 1 0 0 +ATI Radeon 9200 .*ATI.*Radeon 92.. 0 1 1 1.3 +ATI Radeon 9500 .*ATI.*Radeon 95.. 0 1 1 2.1 +ATI Radeon 9600 .*ATI.*Radeon 96.. 0 1 1 2.1 +ATI Radeon 9700 .*ATI.*Radeon 97.. 1 1 0 0 +ATI Radeon 9800 .*ATI.*Radeon 98.. 1 1 1 2.1 +ATI Radeon RV250 .*ATI.*RV250.* 0 1 0 0 +ATI Radeon RV600 .*ATI.*RV6.* 1 1 0 0 +ATI Radeon RX700 .*ATI.*RX70.* 1 1 0 0 ATI Radeon RX800 .*ATI.*Radeon *RX80.* 2 1 0 0 -ATI RS880M .*ATI.*RS880M 1 1 0 0 -ATI Radeon RX9550 .*ATI.*RX9550.* 1 1 0 0 -ATI Radeon VE .*ATI.*Radeon.*VE.* 0 0 0 0 +ATI RS880M .*ATI.*RS880M 1 1 0 0 +ATI Radeon RX9550 .*ATI.*RX9550.* 1 1 0 0 +ATI Radeon VE .*ATI.*Radeon.*VE.* 0 0 0 0 ATI Radeon X300 .*ATI.*Radeon *X3.* 1 1 1 2.1 -ATI Radeon X400 .*ATI.*Radeon ?X4.* 0 1 0 0 -ATI Radeon X500 .*ATI.*Radeon ?X5.* 1 1 1 2.1 +ATI Radeon X400 .*ATI.*Radeon ?X4.* 0 1 0 0 +ATI Radeon X500 .*ATI.*Radeon ?X5.* 1 1 1 2.1 ATI Radeon X600 .*ATI.*Radeon ?X6.* 1 1 1 2.1 -ATI Radeon X700 .*ATI.*Radeon ?X7.* 2 1 1 2.1 -ATI Radeon X800 .*ATI.*Radeon ?X8.* 1 1 1 2.1 -ATI Radeon X900 .*ATI.*Radeon ?X9.* 2 1 0 0 -ATI Radeon Xpress .*ATI.*Radeon Xpress.* 0 1 1 2.1 -ATI Rage 128 .*ATI.*Rage 128.* 0 1 0 0 -ATI R300 (9700) .*R300.* 0 1 1 2.1 -ATI R350 (9800) .*R350.* 1 1 0 0 -ATI R580 (X1900) .*R580.* 3 1 0 0 -ATI RC410 (Xpress 200) .*RC410.* 0 0 0 0 -ATI RS48x (Xpress 200x) .*RS48.* 0 0 0 0 -ATI RS600 (Xpress 3200) .*RS600.* 0 0 0 0 -ATI RV350 (9600) .*RV350.* 0 1 0 0 -ATI RV370 (X300) .*RV370.* 0 1 0 0 -ATI RV410 (X700) .*RV410.* 1 1 0 0 -ATI RV515 .*RV515.* 1 1 0 0 -ATI RV570 (X1900 GT/PRO) .*RV570.* 3 1 0 0 -ATI RV380 .*RV380.* 0 1 0 0 -ATI RV530 .*RV530.* 1 1 0 0 -ATI RX480 (Xpress 200P) .*RX480.* 0 1 0 0 -ATI RX700 .*RX700.* 1 1 0 0 -AMD ANTILLES (HD 6990) .*(AMD|ATI).*Antilles.* 3 1 0 0 -AMD BARTS (HD 6800) .*(AMD|ATI).*Barts.* 3 1 1 2.1 -AMD CAICOS (HD 6400) .*(AMD|ATI).*Caicos.* 3 1 0 0 -AMD CAYMAN (HD 6900) .*(AMD|ATI).*(Cayman|CAYMAM).* 3 1 0 0 +ATI Radeon X700 .*ATI.*Radeon ?X7.* 2 1 1 2.1 +ATI Radeon X800 .*ATI.*Radeon ?X8.* 1 1 1 2.1 +ATI Radeon X900 .*ATI.*Radeon ?X9.* 2 1 0 0 +ATI Radeon Xpress .*ATI.*Radeon Xpress.* 0 1 1 2.1 +ATI Rage 128 .*ATI.*Rage 128.* 0 1 0 0 +ATI R300 (9700) .*R300.* 0 1 1 2.1 +ATI R350 (9800) .*R350.* 1 1 0 0 +ATI R580 (X1900) .*R580.* 3 1 0 0 +ATI RC410 (Xpress 200) .*RC410.* 0 0 0 0 +ATI RS48x (Xpress 200x) .*RS48.* 0 0 0 0 +ATI RS600 (Xpress 3200) .*RS600.* 0 0 0 0 +ATI RV350 (9600) .*RV350.* 0 1 0 0 +ATI RV370 (X300) .*RV370.* 0 1 0 0 +ATI RV410 (X700) .*RV410.* 1 1 0 0 +ATI RV515 .*RV515.* 1 1 0 0 +ATI RV570 (X1900 GT/PRO) .*RV570.* 3 1 0 0 +ATI RV380 .*RV380.* 0 1 0 0 +ATI RV530 .*RV530.* 1 1 0 0 +ATI RX480 (Xpress 200P) .*RX480.* 0 1 0 0 +ATI RX700 .*RX700.* 1 1 0 0 +AMD ANTILLES (HD 6990) .*(AMD|ATI).*Antilles.* 3 1 0 0 +AMD BARTS (HD 6800) .*(AMD|ATI).*Barts.* 3 1 1 2.1 +AMD CAICOS (HD 6400) .*(AMD|ATI).*Caicos.* 3 1 0 0 +AMD CAYMAN (HD 6900) .*(AMD|ATI).*(Cayman|CAYMAM).* 3 1 0 0 AMD CEDAR (HD 5450) .*(AMD|ATI).*Cedar.* 2 1 0 0 -AMD CYPRESS (HD 5800) .*(AMD|ATI).*Cypress.* 3 1 0 0 -AMD HEMLOCK (HD 5970) .*(AMD|ATI).*Hemlock.* 3 1 0 0 -AMD JUNIPER (HD 5700) .*(AMD|ATI).*Juniper.* 3 1 0 0 -AMD PARK .*(AMD|ATI).*Park.* 3 1 0 0 +AMD CYPRESS (HD 5800) .*(AMD|ATI).*Cypress.* 3 1 0 0 +AMD HEMLOCK (HD 5970) .*(AMD|ATI).*Hemlock.* 3 1 0 0 +AMD JUNIPER (HD 5700) .*(AMD|ATI).*Juniper.* 3 1 0 0 +AMD PARK .*(AMD|ATI).*Park.* 3 1 0 0 AMD REDWOOD (HD 5500/5600) .*(AMD|ATI).*Redwood.* 3 1 0 0 AMD TURKS (HD 6500/6600) .*(AMD|ATI).*Turks.* 3 1 0 0 -AMD RS780 (HD 3200) .*RS780.* 0 1 1 2.1 -AMD RS880 (HD 4200) .*RS880.* 0 1 1 3.2 -AMD RV610 (HD 2400) .*RV610.* 1 1 0 0 -AMD RV620 (HD 3400) .*RV620.* 1 1 0 0 -AMD RV630 (HD 2600) .*RV630.* 2 1 0 0 +AMD RS780 (HD 3200) .*RS780.* 0 1 1 2.1 +AMD RS880 (HD 4200) .*RS880.* 0 1 1 3.2 +AMD RV610 (HD 2400) .*RV610.* 1 1 0 0 +AMD RV620 (HD 3400) .*RV620.* 1 1 0 0 +AMD RV630 (HD 2600) .*RV630.* 2 1 0 0 AMD RV635 (HD 3600) .*RV635.* 3 1 0 0 -AMD RV670 (HD 3800) .*RV670.* 3 1 0 0 -AMD R680 (HD 3870 X2) .*R680.* 3 1 0 0 -AMD R700 (HD 4800 X2) .*R700.* 3 1 0 0 -AMD RV710 (HD 4300) .*RV710.* 0 1 1 1.4 +AMD RV670 (HD 3800) .*RV670.* 3 1 0 0 +AMD R680 (HD 3870 X2) .*R680.* 3 1 0 0 +AMD R700 (HD 4800 X2) .*R700.* 3 1 0 0 +AMD RV710 (HD 4300) .*RV710.* 0 1 1 1.4 AMD RV730 (HD 4600) .*RV730.* 3 1 0 0 -AMD RV740 (HD 4700) .*RV740.* 3 1 0 0 -AMD RV770 (HD 4800) .*RV770.* 3 1 0 0 -AMD RV790 (HD 4800) .*RV790.* 3 1 0 0 -ATI 760G/Radeon 3000 .*ATI.*AMD 760G.* 1 1 1 3.3 -ATI 780L/Radeon 3000 .*ATI.*AMD 780L.* 1 1 0 0 -ATI Radeon DDR .*ATI.*Radeon ?DDR.* 0 1 0 0 +AMD RV740 (HD 4700) .*RV740.* 3 1 0 0 +AMD RV770 (HD 4800) .*RV770.* 3 1 0 0 +AMD RV790 (HD 4800) .*RV790.* 3 1 0 0 +ATI 760G/Radeon 3000 .*ATI.*AMD 760G.* 1 1 1 3.3 +ATI 780L/Radeon 3000 .*ATI.*AMD 780L.* 1 1 0 0 +ATI Radeon DDR .*ATI.*Radeon ?DDR.* 0 1 0 0 ATI FirePro 2000 .*ATI.*FirePro 2.* 2 1 1 4.1 -ATI FirePro 3000 .*ATI.*FirePro V3.* 2 1 0 0 +ATI FirePro 3000 .*ATI.*FirePro V3.* 2 1 0 0 ATI FirePro 4000 .*ATI.*FirePro V4.* 2 1 0 0 -ATI FirePro 5000 .*ATI.*FirePro V5.* 3 1 0 0 -ATI FirePro 7000 .*ATI.*FirePro V7.* 3 1 0 0 -ATI FirePro M .*ATI.*FirePro M.* 3 1 1 4.2 -ATI R300 (9700) .*R300.* 0 1 1 2.1 +ATI FirePro 5000 .*ATI.*FirePro V5.* 3 1 0 0 +ATI FirePro 7000 .*ATI.*FirePro V7.* 3 1 0 0 +ATI FirePro M .*ATI.*FirePro M.* 3 1 1 4.2 +ATI R300 (9700) .*R300.* 0 1 1 2.1 ATI Radeon .*ATI.*(Diamond|Radeon).* 0 1 0 4.2 -Intel X3100 .*Intel.*X3100.* 1 1 1 2.1 -Intel GMA 3600 .*Intel.* 3600.* 0 1 1 3 -Intel 830M .*Intel.*830M 0 0 0 0 -Intel 845G .*Intel.*845G 0 0 1 1.4 -Intel 855GM .*Intel.*855GM 0 0 1 1.4 -Intel 865G .*Intel.*865G 0 0 1 1.4 -Intel 900 .*Intel.*900.*900 0 0 0 0 -Intel 915GM .*Intel.*915GM 0 0 1 1.4 -Intel 915G .*Intel.*915G 0 0 1 1.4 -Intel 945GM .*Intel.*945GM.* 0 1 1 1.4 -Intel 945G .*Intel.*945G.* 0 1 1 1.4 -Intel 950 .*Intel.*950.* 0 1 1 1.4 -Intel 965 .*Intel.*965.* 0 1 1 2.1 -Intel G33 .*Intel.*G33.* 1 0 1 1.4 -Intel G41 .*Intel.*G41.* 1 1 1 2.1 -Intel G45 .*Intel.*G45.* 1 1 1 2.1 -Intel Bear Lake .*Intel.*Bear Lake.* 1 0 1 1.4 -Intel Broadwater .*Intel.*Broadwater.* 0 0 1 1.4 -Intel Brookdale .*Intel.*Brookdale.* 0 0 1 1.3 -Intel Cantiga .*Intel.*Cantiga.* 0 0 1 2 -Intel Eaglelake .*Intel.*Eaglelake.* 1 1 1 2 -Intel Graphics Media HD .*Intel.*Graphics Media.*HD.* 1 1 1 2.1 -Intel HD Graphics 2000 .*Intel.*HD Graphics 2.* 2 1 0 4 -Intel HD Graphics 3000 .*Intel.*HD Graphics 3.* 3 1 1 3.1 -Intel HD Graphics 4000 .*Intel.*HD Graphics 4.* 3 1 1 4 +Intel X3100 .*Intel.*X3100.* 1 1 1 2.1 +Intel GMA 3600 .*Intel.* 3600.* 0 1 1 3 +Intel 830M .*Intel.*830M 0 0 0 0 +Intel 845G .*Intel.*845G 0 0 1 1.4 +Intel 855GM .*Intel.*855GM 0 0 1 1.4 +Intel 865G .*Intel.*865G 0 0 1 1.4 +Intel 900 .*Intel.*900.*900 0 0 0 0 +Intel 915GM .*Intel.*915GM 0 0 1 1.4 +Intel 915G .*Intel.*915G 0 0 1 1.4 +Intel 945GM .*Intel.*945GM.* 0 1 1 1.4 +Intel 945G .*Intel.*945G.* 0 1 1 1.4 +Intel 950 .*Intel.*950.* 0 1 1 1.4 +Intel 965 .*Intel.*965.* 0 1 1 2.1 +Intel G33 .*Intel.*G33.* 1 0 1 1.4 +Intel G41 .*Intel.*G41.* 1 1 1 2.1 +Intel G45 .*Intel.*G45.* 1 1 1 2.1 +Intel Bear Lake .*Intel.*Bear Lake.* 1 0 1 1.4 +Intel Broadwater .*Intel.*Broadwater.* 0 0 1 1.4 +Intel Brookdale .*Intel.*Brookdale.* 0 0 1 1.3 +Intel Cantiga .*Intel.*Cantiga.* 0 0 1 2 +Intel Eaglelake .*Intel.*Eaglelake.* 1 1 1 2 +Intel Graphics Media HD .*Intel.*Graphics Media.*HD.* 1 1 1 2.1 +Intel HD Graphics 2000 .*Intel.*HD Graphics 2.* 2 1 0 4 +Intel HD Graphics 3000 .*Intel.*HD Graphics 3.* 3 1 1 3.1 +Intel HD Graphics 4000 .*Intel.*HD Graphics 4.* 3 1 1 4 Intel HD2000 .*Intel.*HD2000.* 2 1 0 0 Intel HD3000 .*Intel.*HD3000.* 3 1 0 0 -Intel HD Graphics .*Intel.*HD Graphics.* 2 1 1 4 -Intel Mobile 4 Series .*Intel.*Mobile.* 4 Series.* 0 1 1 2.1 -Intel 4 Series Internal .*Intel.* 4 Series Internal.* 1 1 1 2.1 -Intel Media Graphics HD .*Intel.*Media Graphics HD.* 0 1 0 0 -Intel Montara .*Intel.*Montara.* 0 0 1 1.3 -Intel Pineview .*Intel.*Pineview.* 0 1 1 1.4 -Intel Springdale .*Intel.*Springdale.* 0 0 1 1.3 -Intel Grantsdale .*Intel.*Grantsdale.* 1 1 0 0 -Intel Q45/Q43 .*Intel.*Q4.* 1 1 1 2.1 -Intel B45/B43 .*Intel.*B4.* 1 1 1 2.1 -Intel 3D-Analyze .*Intel.*3D-Analyze.* 2 1 0 0 -Matrox .*Matrox.* 0 0 0 0 +Intel HD Graphics .*Intel.*HD Graphics.* 2 1 1 4 +Intel Mobile 4 Series .*Intel.*Mobile.* 4 Series.* 0 1 1 2.1 +Intel 4 Series Internal .*Intel.* 4 Series Internal.* 1 1 1 2.1 +Intel Media Graphics HD .*Intel.*Media Graphics HD.* 0 1 0 0 +Intel Montara .*Intel.*Montara.* 0 0 1 1.3 +Intel Pineview .*Intel.*Pineview.* 0 1 1 1.4 +Intel Springdale .*Intel.*Springdale.* 0 0 1 1.3 +Intel Grantsdale .*Intel.*Grantsdale.* 1 1 0 0 +Intel Q45/Q43 .*Intel.*Q4.* 1 1 1 2.1 +Intel B45/B43 .*Intel.*B4.* 1 1 1 2.1 +Intel 3D-Analyze .*Intel.*3D-Analyze.* 2 1 0 0 +Matrox .*Matrox.* 0 0 0 0 Mesa .*Mesa.* 1 0 1 2.1 -Gallium .*Gallium.* 1 1 1 2.1 +Gallium .*Gallium.* 1 1 1 2.1 NVIDIA G100M .*NVIDIA .*100M.* 4 1 1 3.3 NVIDIA G102M .*NVIDIA .*102M.* 1 1 1 3.3 NVIDIA G103M .*NVIDIA .*103M.* 2 1 1 3.3 @@ -380,14 +380,14 @@ NVIDIA GTX 660M .*NVIDIA .*GTX *66*M.* 5 1 0 0 NVIDIA GTX 670M .*NVIDIA .*GTX *67*M.* 5 1 1 4.2 NVIDIA GTX 680M .*NVIDIA .*GTX *68*M.* 5 1 0 0 NVIDIA GTX 690M .*NVIDIA .*GTX *69*M.* 5 1 0 0 -NVIDIA G100 .*NVIDIA .*G10.* 3 1 1 4.2 +NVIDIA G100 .*NVIDIA .*G10.* 3 1 1 4.2 NVIDIA GT 120 .*NVIDIA .*GT *12.* 2 1 0 3 NVIDIA GT 130 .*NVIDIA .*GT *13.* 2 1 0 3.3 NVIDIA GTS 150 .*NVIDIA .*GTS *15.* 2 1 0 0 -NVIDIA 200 .*NVIDIA .*GeForce 20.* 2 1 1 3.3 -NVIDIA G200 .*NVIDIA .*GeForce G20.* 2 1 1 3.3 -NVIDIA G210 .*NVIDIA .*GeForce G210.* 3 1 1 3.3 -NVIDIA 210 .*NVIDIA .*GeForce 210.* 3 1 1 3.3 +NVIDIA 200 .*NVIDIA .*GeForce 20.* 2 1 1 3.3 +NVIDIA G200 .*NVIDIA .*GeForce G20.* 2 1 1 3.3 +NVIDIA G210 .*NVIDIA .*GeForce G210.* 3 1 1 3.3 +NVIDIA 210 .*NVIDIA .*GeForce 210.* 3 1 1 3.3 NVIDIA GT 220 .*NVIDIA .*GT *22.* 2 1 1 3.3 NVIDIA GT 230 .*NVIDIA .*GT *23.* 2 1 1 3.3 NVIDIA GT 240 .*NVIDIA .*GT *24.* 4 1 1 3.3 @@ -397,12 +397,12 @@ NVIDIA GTX 260 .*NVIDIA .*GTX *26.* 4 1 1 3.3 NVIDIA GTX 270 .*NVIDIA .*GTX *27.* 4 1 0 3.3 NVIDIA GTX 280 .*NVIDIA .*GTX *28.* 4 1 1 3.3 NVIDIA GTX 290 .*NVIDIA .*GTX *29.* 5 1 0 3.3 -NVIDIA 310 .*NVIDIA .*GeForce 310.* 3 1 1 3.3 -NVIDIA 315 .*NVIDIA .*GeForce 315.* 3 1 1 3.3 +NVIDIA 310 .*NVIDIA .*GeForce 310.* 3 1 1 3.3 +NVIDIA 315 .*NVIDIA .*GeForce 315.* 3 1 1 3.3 NVIDIA GT 320 .*NVIDIA .*GT *32.* 3 1 0 3.3 NVIDIA GT 330 .*NVIDIA .*GT *33.* 3 1 0 3.3 NVIDIA GT 340 .*NVIDIA .*GT *34.* 3 1 0 0 -NVIDIA 405 .*NVIDIA .* 405.* 3 1 0 3.3 +NVIDIA 405 .*NVIDIA .* 405.* 3 1 0 3.3 NVIDIA GT 420 .*NVIDIA .*GT *42.* 3 1 1 4.2 NVIDIA GT 430 .*NVIDIA .*GT *43.* 3 1 1 4.2 NVIDIA GT 440 .*NVIDIA .*GT *44.* 4 1 0 4.2 @@ -429,125 +429,125 @@ NVIDIA GTX 660 .*NVIDIA .*GTX *66.* 5 1 0 4.3 NVIDIA GTX 670 .*NVIDIA .*GTX *67.* 5 1 1 4.2 NVIDIA GTX 680 .*NVIDIA .*GTX *68.* 5 1 1 4.2 NVIDIA GTX 690 .*NVIDIA .*GTX *69.* 5 1 1 4.2 -NVIDIA C51 .*NVIDIA .*C51.* 0 1 1 2 -NVIDIA G72 .*NVIDIA .*G72.* 1 1 0 0 -NVIDIA G73 .*NVIDIA .*G73.* 1 1 0 0 -NVIDIA G84 .*NVIDIA .*G84.* 2 1 0 0 -NVIDIA G86 .*NVIDIA .*G86.* 3 1 0 0 -NVIDIA G92 .*NVIDIA .*G92.* 3 1 0 0 -NVIDIA GeForce .*GeForce 256.* 0 0 0 0 -NVIDIA GeForce 2 .*GeForce ?2 ?.* 0 1 1 1.5 +NVIDIA C51 .*NVIDIA .*C51.* 0 1 1 2 +NVIDIA G72 .*NVIDIA .*G72.* 1 1 0 0 +NVIDIA G73 .*NVIDIA .*G73.* 1 1 0 0 +NVIDIA G84 .*NVIDIA .*G84.* 2 1 0 0 +NVIDIA G86 .*NVIDIA .*G86.* 3 1 0 0 +NVIDIA G92 .*NVIDIA .*G92.* 3 1 0 0 +NVIDIA GeForce .*GeForce 256.* 0 0 0 0 +NVIDIA GeForce 2 .*GeForce ?2 ?.* 0 1 1 1.5 NVIDIA GeForce 3 .*GeForce ?3 ?.* 2 1 1 2.1 NVIDIA GeForce 3 Ti .*GeForce ?3 Ti.* 0 1 0 0 -NVIDIA GeForce 4 .*NVIDIA .*GeForce ?4.* 0 1 1 1.5 +NVIDIA GeForce 4 .*NVIDIA .*GeForce ?4.* 0 1 1 1.5 NVIDIA GeForce 4 Go .*NVIDIA .*GeForce ?4.*Go.* 0 1 0 0 NVIDIA GeForce 4 MX .*NVIDIA .*GeForce ?4 MX.* 0 1 0 0 NVIDIA GeForce 4 PCX .*NVIDIA .*GeForce ?4 PCX.* 0 1 0 0 NVIDIA GeForce 4 Ti .*NVIDIA .*GeForce ?4 Ti.* 0 1 0 0 -NVIDIA GeForce 6100 .*NVIDIA .*GeForce 61.* 3 1 1 4.2 -NVIDIA GeForce 6200 .*NVIDIA .*GeForce 62.* 0 1 1 2.1 -NVIDIA GeForce 6500 .*NVIDIA .*GeForce 65.* 1 1 1 2.1 -NVIDIA GeForce 6600 .*NVIDIA .*GeForce 66.* 2 1 1 2.1 -NVIDIA GeForce 6700 .*NVIDIA .*GeForce 67.* 2 1 1 2.1 -NVIDIA GeForce 6800 .*NVIDIA .*GeForce 68.* 1 1 1 2.1 -NVIDIA GeForce 7000 .*NVIDIA .*GeForce 70.* 1 1 1 2.1 -NVIDIA GeForce 7100 .*NVIDIA .*GeForce 71.* 1 1 1 2.1 -NVIDIA GeForce 7200 .*NVIDIA .*GeForce 72.* 1 1 0 0 -NVIDIA GeForce 7300 .*NVIDIA .*GeForce 73.* 1 1 1 2.1 -NVIDIA GeForce 7500 .*NVIDIA .*GeForce 75.* 2 1 1 2.1 -NVIDIA GeForce 7600 .*NVIDIA .*GeForce 76.* 2 1 1 2.1 -NVIDIA GeForce 7800 .*NVIDIA .*GeForce 78.* 2 1 1 2.1 -NVIDIA GeForce 7900 .*NVIDIA .*GeForce 79.* 3 1 1 2.1 +NVIDIA GeForce 6100 .*NVIDIA .*GeForce 61.* 3 1 1 4.2 +NVIDIA GeForce 6200 .*NVIDIA .*GeForce 62.* 0 1 1 2.1 +NVIDIA GeForce 6500 .*NVIDIA .*GeForce 65.* 1 1 1 2.1 +NVIDIA GeForce 6600 .*NVIDIA .*GeForce 66.* 2 1 1 2.1 +NVIDIA GeForce 6700 .*NVIDIA .*GeForce 67.* 2 1 1 2.1 +NVIDIA GeForce 6800 .*NVIDIA .*GeForce 68.* 1 1 1 2.1 +NVIDIA GeForce 7000 .*NVIDIA .*GeForce 70.* 1 1 1 2.1 +NVIDIA GeForce 7100 .*NVIDIA .*GeForce 71.* 1 1 1 2.1 +NVIDIA GeForce 7200 .*NVIDIA .*GeForce 72.* 1 1 0 0 +NVIDIA GeForce 7300 .*NVIDIA .*GeForce 73.* 1 1 1 2.1 +NVIDIA GeForce 7500 .*NVIDIA .*GeForce 75.* 2 1 1 2.1 +NVIDIA GeForce 7600 .*NVIDIA .*GeForce 76.* 2 1 1 2.1 +NVIDIA GeForce 7800 .*NVIDIA .*GeForce 78.* 2 1 1 2.1 +NVIDIA GeForce 7900 .*NVIDIA .*GeForce 79.* 3 1 1 2.1 NVIDIA GeForce 8100 .*NVIDIA .*GeForce 81.* 1 1 0 0 NVIDIA GeForce 8200M .*NVIDIA .*GeForce 8200M.* 1 1 0 3.3 NVIDIA GeForce 8200 .*NVIDIA .*GeForce 82.* 1 1 0 2.1 -NVIDIA GeForce 8300 .*NVIDIA .*GeForce 83.* 3 1 1 3.3 +NVIDIA GeForce 8300 .*NVIDIA .*GeForce 83.* 3 1 1 3.3 NVIDIA GeForce 8400M .*NVIDIA .*GeForce 8400M.* 1 1 1 3.3 -NVIDIA GeForce 8400 .*NVIDIA .*GeForce 84.* 2 1 1 3.3 -NVIDIA GeForce 8500 .*NVIDIA .*GeForce 85.* 2 1 1 3.3 +NVIDIA GeForce 8400 .*NVIDIA .*GeForce 84.* 2 1 1 3.3 +NVIDIA GeForce 8500 .*NVIDIA .*GeForce 85.* 2 1 1 3.3 NVIDIA GeForce 8600M .*NVIDIA .*GeForce 8600M.* 2 1 1 3.3 -NVIDIA GeForce 8600 .*NVIDIA .*GeForce 86.* 3 1 1 3.3 +NVIDIA GeForce 8600 .*NVIDIA .*GeForce 86.* 3 1 1 3.3 NVIDIA GeForce 8700M .*NVIDIA .*GeForce 8700M.* 2 1 1 3.3 -NVIDIA GeForce 8700 .*NVIDIA .*GeForce 87.* 3 1 0 0 +NVIDIA GeForce 8700 .*NVIDIA .*GeForce 87.* 3 1 0 0 NVIDIA GeForce 8800M .*NVIDIA .*GeForce 8800M.* 2 1 1 3.3 -NVIDIA GeForce 8800 .*NVIDIA .*GeForce 88.* 3 1 1 3.3 +NVIDIA GeForce 8800 .*NVIDIA .*GeForce 88.* 3 1 1 3.3 NVIDIA GeForce 9100M .*NVIDIA .*GeForce 9100M.* 0 1 0 0 -NVIDIA GeForce 9100 .*NVIDIA .*GeForce 91.* 0 1 0 3.3 +NVIDIA GeForce 9100 .*NVIDIA .*GeForce 91.* 0 1 0 3.3 NVIDIA GeForce 9200M .*NVIDIA .*GeForce 9200M.* 1 1 0 3.1 -NVIDIA GeForce 9200 .*NVIDIA .*GeForce 92.* 1 1 0 3.3 +NVIDIA GeForce 9200 .*NVIDIA .*GeForce 92.* 1 1 0 3.3 NVIDIA GeForce 9300M .*NVIDIA .*GeForce 9300M.* 1 1 1 3.3 -NVIDIA GeForce 9300 .*NVIDIA .*GeForce 93.* 1 1 1 3.3 +NVIDIA GeForce 9300 .*NVIDIA .*GeForce 93.* 1 1 1 3.3 NVIDIA GeForce 9400M .*NVIDIA .*GeForce 9400M.* 2 1 1 3.3 -NVIDIA GeForce 9400 .*NVIDIA .*GeForce 94.* 3 1 1 3.3 +NVIDIA GeForce 9400 .*NVIDIA .*GeForce 94.* 3 1 1 3.3 NVIDIA GeForce 9500M .*NVIDIA .*GeForce 9500M.* 1 1 1 3.3 -NVIDIA GeForce 9500 .*NVIDIA .*GeForce 95.* 3 1 1 3.3 +NVIDIA GeForce 9500 .*NVIDIA .*GeForce 95.* 3 1 1 3.3 NVIDIA GeForce 9600M .*NVIDIA .*GeForce 9600M.* 2 1 1 3.3 -NVIDIA GeForce 9600 .*NVIDIA .*GeForce 96.* 3 1 1 3.3 +NVIDIA GeForce 9600 .*NVIDIA .*GeForce 96.* 3 1 1 3.3 NVIDIA GeForce 9700M .*NVIDIA .*GeForce 9700M.* 0 1 1 3.3 NVIDIA GeForce 9800M .*NVIDIA .*GeForce 9800M.* 2 1 1 3.3 -NVIDIA GeForce 9800 .*NVIDIA .*GeForce 98.* 3 1 1 3.3 -NVIDIA GeForce FX 5100 .*NVIDIA .*GeForce FX 51.* 0 1 0 0 -NVIDIA GeForce FX 5200 .*NVIDIA .*GeForce FX 52.* 0 1 0 2.1 -NVIDIA GeForce FX 5300 .*NVIDIA .*GeForce FX 53.* 0 1 0 0 -NVIDIA GeForce FX 5500 .*NVIDIA .*GeForce FX 55.* 0 1 1 2.1 -NVIDIA GeForce FX 5600 .*NVIDIA .*GeForce FX 56.* 1 1 1 2.1 -NVIDIA GeForce FX 5700 .*NVIDIA .*GeForce FX 57.* 0 1 1 2.1 -NVIDIA GeForce FX 5800 .*NVIDIA .*GeForce FX 58.* 1 1 0 0 -NVIDIA GeForce FX 5900 .*NVIDIA .*GeForce FX 59.* 1 1 1 2.1 -NVIDIA GeForce FX Go5100 .*NVIDIA .*GeForce FX Go51.* 0 1 0 0 +NVIDIA GeForce 9800 .*NVIDIA .*GeForce 98.* 3 1 1 3.3 +NVIDIA GeForce FX 5100 .*NVIDIA .*GeForce FX 51.* 0 1 0 0 +NVIDIA GeForce FX 5200 .*NVIDIA .*GeForce FX 52.* 0 1 0 2.1 +NVIDIA GeForce FX 5300 .*NVIDIA .*GeForce FX 53.* 0 1 0 0 +NVIDIA GeForce FX 5500 .*NVIDIA .*GeForce FX 55.* 0 1 1 2.1 +NVIDIA GeForce FX 5600 .*NVIDIA .*GeForce FX 56.* 1 1 1 2.1 +NVIDIA GeForce FX 5700 .*NVIDIA .*GeForce FX 57.* 0 1 1 2.1 +NVIDIA GeForce FX 5800 .*NVIDIA .*GeForce FX 58.* 1 1 0 0 +NVIDIA GeForce FX 5900 .*NVIDIA .*GeForce FX 59.* 1 1 1 2.1 +NVIDIA GeForce FX Go5100 .*NVIDIA .*GeForce FX Go51.* 0 1 0 0 NVIDIA GeForce FX Go5200 .*NVIDIA .*GeForce FX Go52.* 0 1 0 0 -NVIDIA GeForce FX Go5300 .*NVIDIA .*GeForce FX Go53.* 0 1 0 0 -NVIDIA GeForce FX Go5500 .*NVIDIA .*GeForce FX Go55.* 0 1 0 0 -NVIDIA GeForce FX Go5600 .*NVIDIA .*GeForce FX Go56.* 0 1 1 2.1 -NVIDIA GeForce FX Go5700 .*NVIDIA .*GeForce FX Go57.* 1 1 1 1.5 -NVIDIA GeForce FX Go5800 .*NVIDIA .*GeForce FX Go58.* 1 1 0 0 -NVIDIA GeForce FX Go5900 .*NVIDIA .*GeForce FX Go59.* 1 1 0 0 -NVIDIA GeForce FX Go5xxx .*NVIDIA .*GeForce FX Go.* 0 1 0 0 -NVIDIA GeForce Go 6100 .*NVIDIA .*GeForce Go 61.* 0 1 1 2.1 +NVIDIA GeForce FX Go5300 .*NVIDIA .*GeForce FX Go53.* 0 1 0 0 +NVIDIA GeForce FX Go5500 .*NVIDIA .*GeForce FX Go55.* 0 1 0 0 +NVIDIA GeForce FX Go5600 .*NVIDIA .*GeForce FX Go56.* 0 1 1 2.1 +NVIDIA GeForce FX Go5700 .*NVIDIA .*GeForce FX Go57.* 1 1 1 1.5 +NVIDIA GeForce FX Go5800 .*NVIDIA .*GeForce FX Go58.* 1 1 0 0 +NVIDIA GeForce FX Go5900 .*NVIDIA .*GeForce FX Go59.* 1 1 0 0 +NVIDIA GeForce FX Go5xxx .*NVIDIA .*GeForce FX Go.* 0 1 0 0 +NVIDIA GeForce Go 6100 .*NVIDIA .*GeForce Go 61.* 0 1 1 2.1 NVIDIA GeForce Go 6200 .*NVIDIA .*GeForce Go 62.* 0 1 0 0 NVIDIA GeForce Go 6400 .*NVIDIA .*GeForce Go 64.* 1 1 1 2 -NVIDIA GeForce Go 6500 .*NVIDIA .*GeForce Go 65.* 1 1 0 0 -NVIDIA GeForce Go 6600 .*NVIDIA .*GeForce Go 66.* 0 1 1 2.1 -NVIDIA GeForce Go 6700 .*NVIDIA .*GeForce Go 67.* 1 1 0 0 -NVIDIA GeForce Go 6800 .*NVIDIA .*GeForce Go 68.* 0 1 1 2.1 +NVIDIA GeForce Go 6500 .*NVIDIA .*GeForce Go 65.* 1 1 0 0 +NVIDIA GeForce Go 6600 .*NVIDIA .*GeForce Go 66.* 0 1 1 2.1 +NVIDIA GeForce Go 6700 .*NVIDIA .*GeForce Go 67.* 1 1 0 0 +NVIDIA GeForce Go 6800 .*NVIDIA .*GeForce Go 68.* 0 1 1 2.1 NVIDIA GeForce Go 7200 .*NVIDIA .*GeForce Go 72.* 1 1 0 0 -NVIDIA GeForce Go 7300 LE .*NVIDIA .*GeForce Go 73.*LE.* 1 1 0 0 -NVIDIA GeForce Go 7300 .*NVIDIA .*GeForce Go 73.* 1 1 1 2.1 -NVIDIA GeForce Go 7400 .*NVIDIA .*GeForce Go 74.* 1 1 1 2.1 -NVIDIA GeForce Go 7600 .*NVIDIA .*GeForce Go 76.* 1 1 1 2.1 -NVIDIA GeForce Go 7700 .*NVIDIA .*GeForce Go 77.* 0 1 1 2.1 -NVIDIA GeForce Go 7800 .*NVIDIA .*GeForce Go 78.* 2 1 0 0 -NVIDIA GeForce Go 7900 .*NVIDIA .*GeForce Go 79.* 1 1 1 2.1 -NVIDIA D9M .*NVIDIA .*D9M.* 1 1 0 0 -NVIDIA G94 .*NVIDIA .*G94.* 3 1 0 0 -NVIDIA GeForce Go 6 .*GeForce Go 6.* 1 1 0 0 -NVIDIA ION 2 .*NVIDIA .*ION 2.* 2 1 0 0 -NVIDIA ION .*NVIDIA Corporation.*ION.* 2 1 1 3.3 -NVIDIA NB8M .*NVIDIA .*NB8M.* 1 1 0 0 -NVIDIA NB8P .*NVIDIA .*NB8P.* 2 1 0 0 -NVIDIA NB9E .*NVIDIA .*NB9E.* 3 1 0 0 -NVIDIA NB9M .*NVIDIA .*NB9M.* 1 1 0 0 -NVIDIA NB9P .*NVIDIA .*NB9P.* 2 1 0 0 +NVIDIA GeForce Go 7300 LE .*NVIDIA .*GeForce Go 73.*LE.* 1 1 0 0 +NVIDIA GeForce Go 7300 .*NVIDIA .*GeForce Go 73.* 1 1 1 2.1 +NVIDIA GeForce Go 7400 .*NVIDIA .*GeForce Go 74.* 1 1 1 2.1 +NVIDIA GeForce Go 7600 .*NVIDIA .*GeForce Go 76.* 1 1 1 2.1 +NVIDIA GeForce Go 7700 .*NVIDIA .*GeForce Go 77.* 0 1 1 2.1 +NVIDIA GeForce Go 7800 .*NVIDIA .*GeForce Go 78.* 2 1 0 0 +NVIDIA GeForce Go 7900 .*NVIDIA .*GeForce Go 79.* 1 1 1 2.1 +NVIDIA D9M .*NVIDIA .*D9M.* 1 1 0 0 +NVIDIA G94 .*NVIDIA .*G94.* 3 1 0 0 +NVIDIA GeForce Go 6 .*GeForce Go 6.* 1 1 0 0 +NVIDIA ION 2 .*NVIDIA .*ION 2.* 2 1 0 0 +NVIDIA ION .*NVIDIA Corporation.*ION.* 2 1 1 3.3 +NVIDIA NB8M .*NVIDIA .*NB8M.* 1 1 0 0 +NVIDIA NB8P .*NVIDIA .*NB8P.* 2 1 0 0 +NVIDIA NB9E .*NVIDIA .*NB9E.* 3 1 0 0 +NVIDIA NB9M .*NVIDIA .*NB9M.* 1 1 0 0 +NVIDIA NB9P .*NVIDIA .*NB9P.* 2 1 0 0 NVIDIA N10 .*NVIDIA .*N10.* 1 1 0 0 NVIDIA GeForce PCX .*GeForce PCX.* 0 1 0 0 NVIDIA Generic .*NVIDIA .*Unknown.* 0 0 0 3 -NVIDIA NV17 .*NVIDIA .*NV17.* 0 1 0 0 -NVIDIA NV34 .*NVIDIA .*NV34.* 0 1 0 0 -NVIDIA NV35 .*NVIDIA .*NV35.* 0 1 0 0 -NVIDIA NV36 .*NVIDIA .*NV36.* 1 1 0 0 -NVIDIA NV41 .*NVIDIA .*NV41.* 1 1 0 0 -NVIDIA NV43 .*NVIDIA .*NV43.* 1 1 0 0 -NVIDIA NV44 .*NVIDIA .*NV44.* 1 1 0 0 -NVIDIA nForce .*NVIDIA .*nForce.* 0 0 0 3.3 -NVIDIA MCP51 .*NVIDIA .*MCP51.* 1 1 0 0 +NVIDIA NV17 .*NVIDIA .*NV17.* 0 1 0 0 +NVIDIA NV34 .*NVIDIA .*NV34.* 0 1 0 0 +NVIDIA NV35 .*NVIDIA .*NV35.* 0 1 0 0 +NVIDIA NV36 .*NVIDIA .*NV36.* 1 1 0 0 +NVIDIA NV41 .*NVIDIA .*NV41.* 1 1 0 0 +NVIDIA NV43 .*NVIDIA .*NV43.* 1 1 0 0 +NVIDIA NV44 .*NVIDIA .*NV44.* 1 1 0 0 +NVIDIA nForce .*NVIDIA .*nForce.* 0 0 0 3.3 +NVIDIA MCP51 .*NVIDIA .*MCP51.* 1 1 0 0 NVIDIA MCP61 .*NVIDIA .*MCP61.* 1 1 0 0 -NVIDIA MCP67 .*NVIDIA .*MCP67.* 1 1 0 0 -NVIDIA MCP68 .*NVIDIA .*MCP68.* 1 1 0 0 -NVIDIA MCP73 .*NVIDIA .*MCP73.* 1 1 0 0 -NVIDIA MCP77 .*NVIDIA .*MCP77.* 1 1 0 0 -NVIDIA MCP78 .*NVIDIA .*MCP78.* 1 1 0 0 -NVIDIA MCP79 .*NVIDIA .*MCP79.* 1 1 0 0 -NVIDIA MCP7A .*NVIDIA .*MCP7A.* 1 1 0 0 +NVIDIA MCP67 .*NVIDIA .*MCP67.* 1 1 0 0 +NVIDIA MCP68 .*NVIDIA .*MCP68.* 1 1 0 0 +NVIDIA MCP73 .*NVIDIA .*MCP73.* 1 1 0 0 +NVIDIA MCP77 .*NVIDIA .*MCP77.* 1 1 0 0 +NVIDIA MCP78 .*NVIDIA .*MCP78.* 1 1 0 0 +NVIDIA MCP79 .*NVIDIA .*MCP79.* 1 1 0 0 +NVIDIA MCP7A .*NVIDIA .*MCP7A.* 1 1 0 0 NVIDIA Quadro2 .*Quadro2.* 0 1 0 0 NVIDIA Quadro 1000M .*Quadro.*1000M.* 2 1 0 4.2 NVIDIA Quadro 2000 M/D .*Quadro.*2000.* 3 1 0 4.2 @@ -555,12 +555,12 @@ NVIDIA Quadro 3000M .*Quadro.*3000M.* 3 1 0 0 NVIDIA Quadro 4000M .*Quadro.*4000M.* 3 1 0 0 NVIDIA Quadro 4000 .*Quadro *4000.* 3 1 0 4.2 NVIDIA Quadro 50x0 M .*Quadro.*50.0.* 3 1 0 0 -NVIDIA Quadro 6000 .*Quadro.*6000.* 3 1 0 0 -NVIDIA Quadro 400 .*Quadro.*400.* 2 1 0 3.3 +NVIDIA Quadro 6000 .*Quadro.* 6000.* 3 1 0 0 +NVIDIA Quadro 400 .*Quadro.* 400.* 2 1 0 3.3 NVIDIA Quadro 600 .*Quadro.*600.* 2 1 0 3.3 NVIDIA Quadro4 .*Quadro4.* 0 1 0 0 -NVIDIA Quadro DCC .*Quadro DCC.* 0 1 0 0 -NVIDIA Quadro CX .*Quadro.*CX.* 3 1 0 0 +NVIDIA Quadro DCC .*Quadro DCC.* 0 1 0 0 +NVIDIA Quadro CX .*Quadro.*CX.* 3 1 0 0 NVIDIA Quadro FX 770M .*Quadro.*FX *770M.* 2 1 0 0 NVIDIA Quadro FX 1500M .*Quadro.*FX *1500M.* 1 1 0 2.1 NVIDIA Quadro FX 1600M .*Quadro.*FX *1600M.* 2 1 0 0 @@ -574,7 +574,7 @@ NVIDIA Quadro FX 3800 .*Quadro.*FX *3800.* 3 1 0 3.2 NVIDIA Quadro FX 4500 .*Quadro.*FX *45.* 3 1 0 0 NVIDIA Quadro FX 880M .*Quadro.*FX *880M.* 3 1 0 3.3 NVIDIA Quadro FX 4800 .*NVIDIA .*Quadro *FX *4800.* 3 1 0 0 -NVIDIA Quadro FX .*Quadro FX.* 1 1 0 3.3 +NVIDIA Quadro FX .*Quadro FX.* 1 1 0 3.3 NVIDIA Quadro NVS 1xxM .*Quadro NVS *1.[05]M.* 0 1 1 3.3 NVIDIA Quadro NVS 300M .*NVIDIA .*NVS *300M.* 2 1 0 0 NVIDIA Quadro NVS 320M .*NVIDIA .*NVS *320M.* 2 1 0 0 @@ -583,16 +583,16 @@ NVIDIA Quadro NVS 3100M .*NVIDIA .*NVS *3100M.* 2 1 0 0 NVIDIA Quadro NVS 4200M .*NVIDIA .*NVS *4200M.* 2 1 0 4.1 NVIDIA Quadro NVS 5100M .*NVIDIA .*NVS *5100M.* 2 1 0 0 NVIDIA Quadro NVS .*NVIDIA .*NVS 0 1 0 3.2 -NVIDIA Corporation N12P .*NVIDIA .*N12P.* 1 1 1 4.1 +NVIDIA Corporation N12P .*NVIDIA .*N12P.* 1 1 1 4.1 NVIDIA Corporation N11M .*NVIDIA .*N11M.* 2 1 0 0 NVIDIA RIVA TNT .*RIVA TNT.* 0 0 0 0 -S3 .*S3 Graphics.* 0 0 1 1.4 -SiS SiS.* 0 0 1 1.5 -Trident Trident.* 0 0 0 0 -Tungsten Graphics Tungsten.* 0 0 0 0 -XGI XGI.* 0 0 0 0 -VIA VIA.* 0 0 0 0 -Apple Generic Apple.*Generic.* 0 0 0 0 -Apple Software Renderer Apple.*Software Renderer.* 0 0 0 0 -Humper Humper.* 0 1 1 2.1 -PowerVR SGX545 .*PowerVR SGX.* 1 1 1 3 +S3 .*S3 Graphics.* 0 0 1 1.4 +SiS SiS.* 0 0 1 1.5 +Trident Trident.* 0 0 0 0 +Tungsten Graphics Tungsten.* 0 0 0 0 +XGI XGI.* 0 0 0 0 +VIA VIA.* 0 0 0 0 +Apple Generic Apple.*Generic.* 0 0 0 0 +Apple Software Renderer Apple.*Software Renderer.* 0 0 0 0 +Humper Humper.* 0 1 1 2.1 +PowerVR SGX545 .*PowerVR SGX.* 1 1 1 3 diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index c88694ef76..c88694ef76 100755..100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 7f56d7afdd..b2a57b5602 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1800,6 +1800,8 @@ bool LLAppViewer::cleanup() LLAvatarAppearance::cleanupClass(); + LLAvatarAppearance::cleanupClass(); + LLPostProcess::cleanupClass(); LLTracker::cleanupInstance(); @@ -3763,6 +3765,12 @@ void LLAppViewer::requestQuit() gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent. } + // Try to send last batch of avatar rez metrics. + if (!gDisconnected && isAgentAvatarValid()) + { + gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent. + } + LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE); effectp->setPositionGlobal(gAgent.getPositionGlobal()); effectp->setColor(LLColor4U(gAgent.getEffectColor())); diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index bb1d263670..8c9fd4152a 100755 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -308,6 +308,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()) @@ -441,7 +484,7 @@ void LLDrawable::makeActive() } llassert(isAvatar() || isRoot() || mParent->isActive()); - } +} void LLDrawable::makeStatic(BOOL warning_enabled) diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 4608d16fec..289abd3335 100755 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -145,6 +145,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..fc5571aa58 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" @@ -98,6 +99,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; diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index ab9bb9e611..93656c34e4 100755 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -50,6 +50,7 @@ public: POOL_GROUND, POOL_FULLBRIGHT, POOL_BUMP, + POOL_MATERIALS, POOL_TERRAIN, POOL_SKY, POOL_WL_SKY, @@ -133,6 +134,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, diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 313b310e1e..d5de5d30b0 100755 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -91,12 +91,31 @@ 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); + pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); gDeferredDiffuseAlphaMaskProgram.unbind(); } +void LLDrawPoolAlpha::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); + } + } +} + S32 LLDrawPoolAlpha::getNumPostDeferredPasses() { @@ -133,8 +152,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 +168,6 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass) void LLDrawPoolAlpha::endPostDeferredPass(S32 pass) { - if (pass == 1) { gPipeline.mDeferredDepth.flush(); @@ -234,23 +251,33 @@ void LLDrawPoolAlpha::render(S32 pass) simple_shader->bind(); simple_shader->setMinimumAlpha(0.33f); - pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + 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); } if (fullbright_shader) { fullbright_shader->bind(); fullbright_shader->setMinimumAlpha(0.33f); + if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred) + { + fullbright_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); + } else { + fullbright_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); + } } - pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushMaskBatches(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()); + pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE); gPipeline.enableLightsDynamic(); - pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask()); + pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE); gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK } } @@ -302,7 +329,7 @@ void LLDrawPoolAlpha::render(S32 pass) if (mVertexShaderLevel > 0) { - renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX); + renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2); } else { @@ -412,8 +439,14 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) } LLRenderPass::applyModelMatrix(params); - + LLMaterial* mat = NULL; + + if (deferred_render && !LLPipeline::sUnderWaterRender) + { + mat = params.mMaterial; + } + if (params.mFullbright) { // Turn off lighting if it hasn't already been so. @@ -446,11 +479,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 (!params.mFullbright && 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(); } @@ -459,6 +511,44 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) LLGLSLShader::bindNoShader(); current_shader = NULL; } + + if (use_shaders && mat && !params.mFullbright) + { + // I apologize in advance for not giving this its own shader. + // 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); + + if (params.mNormalMap) + { + params.mNormalMap->addTextureStats(params.mVSize); + current_shader->bindTexture(LLShaderMgr::BUMP_MAP, params.mNormalMap); + } else { + LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(params.mVSize); + current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); + } + + if (params.mSpecularMap) + { + params.mSpecularMap->addTextureStats(params.mVSize); + current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap); + } else { + LLViewerFetchedTexture::sWhiteImagep->addTextureStats(params.mVSize); + current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); + } + } + + } 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) { @@ -477,12 +567,20 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) } } } - else + else { //not batching textures or batch has only 1 texture -- might need a texture matrix if (params.mTexture.notNull()) { params.mTexture->addTextureStats(params.mVSize); - gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ; + if (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..46c17f3b99 100755 --- a/indra/newview/lldrawpoolalpha.h +++ b/indra/newview/lldrawpoolalpha.h @@ -70,6 +70,8 @@ public: void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE); void renderAlpha(U32 mask); void renderAlphaHighlight(U32 mask); + void pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures); + static BOOL sShowDebugAlpha; diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 294cecc703..69f10cd4df 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -183,6 +183,9 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass) case 4: beginDeferredRiggedBump(); break; + default: + beginDeferredRiggedMaterial(pass-5); + break; } } @@ -215,6 +218,9 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass) case 4: endDeferredRiggedBump(); break; + default: + endDeferredRiggedMaterial(pass-5); + break; } } @@ -225,7 +231,7 @@ void LLDrawPoolAvatar::renderDeferred(S32 pass) S32 LLDrawPoolAvatar::getNumPostDeferredPasses() { - return 6; + return 10; } void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass) @@ -247,9 +253,12 @@ void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass) case 4: beginRiggedFullbrightAlpha(); break; - case 5: + case 9: beginRiggedGlow(); break; + default: + beginDeferredRiggedMaterialAlpha(pass-5); + break; } } @@ -275,11 +284,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 +337,9 @@ void LLDrawPoolAvatar::endPostDeferredPass(S32 pass) case 5: endRiggedGlow(); break; + default: + endDeferredRiggedAlpha(); + break; } } @@ -328,17 +363,21 @@ 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); + render(p); } @@ -425,12 +464,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 +492,7 @@ S32 LLDrawPoolAvatar::getNumDeferredPasses() } else { - return 5; + return 21; } } @@ -1010,6 +1047,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; @@ -1185,6 +1258,23 @@ 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); @@ -1197,7 +1287,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) return; } - if (pass >= 7 && pass < 9) + if (pass >= 7 && pass < 13) { if (pass == 7) { @@ -1210,9 +1300,32 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) renderRiggedFullbrightAlpha(avatarp); return; } + + if (LLPipeline::sRenderDeferred) + { + 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; + } + + { + LLGLEnable blend(GL_BLEND); + renderDeferredRiggedMaterial(avatarp, p); + } + return; + } + else if (pass == 9) + { + renderRiggedGlow(avatarp); + return; + } } - if (pass == 9) + if (pass == 13) { renderRiggedGlow(avatarp); @@ -1510,10 +1623,41 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) gGL.diffuseColor4f(0,0,0,face->getTextureEntry()->getGlow()); }*/ - gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture()); - if (normal_channel > -1) + LLMaterial* mat = face->getTextureEntry()->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)); + + LLColor4U col = mat->getSpecularLightColor(); + U8 spec = mat->getSpecularLightExponent(); + + U8 env = mat->getEnvironmentIntensity(); + + sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0]/255.f, col.mV[1]/255.f, col.mV[2]/255.f, spec/255.f); + + sVertexProgram->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env/255.f); + + sVertexProgram->setMinimumAlpha(mat->getAlphaMaskCutoff()/255.f); + + for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) + { + LLViewerTexture* tex = face->getTexture(i); + if (tex) + { + tex->addTextureStats(avatar->getPixelArea()); + } + } + } + else { - LLDrawPoolBump::bindBumpMap(face, normal_channel); + gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture()); + if (normal_channel > -1) + { + LLDrawPoolBump::bindBumpMap(face, normal_channel); + } } if (face->mTextureMatrix) @@ -1545,6 +1689,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..bb9126c162 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_BINORMAL | + 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_BINORMAL | + 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 | diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index e8d43c8631..cb40cf2039 100755 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -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) diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp new file mode 100644 index 0000000000..3e0f9c9d4d --- /dev/null +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -0,0 +1,216 @@ +/** + * @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); + + 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..cfbd13f335 --- /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_BINORMAL + }; + + /*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..1a6293c010 100755 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -198,7 +198,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 @@ -405,12 +409,20 @@ void LLDrawPoolFullbright::render(S32 pass) fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f); U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE); + 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(); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 281f852b0a..ef8c4ff543 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 @@ -167,8 +167,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 +189,6 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp) mImportanceToCamera = 0.f ; mBoundingSphereRadius = 0.0f ; - mAtlasInfop = NULL ; - mUsingAtlas = FALSE ; mHasMedia = FALSE ; } @@ -197,9 +199,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,8 +244,7 @@ void LLFace::destroy() } setDrawInfo(NULL); - removeAtlas(); - + mDrawablep = NULL; mVObjp = NULL; } @@ -293,48 +297,76 @@ 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) - { //dirty texture on an alpha object should be treated as an LoD update - LLVOVolume* vobj = drawablep->getVOVolume(); - if (vobj) + if (mVObjp.notNull() && mVObjp->getVolume()) + { + for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) { - vobj->mLODChanged = TRUE; + 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) + { + vobj->mLODChanged = TRUE; + } + gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE); + } } - 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 +376,17 @@ void LLFace::switchTexture(LLViewerTexture* new_texture) llerrs << "Can not switch to a null texture." << llendl; return; } - new_texture->addTextureStats(mTexture->getMaxVirtualSize()) ; - getViewerObject()->changeTEImage(mTEOffset, new_texture) ; - setTexture(new_texture) ; + llassert(mTexture[ch].notNull()); + + new_texture->addTextureStats(mTexture[ch]->getMaxVirtualSize()) ; + + if (ch == LLRender::DIFFUSE_MAP) + { + getViewerObject()->changeTEImage(mTEOffset, new_texture) ; + } + + setTexture(ch, new_texture) ; dirtyTexture(); } @@ -1058,6 +1097,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 @@ -1219,7 +1264,8 @@ 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; @@ -1251,27 +1297,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, 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; @@ -1292,6 +1317,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { if (tep) { + LLMaterial* mat = tep->getMaterialParams().get(); + GLfloat alpha[4] = { 0.00f, @@ -1300,11 +1327,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, 0.75f }; - if (getPoolType() != LLDrawPool::POOL_ALPHA && (LLPipeline::sRenderDeferred || (LLPipeline::sRenderBump && tep->getShiny()))) + if ((!LLPipeline::sRenderDeferred || !mat || mat->getSpecularID().isNull()) && + getPoolType() != LLDrawPool::POOL_ALPHA && + (LLPipeline::sRenderDeferred || (LLPipeline::sRenderBump && tep->getShiny()))) { + llassert(tep->getShiny() <= 3); color.mV[3] = U8 (alpha[tep->getShiny()] * 255); } } + } // INDICES @@ -1556,11 +1587,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; @@ -1601,11 +1632,18 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, U8 tex_mode = 0; + 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)) { - LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp; - tex_mode = vobj->mTexAnimMode; - if (!tex_mode) { clearState(TEXTURE_ANIM); @@ -1620,7 +1658,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, do_xform = false; } - + if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) { //don't override texture transform during tc bake tex_mode = 0; @@ -1630,12 +1668,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); - 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 (mat && !do_bump) + { + do_bump = mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1) || + mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2); + } + + bool do_tex_mat = tex_mode && mTextureMatrix; + + 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 +1693,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 +1733,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 +1744,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 +1767,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 +1783,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, xform(tc, cos_ang, sin_ang, os, ot, ms, mt); - *tex_coords++ = tc; + *tex_coords0++ = tc; } } } @@ -1747,145 +1794,114 @@ 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; - - for (S32 i = 0; i < num_vertices; i++) - { - LLVector2 tc(vf.mTexCoords[i]); - - LLVector4a& norm = vf.mNormals[i]; - LLVector4a& center = *(vf.mCenter); - - if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) - { - LLVector4a vec = vf.mPositions[i]; - - vec.mul(scalea); + std::vector<LLVector2> bump_tc; - switch (texgen) - { - 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; - } - } + if (mat) + { //writing out normal and specular texture coordinates, not bump offsets + do_bump = false; + } - if (tex_mode && mTextureMatrix) - { - LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); - tmp = tmp * *mTextureMatrix; - tc.mV[0] = tmp.mV[0]; - tc.mV[1] = tmp.mV[1]; - } - else - { - xform(tc, cos_ang, sin_ang, os, ot, ms, mt); - } + LLStrider<LLVector2> dst; - if(in_atlas) + for (U32 ch = 0; ch < 3; ++ch) + { + switch (ch) { - // - //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; - } + case 0: + mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount, map_range); 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 + case 1: + if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)) { - tc.mV[0] = int_part + 1 - tc.mV[0] ; - } - else //even number - { - tc.mV[0] -= int_part ; - } + mVertexBuffer->getTexCoord1Strider(dst, mGeomIndex, mGeomCount, map_range); + if (mat && !tex_anim) + { + r = mat->getNormalRotation(); + mat->getNormalOffset(os, ot); + mat->getNormalRepeat(ms, mt); - 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] ; + cos_ang = cos(r); + sin_ang = sin(r); + + } } - else //even number + else { - tc.mV[1] -= int_part ; + continue; } 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) + case 2: + if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2)) { - tc.mV[0] = 1.0f + tc.mV[0] ; + 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); + } } - if(tc.mV[1] < 0.f) + else { - tc.mV[1] = 1.0f + tc.mV[1] ; + continue; } break; - default: - break; - } - - tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ; - tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ; } + + + for (S32 i = 0; i < num_vertices; i++) + { + LLVector2 tc(vf.mTexCoords[i]); + + LLVector4a& norm = vf.mNormals[i]; + + LLVector4a& center = *(vf.mCenter); + + if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) + { + LLVector4a vec = vf.mPositions[i]; + vec.mul(scalea); - *tex_coords++ = tc; - if (do_bump) - { - bump_tc.push_back(tc); + switch (texgen) + { + 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; + } + } + + if (tex_mode && mTextureMatrix) + { + LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); + tmp = tmp * *mTextureMatrix; + tc.mV[0] = tmp.mV[0]; + tc.mV[1] = tmp.mV[1]; + } + else + { + xform(tc, cos_ang, sin_ang, os, ot, ms, mt); + } + + *dst++ = tc; + if (do_bump) + { + bump_tc.push_back(tc); + } } } @@ -1894,9 +1910,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, 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++) { @@ -1923,7 +1939,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, 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) @@ -2027,9 +2043,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLFastTimer t(FTM_FACE_GEOM_BINORMAL); mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range); F32* binormals = (F32*) binorm.get(); - + + mVObjp->getVolume()->genBinormals(f); + for (S32 i = 0; i < num_vertices; i++) - { + { LLVector4a binormal; mat_normal.rotate(vf.mBinormals[i], binormal); binormal.normalize3fast(); @@ -2153,9 +2171,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 +2225,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 ); } @@ -2574,159 +2592,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 -{ - if(isAtlasInUse()) - { - return mAtlasInfop->getTexCoordOffset() ; - } - return NULL ; -} -const LLVector2* LLFace::getTexCoordScale() const -{ - if(isAtlasInUse()) - { - return mAtlasInfop->getTexCoordScale() ; - } - return NULL ; -} - -BOOL LLFace::isAtlasInUse()const -{ - return mUsingAtlas ; -} - -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) +LLViewerTexture* LLFace::getTexture(U32 ch) const { - //no valid atlas to use. - if(flag && (!mAtlasInfop || !mAtlasInfop->isValid())) - { - flag = FALSE ; - } + llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); - 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 ; - } + return mTexture[ch] ; } -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; @@ -2742,6 +2614,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 de4d03351c..453d2c23d4 100755 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -41,7 +41,6 @@ #include "llvertexbuffer.h" #include "llviewertexture.h" #include "lldrawable.h" -#include "lltextureatlasmanager.h" class LLFacePool; class LLVolume; @@ -50,7 +49,6 @@ class LLTextureEntry; class LLVertexProgram; class LLViewerTexture; class LLGeometryManager; -class LLTextureAtlasSlot; const F32 MIN_ALPHA_SIZE = 1024.f; const F32 MIN_TEX_ANIM_SIZE = 512.f; @@ -110,8 +108,12 @@ 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; } @@ -130,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; @@ -149,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); @@ -223,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 @@ -266,6 +258,8 @@ public: F32 mLastSkinTime; F32 mLastMoveTime; LLMatrix4* mTextureMatrix; + LLMatrix4* mSpecMapMatrix; + LLMatrix4* mNormalMapMatrix; LLDrawInfo* mDrawInfo; private: @@ -281,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; @@ -302,9 +298,6 @@ private: F32 mBoundingSphereRadius ; bool mHasMedia ; - //atlas - LLPointer<LLTextureAtlasSlot> mAtlasInfop ; - BOOL mUsingAtlas ; protected: static BOOL sSafeRenderSelect; 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/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 25df4889b0..1f2b9904eb 100755 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -372,10 +372,12 @@ std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id) std::vector<LLViewerObject*> obj_list; LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id); - for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(); face_iterator++) + U32 ch = LLRender::DIFFUSE_MAP; + + for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(ch); face_iterator++) { // getting an object from a face - LLFace* face_to_object = (*old_texture->getFaceList())[face_iterator]; + LLFace* face_to_object = (*old_texture->getFaceList(ch))[face_iterator]; if(face_to_object) { diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp new file mode 100644 index 0000000000..fb8cffa4ef --- /dev/null +++ b/indra/newview/llmaterialmgr.cpp @@ -0,0 +1,719 @@ +/** + * @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() +{ + 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; +} + +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; + } + + mGetPending.erase(pending_material_t(region_id, material_id)); + + 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); + } + + 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..39be5cab29 --- /dev/null +++ b/indra/newview/llmaterialmgr.h @@ -0,0 +1,96 @@ +/** + * @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 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; + + 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/llpanelface.cpp b/indra/newview/llpanelface.cpp index 445c0d811f..9c40ff06cc 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,27 @@ #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; + +// // Methods // @@ -73,21 +97,38 @@ 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::onCommitMaterial, this); + childSetCommitCallback("bumpyScaleV",&LLPanelFace::onCommitMaterial, this); + childSetCommitCallback("bumpyRot",&LLPanelFace::onCommitMaterial, this); + childSetCommitCallback("bumpyOffsetU",&LLPanelFace::onCommitMaterial, this); + childSetCommitCallback("bumpyOffsetV",&LLPanelFace::onCommitMaterial, this); + childSetCommitCallback("shinyScaleU",&LLPanelFace::onCommitMaterial, this); + childSetCommitCallback("shinyScaleV",&LLPanelFace::onCommitMaterial, this); + childSetCommitCallback("shinyRot",&LLPanelFace::onCommitMaterial, this); + childSetCommitCallback("shinyOffsetU",&LLPanelFace::onCommitMaterial, this); + childSetCommitCallback("shinyOffsetV",&LLPanelFace::onCommitMaterial, this); + childSetCommitCallback("glossiness",&LLPanelFace::onCommitMaterial, this); + childSetCommitCallback("environment",&LLPanelFace::onCommitMaterial, this); + childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterial, 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 +138,7 @@ BOOL LLPanelFace::postBuild() LLSpinCtrl* mCtrlGlow; setMouseOpaque(FALSE); + mTextureCtrl = getChild<LLTextureCtrl>("texture control"); if(mTextureCtrl) { @@ -112,6 +154,36 @@ BOOL LLPanelFace::postBuild() mTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); } + mShinyTextureCtrl = getChild<LLTextureCtrl>("shinytexture control"); + if(mShinyTextureCtrl) + { + mShinyTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectTexture" ))); + 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->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( "DefaultObjectTexture" ))); + 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->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 +195,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 +233,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 +260,12 @@ BOOL LLPanelFace::postBuild() } LLPanelFace::LLPanelFace() -: LLPanel() +: LLPanel(), + mMaterialID(LLMaterialID::null), + mMaterial(LLMaterialPtr()), + mIsAlpha(false) { + USE_TEXTURE = LLTrans::getString("use_texture"); } @@ -197,8 +296,21 @@ void LLPanelFace::sendBump() { LLComboBox* mComboBumpiness = getChild<LLComboBox>("combobox bumpiness"); if(!mComboBumpiness)return; - U8 bump = (U8) mComboBumpiness->getCurrentIndex() & TEM_BUMP_MASK; + U32 bumpiness = mComboBumpiness->getCurrentIndex(); + if (bumpiness < BUMPY_TEXTURE) + { + LL_DEBUGS("Materials") << "clearing bumptexture control" << LL_ENDL; + LLTextureCtrl* bumpytexture_ctrl = getChild<LLTextureCtrl>("bumpytexture control"); + bumpytexture_ctrl->clear(); + LLSD dummy_data; + onSelectNormalTexture(dummy_data); + } + U8 bump = (U8) bumpiness & TEM_BUMP_MASK; LLSelectMgr::getInstance()->selectionSetBumpmap( bump ); + + //refresh material state (in case this change impacts material params) + LLSD dummy_data; + onCommitNormalTexture(dummy_data); } void LLPanelFace::sendTexGen() @@ -213,8 +325,18 @@ void LLPanelFace::sendShiny() { LLComboBox* mComboShininess = getChild<LLComboBox>("combobox shininess"); if(!mComboShininess)return; - U8 shiny = (U8) mComboShininess->getCurrentIndex() & TEM_SHINY_MASK; + U32 shininess = mComboShininess->getCurrentIndex(); + if (shininess < SHINY_TEXTURE) + { + LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control"); + texture_ctrl->setImageAssetID(LLUUID()); + } + U8 shiny = (U8) shininess & TEM_SHINY_MASK; LLSelectMgr::getInstance()->selectionSetShiny( shiny ); + + //refresh material state (in case this change impacts material params) + LLSD dummy_data; + onCommitSpecularTexture(dummy_data); } void LLPanelFace::sendFullbright() @@ -268,22 +390,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 +411,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) { @@ -482,7 +598,7 @@ void LLPanelFace::sendTextureInfo() } void LLPanelFace::getState() -{ +{ //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,25 +608,53 @@ 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); + + 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); + + onCommitMaterialsMedia(NULL, this); bool identical; + bool identical_diffuse; + bool identical_norm; + bool identical_spec; + LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control"); + LLTextureCtrl* shinytexture_ctrl = getChild<LLTextureCtrl>("shinytexture control"); + LLTextureCtrl* bumpytexture_ctrl = getChild<LLTextureCtrl>("bumpytexture control"); + LLUUID id; + LLUUID normmap_id; + LLUUID specmap_id; + // Texture { - LLUUID id; struct f1 : public LLSelectedTEGetFunctor<LLUUID> { LLUUID get(LLViewerObject* object, S32 te_index) @@ -539,46 +683,206 @@ void LLPanelFace::getState() return id; } } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id ); + identical_diffuse = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id ); + + // Normal map + struct norm_get : public LLSelectedTEGetFunctor<LLUUID> + { + LLUUID get(LLViewerObject* object, S32 te_index) + { + LLUUID id; + + LLMaterial* mat = object->getTE(te_index)->getMaterialParams().get(); + + if (mat) + { + id = mat->getNormalID(); + } + + return id; + } + } norm_get_func; + identical_norm = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &norm_get_func, normmap_id ); + + // Specular map + struct spec_get : public LLSelectedTEGetFunctor<LLUUID> + { + LLUUID get(LLViewerObject* object, S32 te_index) + { + LLUUID id; + + LLMaterial* mat = object->getTE(te_index)->getMaterialParams().get(); + + if (mat) + { + id = mat->getSpecularID(); + } + + return id; + } + } spec_get_func; + identical_spec = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &spec_get_func, specmap_id ); + + mIsAlpha = FALSE; + LLGLenum image_format; + struct f2 : public LLSelectedTEGetFunctor<LLGLenum> + { + LLGLenum get(LLViewerObject* object, S32 te_index) + { + LLGLenum image_format = GL_RGB; + + LLViewerTexture* image = object->getTEImage(te_index); + if (image) image_format = image->getPrimaryFormat(); + return image_format; + } + } func2; + LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func2, 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; + } + break; + } if(LLViewerMedia::textureHasMedia(id)) { - getChildView("textbox autofix")->setEnabled(editable); getChildView("button align")->setEnabled(editable); } - if (identical) + // Specular map + struct alpha_get : public LLSelectedTEGetFunctor<U8> { - // All selected have the same texture - if(texture_ctrl) + U8 get(LLViewerObject* object, S32 te_index) + { + U8 ret = 1; + + LLMaterial* mat = object->getTE(te_index)->getMaterialParams().get(); + + if (mat) { - texture_ctrl->setTentative( FALSE ); - texture_ctrl->setEnabled( editable ); - texture_ctrl->setImageAssetID( id ); + ret = mat->getDiffuseAlphaMode(); } - } - else + + return ret; + } + } alpha_get_func; + + U8 alpha_mode = 1; + LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &alpha_get_func, alpha_mode); + { - if(texture_ctrl) + LLCtrlSelectionInterface* combobox_alphamode = + childGetSelectionInterface("combobox alphamode"); + + if (combobox_alphamode) { - if( id.isNull() ) - { - // None selected - texture_ctrl->setTentative( FALSE ); - texture_ctrl->setEnabled( FALSE ); - texture_ctrl->setImageAssetID( LLUUID::null ); - } - else + if (!mIsAlpha) { - // Tentative: multiple selected with different textures - texture_ctrl->setTentative( TRUE ); - texture_ctrl->setEnabled( editable ); - texture_ctrl->setImageAssetID( id ); + alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; } + + combobox_alphamode->selectNthItem(alpha_mode); + } + else + { + llwarns << "failed childGetSelectionInterface for 'combobox alphamode'" << llendl; + } + + updateAlphaControls(getChild<LLComboBox>("combobox alphamode"),this); + } + + if(texture_ctrl && !texture_ctrl->isPickerShown()) + { + if (identical_diffuse) + { + texture_ctrl->setTentative( FALSE ); + texture_ctrl->setEnabled( editable ); + texture_ctrl->setImageAssetID( id ); + getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha); + getChildView("label alphamode")->setEnabled(editable && mIsAlpha); + getChildView("maskcutoff")->setEnabled(editable && mIsAlpha); + getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha); + } + 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 + { + // Tentative: multiple selected with different textures + texture_ctrl->setTentative( TRUE ); + texture_ctrl->setEnabled( editable ); + texture_ctrl->setImageAssetID( id ); + getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha); + getChildView("label alphamode")->setEnabled(editable && mIsAlpha); + getChildView("maskcutoff")->setEnabled(editable && mIsAlpha); + getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha); + } + } + + if (shinytexture_ctrl && !shinytexture_ctrl->isPickerShown()) + { + if (identical_spec) + { + 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( FALSE ); + shinytexture_ctrl->setImageAssetID( LLUUID::null ); + } + else + { + shinytexture_ctrl->setTentative( TRUE ); + shinytexture_ctrl->setEnabled( editable ); + shinytexture_ctrl->setImageAssetID( specmap_id ); + } + } + + if (bumpytexture_ctrl && !bumpytexture_ctrl->isPickerShown()) + { + if (identical_norm) + { + 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( FALSE ); + 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; @@ -617,6 +921,26 @@ void LLPanelFace::getState() } } + // 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; + + { + struct f11 : public LLSelectedTEGetFunctor<LLTextureEntry::e_texgen> + { + LLTextureEntry::e_texgen get(LLViewerObject* object, S32 face) + { + return (LLTextureEntry::e_texgen)(object->getTE(face)->getTexGen()); + } + } func; + identical_texgen = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, selected_texgen ); + identical_planar_texgen = (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)); + } + // Texture scale { F32 scale_s = 1.f; @@ -627,14 +951,68 @@ void LLPanelFace::getState() return object->getTE(face)->mScaleS; } } func; + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_s ); identical = align_planar ? identical_planar_aligned : identical; - getChild<LLUICtrl>("TexScaleU")->setValue(editable ? llabs(scale_s) : 0); + + F32 scale_u = editable ? scale_s : 0; + scale_u *= identical_planar_texgen ? 2.0f : 1.0f; + + getChild<LLUICtrl>("TexScaleU")->setValue(scale_u); getChild<LLUICtrl>("TexScaleU")->setTentative(LLSD((BOOL)(!identical))); 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); + + scale_s = 1.f; + struct f3 : public LLSelectedTEGetFunctor<F32> + { + F32 get(LLViewerObject* object, S32 face) + { + F32 s = 1.f, t = 1.f; + + LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); + if (mat) + { + mat->getSpecularRepeat(s, t); + } + return s; + } + } shiny_func; + + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &shiny_func, scale_s ); + identical = align_planar ? identical_planar_aligned : identical; + + F32 scale_s_value = editable ? scale_s : 0; + scale_s_value *= identical_planar_texgen ? 2.0f : 1.0f; + + getChild<LLUICtrl>("shinyScaleU")->setValue(scale_s_value); + getChild<LLUICtrl>("shinyScaleU")->setTentative(LLSD((BOOL)(!identical))); + getChildView("shinyScaleU")->setEnabled(editable && specmap_id.notNull()); + + scale_s = 1.f; + struct f4 : public LLSelectedTEGetFunctor<F32> + { + F32 get(LLViewerObject* object, S32 face) + { + F32 s = 1.f, t = 1.f; + + LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); + if (mat) + { + mat->getNormalRepeat(s, t); + } + return s; + } + } bump_func; + + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &bump_func, scale_s ); + identical = align_planar ? identical_planar_aligned : identical; + + scale_s_value = editable ? scale_s : 0; + scale_s_value *= identical_planar_texgen ? 2.0f : 1.0f; + + getChild<LLUICtrl>("bumpyScaleU")->setValue(scale_s_value); + getChild<LLUICtrl>("bumpyScaleU")->setTentative(LLSD((BOOL)(!identical))); + getChildView("bumpyScaleU")->setEnabled(editable && normmap_id.notNull()); } { @@ -649,12 +1027,65 @@ void LLPanelFace::getState() identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_t ); identical = align_planar ? identical_planar_aligned : identical; - getChild<LLUICtrl>("TexScaleV")->setValue(llabs(editable ? llabs(scale_t) : 0)); + F32 scale_t_value = editable ? scale_t : 0; + scale_t_value *= identical_planar_texgen ? 2.0f : 1.0f; + + getChild<LLUICtrl>("TexScaleV")->setValue(scale_t_value); 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); + + scale_t = 1.f; + struct f4 : public LLSelectedTEGetFunctor<F32> + { + F32 get(LLViewerObject* object, S32 face) + { + F32 s = 1.f, t = 1.f; + + LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); + if (mat) + { + mat->getSpecularRepeat(s, t); + } + return t; + } + } shiny_func; + + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &shiny_func, scale_t ); + identical = align_planar ? identical_planar_aligned : identical; + + scale_t_value = editable ? scale_t : 0; + scale_t_value *= identical_planar_texgen ? 2.0f : 1.0f; + + getChild<LLUICtrl>("shinyScaleV")->setValue(scale_t_value); + getChild<LLUICtrl>("shinyScaleV")->setTentative(LLSD((BOOL)(!identical))); + getChildView("shinyScaleV")->setEnabled(editable && specmap_id.notNull()); + + scale_t = 1.f; + struct f5 : public LLSelectedTEGetFunctor<F32> + { + F32 get(LLViewerObject* object, S32 face) + { + F32 s = 1.f, t = 1.f; + + LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); + if (mat) + { + mat->getNormalRepeat(s, t); + } + return t; + } + } bump_func; + + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &bump_func, scale_t ); + identical = align_planar ? identical_planar_aligned : identical; + + scale_t_value = editable ? scale_t : 0.0f; + scale_t_value *= identical_planar_texgen ? 2.0f : 1.0f; + + getChild<LLUICtrl>("bumpyScaleV")->setValue(scale_t_value); + getChild<LLUICtrl>("bumpyScaleV")->setTentative(LLSD((BOOL)(!identical))); + getChildView("bumpyScaleV")->setEnabled(editable && normmap_id.notNull()); + } // Texture offset @@ -673,6 +1104,51 @@ void LLPanelFace::getState() getChild<LLUICtrl>("TexOffsetU")->setValue(editable ? offset_s : 0); getChild<LLUICtrl>("TexOffsetU")->setTentative(!identical); getChildView("TexOffsetU")->setEnabled(editable); + + offset_s = 1.f; + struct f3 : public LLSelectedTEGetFunctor<F32> + { + F32 get(LLViewerObject* object, S32 face) + { + F32 s = 0.f, t = 0.f; + + LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); + if (mat) + { + mat->getSpecularOffset(s, t); + } + return s; + } + } shiny_func; + + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &shiny_func, offset_s ); + identical = align_planar ? identical_planar_aligned : identical; + getChild<LLUICtrl>("shinyOffsetU")->setValue(editable ? offset_s : 0); + getChild<LLUICtrl>("shinyOffsetU")->setTentative(LLSD((BOOL)(!identical))); + getChildView("shinyOffsetU")->setEnabled(editable && specmap_id.notNull()); + + offset_s = 1.f; + struct f5 : public LLSelectedTEGetFunctor<F32> + { + F32 get(LLViewerObject* object, S32 face) + { + F32 s = 0.f, t = 0.f; + + LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); + if (mat) + { + mat->getNormalOffset(s, t); + } + return s; + } + } bump_func; + + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &bump_func, offset_s ); + identical = align_planar ? identical_planar_aligned : identical; + + getChild<LLUICtrl>("bumpyOffsetU")->setValue(editable ? offset_s : 0); + getChild<LLUICtrl>("bumpyOffsetU")->setTentative(LLSD((BOOL)(!identical))); + getChildView("bumpyOffsetU")->setEnabled(editable && normmap_id.notNull()); } { @@ -689,6 +1165,52 @@ void LLPanelFace::getState() getChild<LLUICtrl>("TexOffsetV")->setValue(editable ? offset_t : 0); getChild<LLUICtrl>("TexOffsetV")->setTentative(!identical); getChildView("TexOffsetV")->setEnabled(editable); + + + offset_t = 1.f; + struct f3 : public LLSelectedTEGetFunctor<F32> + { + F32 get(LLViewerObject* object, S32 face) + { + F32 s = 1.f, t = 1.f; + + LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); + if (mat) + { + mat->getSpecularOffset(s, t); + } + return t; + } + } shiny_func; + + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &shiny_func, offset_t ); + identical = align_planar ? identical_planar_aligned : identical; + getChild<LLUICtrl>("shinyOffsetV")->setValue(editable ? offset_t : 0); + getChild<LLUICtrl>("shinyOffsetV")->setTentative(LLSD((BOOL)(!identical))); + getChildView("shinyOffsetV")->setEnabled(editable && specmap_id.notNull()); + + offset_t = 1.f; + struct f4 : public LLSelectedTEGetFunctor<F32> + { + F32 get(LLViewerObject* object, S32 face) + { + F32 s = 1.f, t = 1.f; + + LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); + if (mat) + { + mat->getNormalOffset(s, t); + } + return t; + } + } bump_func; + + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &bump_func, offset_t ); + identical = align_planar ? identical_planar_aligned : identical; + + getChild<LLUICtrl>("bumpyOffsetV")->setValue(editable ? offset_t : 0); + getChild<LLUICtrl>("bumpyOffsetV")->setTentative(LLSD((BOOL)(!identical))); + getChildView("bumpyOffsetV")->setEnabled(editable && normmap_id.notNull()); } // Texture rotation @@ -706,9 +1228,59 @@ void LLPanelFace::getState() getChild<LLUICtrl>("TexRot")->setValue(editable ? rotation * RAD_TO_DEG : 0); getChild<LLUICtrl>("TexRot")->setTentative(!identical); getChildView("TexRot")->setEnabled(editable); + + + + rotation = 1.f; + struct f3 : public LLSelectedTEGetFunctor<F32> + { + F32 get(LLViewerObject* object, S32 face) + { + F32 ret = 0.f; + + LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); + if (mat) + { + ret = mat->getSpecularRotation(); + } + return ret; + } + } shiny_func; + + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &shiny_func, rotation ); + identical = align_planar ? identical_planar_aligned : identical; + getChild<LLUICtrl>("shinyRot")->setValue(editable ? rotation * RAD_TO_DEG : 0); + getChild<LLUICtrl>("shinyRot")->setTentative(LLSD((BOOL)(!identical))); + getChildView("shinyRot")->setEnabled(editable && specmap_id.notNull()); + + rotation = 1.f; + struct f4 : public LLSelectedTEGetFunctor<F32> + { + F32 get(LLViewerObject* object, S32 face) + { + F32 ret = 0.f; + + LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); + if (mat) + { + ret = mat->getNormalRotation(); + } + return ret; + } + } bump_func; + + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &bump_func, rotation ); + identical = align_planar ? identical_planar_aligned : identical; + + getChild<LLUICtrl>("bumpyRot")->setValue(editable ? rotation * RAD_TO_DEG : 0); + getChild<LLUICtrl>("bumpyRot")->setTentative(LLSD((BOOL)(!identical))); + getChildView("bumpyRot")->setEnabled(editable && normmap_id.notNull()); } // Color swatch + { + getChildView("color label")->setEnabled(editable); + } LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch"); LLColor4 color = LLColor4::white; if(mColorSwatch) @@ -729,6 +1301,7 @@ void LLPanelFace::getState() mColorSwatch->setEnabled( editable ); mColorSwatch->setCanApplyImmediately( editable ); } + // Color transparency { getChildView("color trans")->setEnabled(editable); @@ -758,22 +1331,26 @@ void LLPanelFace::getState() } - // Bump - { - F32 shinyf = 0.f; - struct f9 : public LLSelectedTEGetFunctor<F32> + U8 shiny = 0; + + // Shiny + { + struct f9 : public LLSelectedTEGetFunctor<U8> { - F32 get(LLViewerObject* object, S32 face) + U8 get(LLViewerObject* object, S32 face) { - return (F32)(object->getTE(face)->getShiny()); + return (U8)(object->getTE(face)->getShiny()); } } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, shinyf ); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, shiny ); + + LLUUID spec_map_id = getChild<LLTextureCtrl>("shinytexture control")->getImageAssetID(); + LLCtrlSelectionInterface* combobox_shininess = childGetSelectionInterface("combobox shininess"); if (combobox_shininess) { - combobox_shininess->selectNthItem((S32)shinyf); + combobox_shininess->selectNthItem(spec_map_id.isNull() ? (S32)shiny : SHINY_TEXTURE); } else { @@ -782,23 +1359,45 @@ void LLPanelFace::getState() getChildView("combobox shininess")->setEnabled(editable); getChild<LLUICtrl>("combobox shininess")->setTentative(!identical); getChildView("label shininess")->setEnabled(editable); + getChildView("glossiness")->setEnabled(editable); + getChild<LLUICtrl>("glossiness")->setTentative(!identical); + getChildView("label glossiness")->setEnabled(editable); + getChildView("environment")->setEnabled(editable); + getChild<LLUICtrl>("environment")->setTentative(!identical); + getChildView("label environment")->setEnabled(editable); + getChild<LLUICtrl>("shinycolorswatch")->setTentative(!identical); + getChildView("label shinycolor")->setEnabled(editable); } + LLColorSwatchCtrl* mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch"); + if(mShinyColorSwatch) { - F32 bumpf = 0.f; - struct f10 : public LLSelectedTEGetFunctor<F32> + mShinyColorSwatch->setValid(editable); + mShinyColorSwatch->setEnabled( editable ); + mShinyColorSwatch->setCanApplyImmediately( editable ); + } + + U8 bumpy = 0; + + // Bumpy + { + struct f10 : public LLSelectedTEGetFunctor<U8> { - F32 get(LLViewerObject* object, S32 face) + U8 get(LLViewerObject* object, S32 face) { - return (F32)(object->getTE(face)->getBumpmap()); + return object->getTE(face)->getBumpmap(); } } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, bumpf ); - LLCtrlSelectionInterface* combobox_bumpiness = - childGetSelectionInterface("combobox bumpiness"); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, bumpy ); + + LLUUID norm_map_id = getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID(); + + bumpy = norm_map_id.isNull() ? (S32)bumpy : BUMPY_TEXTURE; + + LLCtrlSelectionInterface* combobox_bumpiness = childGetSelectionInterface("combobox bumpiness"); if (combobox_bumpiness) - { - combobox_bumpiness->selectNthItem((S32)bumpf); + { + combobox_bumpiness->selectNthItem(bumpy); } else { @@ -809,22 +1408,12 @@ void LLPanelFace::getState() getChildView("label bumpiness")->setEnabled(editable); } - { - F32 genf = 0.f; - struct f11 : public LLSelectedTEGetFunctor<F32> - { - F32 get(LLViewerObject* object, S32 face) - { - return (F32)(object->getTE(face)->getTexGen()); - } - } 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_texgen->selectNthItem(((S32)selected_texgen) >> 1); // Maps from enum to combobox entry index } else { @@ -834,45 +1423,40 @@ void LLPanelFace::getState() getChild<LLUICtrl>("combobox texgen")->setTentative(!identical); getChildView("tex gen")->setEnabled(editable); - if (selected_texgen == 1) + if (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR) { - getChild<LLUICtrl>("TexScaleU")->setValue(2.0f * getChild<LLUICtrl>("TexScaleU")->getValue().asReal() ); - getChild<LLUICtrl>("TexScaleV")->setValue(2.0f * getChild<LLUICtrl>("TexScaleV")->getValue().asReal() ); - // 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 (selected_texgen == LLTextureEntry::TEX_GEN_DEFAULT) { getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per face")); } } { - F32 fullbrightf = 0.f; - struct f12 : public LLSelectedTEGetFunctor<F32> + U8 fullbright_flag = 0; + struct f12 : public LLSelectedTEGetFunctor<U8> { - F32 get(LLViewerObject* object, S32 face) + U8 get(LLViewerObject* object, S32 face) { - return (F32)(object->getTE(face)->getFullbright()); + return object->getTE(face)->getFullbright(); } } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, fullbrightf ); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, fullbright_flag ); - getChild<LLUICtrl>("checkbox fullbright")->setValue((S32)fullbrightf); + getChild<LLUICtrl>("checkbox fullbright")->setValue((S32)(fullbright_flag != 0)); getChildView("checkbox fullbright")->setEnabled(editable); getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical); } - // Repeats per meter label - { - getChildView("rpt")->setEnabled(editable); - } - // Repeats per meter { - F32 repeats = 1.f; + F32 repeats_diff = 1.f; + F32 repeats_norm = 1.f; + F32 repeats_spec = 1.f; + struct f13 : public LLSelectedTEGetFunctor<F32> { F32 get(LLViewerObject* object, S32 face) @@ -882,22 +1466,136 @@ void LLPanelFace::getState() // 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]; + 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); + } + + } func_diff; + bool identical_diff_repeats = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_diff, repeats_diff ); + + struct f14 : 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); } - } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, repeats ); + + } func_norm; + BOOL identical_norm_repeats = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_norm, repeats_norm ); + + struct f15 : 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); + } + + } func_spec; + BOOL identical_spec_repeats = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_spec, repeats_spec ); - getChild<LLUICtrl>("rptctrl")->setValue(editable ? repeats : 0); - getChild<LLUICtrl>("rptctrl")->setTentative(!identical); + LLComboBox* mComboTexGen = getChild<LLComboBox>("combobox texgen"); if (mComboTexGen) { - BOOL enabled = editable && (!mComboTexGen || mComboTexGen->getCurrentIndex() != 1); - getChildView("rptctrl")->setEnabled(enabled); - getChildView("button apply")->setEnabled(enabled); + S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0; + BOOL enabled = editable && (index != 1); + BOOL identical = true; + F32 repeats = 1.0f; + + U32 material_type = combobox_mattype->getCurrentIndex(); + switch (material_type) + { + default: + case MATTYPE_DIFFUSE: + { + enabled = editable && !id.isNull(); + identical = identical_diff_repeats; + repeats = repeats_diff; + } + break; + + case MATTYPE_SPECULAR: + { + enabled = (editable && ((shiny == SHINY_TEXTURE) && !specmap_id.isNull())); + identical = identical_spec_repeats; + repeats = repeats_spec; + } + break; + + case MATTYPE_NORMAL: + { + enabled = (editable && ((bumpy == BUMPY_TEXTURE) && !normmap_id.isNull())); + identical = identical_norm_repeats; + repeats = repeats_norm; + } + break; + } + + getChildView("rptctrl")->setEnabled(identical_planar_texgen ? FALSE : enabled); + getChild<LLUICtrl>("rptctrl")->setValue(editable ? repeats : 1.0f); + getChild<LLUICtrl>("rptctrl")->setTentative(!identical); } } + // Materials + { + mMaterialID = LLMaterialID::null; + mMaterial = NULL; + + struct f1 : public LLSelectedTEGetFunctor<LLMaterialID> + { + LLMaterialID get(LLViewerObject* object, S32 te_index) + { + LLMaterialID material_id; + + return object->getTE(te_index)->getMaterialID(); + } + } func; + + LLObjectSelectionHandle sel = LLSelectMgr::getInstance()->getSelection(); + LLSelectNode* node = sel->getFirstNode(); + if (node) + { + int selected_te = node->getLastSelectedTE(); + if (selected_te >= 0) + { + mMaterialID = node->getObject()->getTE(selected_te)->getMaterialID(); + } + } + + llinfos << "Material ID returned: '" << mMaterialID.asString() << "', isNull? " << (mMaterialID.isNull()?"TRUE":"FALSE") << llendl; + + if (!mMaterialID.isNull() && editable) + { + llinfos << "Requesting material ID " << mMaterialID.asString() << llendl; + LLMaterialMgr::getInstance()->get(objectp->getRegion()->getRegionID(),mMaterialID,boost::bind(&LLPanelFace::onMaterialLoaded, this, _1, _2)); + } + + } + // Set variable values for numeric expressions LLCalc* calcp = LLCalc::getInstance(); calcp->setVar(LLCalc::TEX_U_SCALE, childGetValue("TexScaleU").asReal()); @@ -935,13 +1633,11 @@ void LLPanelFace::getState() 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); - + + onCommitMaterialsMedia(NULL,this); // Set variable values for numeric expressions LLCalc* calcp = LLCalc::getInstance(); @@ -958,9 +1654,277 @@ void LLPanelFace::getState() void LLPanelFace::refresh() { + LL_DEBUGS("Materials") << LL_ENDL; getState(); } +void LLPanelFace::onMaterialLoaded(const LLMaterialID& material_id, const LLMaterialPtr material) +{ //laying out UI based on material parameters (calls setVisible on various components) + LL_DEBUGS("Materials") << "material id " << material_id.asString() << " data " << material->asLLSD() << LL_ENDL; + + //make a local copy of the material for editing + // (prevents local edits from overwriting client state on shared materials) + mMaterial = new LLMaterial(*material); + mMaterialID = material_id; + + // Alpha + LLCtrlSelectionInterface* combobox_alphamode = + childGetSelectionInterface("combobox alphamode"); + if (combobox_alphamode) + { + combobox_alphamode->selectNthItem(material->getDiffuseAlphaMode()); + } + else + { + llwarns << "failed childGetSelectionInterface for 'combobox alphamode'" << llendl; + } + getChild<LLUICtrl>("maskcutoff")->setValue(material->getAlphaMaskCutoff()); + updateAlphaControls(getChild<LLComboBox>("combobox alphamode"),this); + + LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT; + bool identical_texgen = true; + bool identical_planar_texgen = false; + + struct f44 : public LLSelectedTEGetFunctor<LLTextureEntry::e_texgen> + { + LLTextureEntry::e_texgen get(LLViewerObject* object, S32 face) + { + return (LLTextureEntry::e_texgen)(object->getTE(face)->getTexGen()); + } + } func; + identical_texgen = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, selected_texgen ); + identical_planar_texgen = (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)); + + // Shiny (specular) + F32 offset_x, offset_y, repeat_x, repeat_y, rot; + LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control"); + texture_ctrl->setImageAssetID(material->getSpecularID()); + LLComboBox* combobox_shininess = getChild<LLComboBox>("combobox shininess"); + if (!material->getSpecularID().isNull()) + { + material->getSpecularOffset(offset_x,offset_y); + material->getSpecularRepeat(repeat_x,repeat_y); + + if (identical_planar_texgen) + { + 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(combobox_shininess,this, !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()) + { + getChild<LLColorSwatchCtrl>("shinycolorswatch")->setOriginal(material->getSpecularLightColor()); + getChild<LLColorSwatchCtrl>("shinycolorswatch")->set(material->getSpecularLightColor(),TRUE); + } + + // Bumpy (normal) + texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control"); + texture_ctrl->setImageAssetID(material->getNormalID()); + LLComboBox* combobox_bumpiness = getChild<LLComboBox>("combobox bumpiness"); + if (!material->getNormalID().isNull()) + { + material->getNormalOffset(offset_x,offset_y); + material->getNormalRepeat(repeat_x,repeat_y); + + if (identical_planar_texgen) + { + repeat_x *= 2.0f; + repeat_y *= 2.0f; + } + + 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(combobox_bumpiness,this, !material->getNormalID().isNull(), true); +} + +void LLPanelFace::updateMaterial() +{ // assign current state of UI to material definition for submit to sim + LL_DEBUGS("Materials") << "Entered." << LL_ENDL; + LLComboBox* comboAlphaMode = getChild<LLComboBox>("combobox alphamode"); + LLComboBox* comboBumpiness = getChild<LLComboBox>("combobox bumpiness"); + LLComboBox* comboShininess = getChild<LLComboBox>("combobox shininess"); + if (!comboAlphaMode || !comboBumpiness || !comboShininess) + { + return; + } + U32 alpha_mode = comboAlphaMode->getCurrentIndex(); + U32 bumpiness = comboBumpiness->getCurrentIndex(); + U32 shininess = comboShininess->getCurrentIndex(); + + LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT; + struct f45 : public LLSelectedTEGetFunctor<LLTextureEntry::e_texgen> + { + LLTextureEntry::e_texgen get(LLViewerObject* object, S32 face) + { + return (LLTextureEntry::e_texgen)(object->getTE(face)->getTexGen()); + } + } func; + bool identical_texgen = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, selected_texgen ); + bool identical_planar_texgen = (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)); + + if ((mIsAlpha && (alpha_mode != LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)) + || (bumpiness == BUMPY_TEXTURE) + || (shininess == SHINY_TEXTURE)) + { + // The user's specified something that needs a material. + bool new_material = false; + if (!mMaterial) + { + new_material = true; + mMaterial = LLMaterialPtr(new LLMaterial()); + } + + LLMaterialPtr material_to_set = mMaterial; + + bool subselection = false; + + // If we're editing a single face and not the entire material for an object, + // we need to clone the material so that our changes to the material's settings + // don't automatically propagate to the non-selected faces + // NORSPEC-92 + // + LLObjectSelectionHandle sel = LLSelectMgr::getInstance()->getSelection(); + LLSelectNode* node = sel->getFirstNode(); + if (node) + { + if (node->getTESelectMask() != TE_SELECT_MASK_ALL) + { + llinfos << "Cloning material to apply to subselection." << llendl; + material_to_set = new LLMaterial(mMaterial->asLLSD()); + subselection = true; + } + else + { + llinfos << "Apply material change to whole selection." << llendl; + } + } + + llassert(!material_to_set.isNull()); + + material_to_set->setDiffuseAlphaMode(getChild<LLComboBox>("combobox alphamode")->getCurrentIndex()); + material_to_set->setAlphaMaskCutoff((U8)(getChild<LLUICtrl>("maskcutoff")->getValue().asInteger())); + + LLUUID norm_map_id = getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID(); + if (!norm_map_id.isNull() && (bumpiness == BUMPY_TEXTURE)) + { + LL_DEBUGS("Materials") << "Setting bumpy texture, bumpiness = " << bumpiness << LL_ENDL; + material_to_set->setNormalID(norm_map_id); + + F32 bumpy_scale_u = getChild<LLUICtrl>("bumpyScaleU")->getValue().asReal(); + F32 bumpy_scale_v = getChild<LLUICtrl>("bumpyScaleV")->getValue().asReal(); + + if (identical_planar_texgen) + { + bumpy_scale_u *= 0.5f; + bumpy_scale_v *= 0.5f; + } + + material_to_set->setNormalOffset(getChild<LLUICtrl>("bumpyOffsetU")->getValue().asReal(), + getChild<LLUICtrl>("bumpyOffsetV")->getValue().asReal()); + material_to_set->setNormalRepeat(bumpy_scale_u, bumpy_scale_v); + material_to_set->setNormalRotation(getChild<LLUICtrl>("bumpyRot")->getValue().asReal()*DEG_TO_RAD); + } + else + { + LL_DEBUGS("Materials") << "Removing bumpy texture, bumpiness = " << bumpiness << LL_ENDL; + material_to_set->setNormalID(LLUUID()); + material_to_set->setNormalOffset(0.0f,0.0f); + material_to_set->setNormalRepeat(1.0f,1.0f); + material_to_set->setNormalRotation(0.0f); + } + + LLUUID spec_map_id = getChild<LLTextureCtrl>("shinytexture control")->getImageAssetID(); + + if (!spec_map_id.isNull() && (shininess == SHINY_TEXTURE)) + { + LL_DEBUGS("Materials") << "Setting shiny texture, shininess = " << shininess << LL_ENDL; + material_to_set->setSpecularID(spec_map_id); + material_to_set->setSpecularOffset(getChild<LLUICtrl>("shinyOffsetU")->getValue().asReal(), + getChild<LLUICtrl>("shinyOffsetV")->getValue().asReal()); + + F32 shiny_scale_u = getChild<LLUICtrl>("shinyScaleU")->getValue().asReal(); + F32 shiny_scale_v = getChild<LLUICtrl>("shinyScaleV")->getValue().asReal(); + + if (identical_planar_texgen) + { + shiny_scale_u *= 0.5f; + shiny_scale_v *= 0.5f; + } + + material_to_set->setSpecularRepeat(shiny_scale_u, shiny_scale_v); + material_to_set->setSpecularRotation(getChild<LLUICtrl>("shinyRot")->getValue().asReal()*DEG_TO_RAD); + + //override shininess to 0.2f if this is a new material + if (!new_material) + { + material_to_set->setSpecularLightColor(getChild<LLColorSwatchCtrl>("shinycolorswatch")->get()); + material_to_set->setSpecularLightExponent(getChild<LLUICtrl>("glossiness")->getValue().asInteger()); + material_to_set->setEnvironmentIntensity(getChild<LLUICtrl>("environment")->getValue().asInteger()); + } + } + else + { + LL_DEBUGS("Materials") << "Removing shiny texture, shininess = " << shininess << LL_ENDL; + material_to_set->setSpecularID(LLUUID()); + material_to_set->setSpecularOffset(0.0f,0.0f); + material_to_set->setSpecularRepeat(1.0f,1.0f); + material_to_set->setSpecularRotation(0.0f); + material_to_set->setSpecularLightColor(LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR); + material_to_set->setSpecularLightExponent(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT); + material_to_set->setEnvironmentIntensity(0); + } + + LL_DEBUGS("Materials") << "Updating material: " << material_to_set->asLLSD() << LL_ENDL; + + + if (node && node->getObject() && node->getObject()->permModify() && subselection) + { + int selected_te = node->getLastSelectedTE(); + if (selected_te >= 0) + { + LLMaterialMgr::getInstance()->put(node->getObject()->getID(),selected_te,*material_to_set); + node->getObject()->getTE(selected_te)->setMaterialParams(material_to_set); + node->getObject()->sendTEUpdate(); + } + } + else + { + LLSelectMgr::getInstance()->selectionSetMaterial( material_to_set ); + } + } + else + { + // The user has specified settings that don't need a material. + if (mMaterial || !mMaterialID.isNull()) + { + LL_DEBUGS("Materials") << "Resetting material entry" << LL_ENDL; + mMaterial = NULL; + mMaterialID = LLMaterialID::null; + // Delete existing material entry... + LLSelectMgr::getInstance()->selectionRemoveMaterial(); + } + } +} + // // Static functions // @@ -977,6 +1941,11 @@ void LLPanelFace::onCommitColor(const LLSD& data) sendColor(); } +void LLPanelFace::onCommitShinyColor(const LLSD& data) +{ + updateMaterial(); +} + void LLPanelFace::onCommitAlpha(const LLSD& data) { sendAlpha(); @@ -994,10 +1963,134 @@ void LLPanelFace::onSelectColor(const LLSD& data) } // static +void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + LLComboBox* combo_matmedia = self->getChild<LLComboBox>("combobox matmedia"); + LLComboBox* combo_mattype = self->getChild<LLComboBox>("combobox mattype"); + LLComboBox* combo_shininess = self->getChild<LLComboBox>("combobox shininess"); + LLComboBox* combo_bumpiness = self->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(); + self->getChildView("combobox mattype")->setVisible(!show_media); + self->getChildView("rptctrl")->setVisible(true); + + // Media controls + self->getChildView("media_info")->setVisible(show_media); + self->getChildView("add_media")->setVisible(show_media); + self->getChildView("delete_media")->setVisible(show_media); + self->getChildView("button align")->setVisible(show_media); + + // Diffuse texture controls + self->getChildView("texture control")->setVisible(show_texture && !show_media); + self->getChildView("label alphamode")->setVisible(show_texture && !show_media); + self->getChildView("combobox alphamode")->setVisible(show_texture && !show_media); + self->getChildView("label maskcutoff")->setVisible(false); + self->getChildView("maskcutoff")->setVisible(false); + if (show_texture && !show_media) + { + updateAlphaControls(ctrl, userdata); + } + self->getChildView("TexScaleU")->setVisible(show_texture); + self->getChildView("TexScaleV")->setVisible(show_texture); + self->getChildView("TexRot")->setVisible(show_texture); + self->getChildView("TexOffsetU")->setVisible(show_texture); + self->getChildView("TexOffsetV")->setVisible(show_texture); + + // Specular map controls + self->getChildView("shinytexture control")->setVisible(show_shininess); + self->getChildView("combobox shininess")->setVisible(show_shininess); + self->getChildView("label shininess")->setVisible(show_shininess); + self->getChildView("label glossiness")->setVisible(false); + self->getChildView("glossiness")->setVisible(false); + self->getChildView("label environment")->setVisible(false); + self->getChildView("environment")->setVisible(false); + self->getChildView("label shinycolor")->setVisible(false); + self->getChildView("shinycolorswatch")->setVisible(false); + if (show_shininess) + { + updateShinyControls(ctrl, userdata); + } + self->getChildView("shinyScaleU")->setVisible(show_shininess); + self->getChildView("shinyScaleV")->setVisible(show_shininess); + self->getChildView("shinyRot")->setVisible(show_shininess); + self->getChildView("shinyOffsetU")->setVisible(show_shininess); + self->getChildView("shinyOffsetV")->setVisible(show_shininess); + + // Normal map controls + if (show_bumpiness) + { + updateBumpyControls(ctrl, userdata); + } + self->getChildView("bumpytexture control")->setVisible(show_bumpiness); + self->getChildView("combobox bumpiness")->setVisible(show_bumpiness); + self->getChildView("label bumpiness")->setVisible(show_bumpiness); + self->getChildView("bumpyScaleU")->setVisible(show_bumpiness); + self->getChildView("bumpyScaleV")->setVisible(show_bumpiness); + self->getChildView("bumpyRot")->setVisible(show_bumpiness); + self->getChildView("bumpyOffsetU")->setVisible(show_bumpiness); + self->getChildView("bumpyOffsetV")->setVisible(show_bumpiness); + + // Enable texture scale/rotation/offset parameters if there's one + // present to set for + bool texParmsEnable = show_texture || + (show_shininess && (combo_shininess->getCurrentIndex() == SHINY_TEXTURE)) || + (show_bumpiness && (combo_bumpiness->getCurrentIndex() == BUMPY_TEXTURE)); + self->getChildView("tex gen")->setEnabled(texParmsEnable); + self->getChildView("combobox texgen")->setEnabled(texParmsEnable); + self->getChildView("rptctrl")->setEnabled(texParmsEnable); + self->getChildView("TexScaleU")->setEnabled(texParmsEnable); + self->getChildView("TexScaleV")->setEnabled(texParmsEnable); + self->getChildView("TexRot")->setEnabled(texParmsEnable); + self->getChildView("TexOffsetU")->setEnabled(texParmsEnable); + self->getChildView("TexOffsetV")->setEnabled(texParmsEnable); + self->getChildView("shinyScaleU")->setEnabled(texParmsEnable); + self->getChildView("shinyScaleV")->setEnabled(texParmsEnable); + self->getChildView("shinyRot")->setEnabled(texParmsEnable); + self->getChildView("shinyOffsetU")->setEnabled(texParmsEnable); + self->getChildView("shinyOffsetV")->setEnabled(texParmsEnable); + self->getChildView("bumpyScaleU")->setEnabled(texParmsEnable); + self->getChildView("bumpyScaleV")->setEnabled(texParmsEnable); + self->getChildView("bumpyRot")->setEnabled(texParmsEnable); + self->getChildView("bumpyOffsetU")->setEnabled(texParmsEnable); + self->getChildView("bumpyOffsetV")->setEnabled(texParmsEnable); + self->getChildView("checkbox planar align")->setEnabled(texParmsEnable); + + // Needed to handle transitions to/from media mode + // NORSPEC-84 + updateAlphaControls(ctrl,userdata); +} + +// static +void LLPanelFace::onCommitMaterialType(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + // This is here to insure that we properly update shared UI elements + // like the texture ctrls for diffuse/norm/spec so that they are correct + // when switching modes + // + self->getState(); +} + +// static void LLPanelFace::onCommitBump(LLUICtrl* ctrl, void* userdata) { LLPanelFace* self = (LLPanelFace*) userdata; self->sendBump(); + + LLComboBox* combo_bumpy = self->getChild<LLComboBox>("combobox bumpiness"); + + updateBumpyControls(combo_bumpy,self, false, true); + self->updateMaterial(); } // static @@ -1008,10 +2101,158 @@ void LLPanelFace::onCommitTexGen(LLUICtrl* ctrl, void* userdata) } // static +void LLPanelFace::updateShinyControls(LLUICtrl* ctrl, void* userdata, bool is_setting_texture, bool mess_with_shiny_combobox) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + LLTextureCtrl* texture_ctrl = self->getChild<LLTextureCtrl>("shinytexture control"); + LLUUID shiny_texture_ID = texture_ctrl->getImageAssetID(); + LL_DEBUGS("Materials") << "Shiny texture selected: " << shiny_texture_ID << LL_ENDL; + LLComboBox* comboShiny = self->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); + + // NORSPEC-94: Set default specular color to white + // + LLColorSwatchCtrl* mShinyColorSwatch = self->getChild<LLColorSwatchCtrl>("shinycolorswatch"); + if(mShinyColorSwatch) + { + LL_DEBUGS("Materials") << "Resetting specular color to default of white" << LL_ENDL; + mShinyColorSwatch->setOriginal(LLColor4::white); + mShinyColorSwatch->set(LLColor4::white, TRUE); + } + self->getChild<LLUICtrl>("glossiness")->setValue(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT); + self->getChild<LLUICtrl>("environment")->setValue(0); + } + comboShiny->setSimple(USE_TEXTURE); + } + else + { + if (comboShiny->itemExists(USE_TEXTURE)) + { + // HACK: This depends on adding the "Use texture" + // item at the end of a list of known length. + comboShiny->remove(SHINY_TEXTURE); + } + } + } + + 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 = 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 + self->getChildView("label glossiness")->setVisible(show_shinyctrls); + self->getChildView("glossiness")->setVisible(show_shinyctrls); + self->getChildView("label environment")->setVisible(show_shinyctrls); + self->getChildView("environment")->setVisible(show_shinyctrls); + self->getChildView("label shinycolor")->setVisible(show_shinyctrls); + self->getChildView("shinycolorswatch")->setVisible(show_shinyctrls); +} + +// static +void LLPanelFace::updateBumpyControls(LLUICtrl* ctrl, void* userdata, bool is_setting_texture, bool mess_with_combobox) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + LLTextureCtrl* texture_ctrl = self->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 = self->getChild<LLComboBox>("combobox bumpiness"); + if (!comboBumpy) + { + return; + } + + if (mess_with_combobox) + { + LLTextureCtrl* texture_ctrl = self->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)) + { + // HACK: This depends on adding the "Use texture" + // item at the end of a list of known length. + comboBumpy->remove(BUMPY_TEXTURE); + } + } + } +} + +// static void LLPanelFace::onCommitShiny(LLUICtrl* ctrl, void* userdata) { LLPanelFace* self = (LLPanelFace*) userdata; - self->sendShiny(); + self->sendShiny(); + LLComboBox* combo_shiny = self->getChild<LLComboBox>("combobox shininess"); + // Need 'true' here to insure that the 'Use Texture' choice is removed + // when we select something other than a spec texture + // + updateShinyControls(combo_shiny,self, false, true); + self->updateMaterial(); +} + +// static +void LLPanelFace::updateAlphaControls(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + LLComboBox* comboAlphaMode = self->getChild<LLComboBox>("combobox alphamode"); + if (!comboAlphaMode) + { + return; + } + U32 alpha_value = comboAlphaMode->getCurrentIndex(); + bool show_alphactrls = (alpha_value == ALPHAMODE_MASK); // Alpha masking + + LLComboBox* combobox_matmedia = self->getChild<LLComboBox>("combobox matmedia"); + U32 mat_media = MATMEDIA_MATERIAL; + if (combobox_matmedia) + { + mat_media = combobox_matmedia->getCurrentIndex(); + } + + LLComboBox* combobox_mattype = self->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); + + self->getChildView("label maskcutoff")->setVisible(show_alphactrls); + self->getChildView("maskcutoff")->setVisible(show_alphactrls); +} + +// static +void LLPanelFace::onCommitAlphaMode(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + updateAlphaControls(ctrl,userdata); + self->updateMaterial(); } // static @@ -1063,6 +2304,58 @@ void LLPanelFace::onSelectTexture(const LLSD& data) sendTexture(); } +void LLPanelFace::onCommitSpecularTexture( const LLSD& data ) +{ + LL_DEBUGS("Materials") << data << LL_ENDL; + LLComboBox* combo_shiny = getChild<LLComboBox>("combobox shininess"); + updateShinyControls(combo_shiny,this, true, true); + updateMaterial(); +} + +void LLPanelFace::onCommitNormalTexture( const LLSD& data ) +{ + LL_DEBUGS("Materials") << data << LL_ENDL; + LLComboBox* combo_bumpy = getChild<LLComboBox>("combobox bumpiness"); + updateBumpyControls(combo_bumpy, this, true, true); + updateMaterial(); +} + +void LLPanelFace::onCancelSpecularTexture(const LLSD& data) +{ + updateMaterial(); + LLComboBox* combo_shiny = getChild<LLComboBox>("combobox shininess"); + updateShinyControls(combo_shiny,this, false, true); +} + +void LLPanelFace::onCancelNormalTexture(const LLSD& data) +{ + updateMaterial(); + LLComboBox* combo_bumpy = getChild<LLComboBox>("combobox bumpiness"); + updateBumpyControls(combo_bumpy,this, false, true); +} + +void LLPanelFace::onSelectSpecularTexture(const LLSD& data) +{ + LL_DEBUGS("Materials") << data << LL_ENDL; + updateMaterial(); + LLComboBox* combo_shiny = getChild<LLComboBox>("combobox shininess"); + updateShinyControls(combo_shiny,this, true, true); +} + +void LLPanelFace::onSelectNormalTexture(const LLSD& data) +{ + LL_DEBUGS("Materials") << data << LL_ENDL; + LLComboBox* combo_bumpy = getChild<LLComboBox>("combobox bumpiness"); + updateBumpyControls(combo_bumpy,this, true, true); + updateMaterial(); +} + +//static +void LLPanelFace::onCommitMaterial(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + self->updateMaterial(); +} // static void LLPanelFace::onCommitTextureInfo( LLUICtrl* ctrl, void* userdata ) @@ -1073,7 +2366,7 @@ 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; @@ -1081,7 +2374,73 @@ void LLPanelFace::onClickApply(void* userdata) //F32 repeats_per_meter = self->mCtrlRepeatsPerMeter->get(); F32 repeats_per_meter = (F32)self->getChild<LLUICtrl>("rptctrl")->getValue().asReal();//self->mCtrlRepeatsPerMeter->get(); - LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter ); + + LLComboBox* combo_mattype = self->getChild<LLComboBox>("combobox mattype"); + + F32 obj_scale_s = 1.0f; + F32 obj_scale_t = 1.0f; + + U32 material_type = combo_mattype->getCurrentIndex(); + + struct f_objscale_s : 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; + + struct f_objscale_t : 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; + + LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_s_func, obj_scale_s ); + LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_t_func, obj_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); + self->updateMaterial(); + } + 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); + self->updateMaterial(); + } + break; + + default: + llassert(false); + break; + } } struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor @@ -1155,7 +2514,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 +2563,4 @@ void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp) } } } + diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 3b5a9b1398..7fbeef223b 100755 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -29,6 +29,7 @@ #include "v4color.h" #include "llpanel.h" +#include "llmaterial.h" class LLButton; class LLCheckBoxCtrl; @@ -42,6 +43,7 @@ class LLTextureCtrl; class LLUICtrl; class LLViewerObject; class LLFloater; +class LLMaterialID; class LLPanelFace : public LLPanel { @@ -74,20 +76,36 @@ 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); + void onMaterialLoaded(const LLMaterialID& material_id, const LLMaterialPtr material); + void updateMaterial(); static void onCommitTextureInfo( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterial( 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 updateShinyControls( LLUICtrl* ctrl, void* userdata, bool is_setting_texture = false, bool mess_with_combobox = false); + static void updateBumpyControls( LLUICtrl* ctrl, void* userdata, bool is_setting_texture = false, bool mess_with_combobox = false); static void onCommitShiny( LLUICtrl* ctrl, void* userdata); + static void updateAlphaControls( 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 onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo); static void onClickAutoFix(void*); static F32 valueGlow(LLViewerObject* object, S32 face); @@ -100,6 +118,23 @@ private: */ void onTextureSelectionChanged(LLInventoryItem* itemp); + LLMaterialID mMaterialID; + LLMaterialPtr mMaterial; + 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; }; #endif + diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 4681efd3e5..5a65623b91 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 @@ -2004,6 +2004,70 @@ void LLSelectMgr::selectionSetGlow(F32 glow) mSelectedObjects->applyToObjects( &func2 ); } +void LLSelectMgr::selectionSetMaterial(LLMaterialPtr material) +{ + struct f1 : public LLSelectedTEFunctor + { + LLMaterialPtr mMaterial; + f1(LLMaterialPtr material) : mMaterial(material) {}; + bool apply(LLViewerObject* object, S32 face) + { + if (object->permModify()) + { + LL_DEBUGS("Materials") << "Putting material on object " << object->getID() << " face " << face << ", material: " << mMaterial->asLLSD() << LL_ENDL; + LLMaterialMgr::getInstance()->put(object->getID(),face,*mMaterial); + object->setTEMaterialParams(face,mMaterial); + } + return true; + } + } func1(material); + 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->setTEMaterialID(face,LLMaterialID::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() diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index cc78e35869..1991b5581b 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; @@ -121,6 +123,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 { @@ -540,6 +544,8 @@ public: void selectionSetClickAction(U8 action); void selectionSetIncludeInSearch(bool include_in_search); void selectionSetGlow(const F32 glow); + void selectionSetMaterial(LLMaterialPtr material); + void selectionRemoveMaterial(); void selectionSetObjectPermissions(U8 perm_field, BOOL set, U32 perm_mask, BOOL override = FALSE); void selectionSetObjectName(const std::string& name); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index f85e855fd3..252f129133 100755 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -4632,7 +4632,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 b1706d9d35..bf32440848 100755 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -119,6 +119,17 @@ public: LL_ALIGN_16(LLFace* mFace); //associated face F32 mDistance; U32 mDrawMode; + LLMaterialPtr mMaterial; // If this is null, the following parameters are unused. + 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 { @@ -169,7 +180,7 @@ public: } }; - + struct CompareBump { bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs) @@ -739,7 +750,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/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.h b/indra/newview/lltexturecache.h index e3fc957fd2..deaacc4975 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.h b/indra/newview/lltexturectrl.h index 599d9c70c5..3fd024082e 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; } diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index aaa81c57d4..aaa81c57d4 100755..100644 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h index e4581d2120..e4581d2120 100755..100644 --- a/indra/newview/llviewerassetstats.h +++ b/indra/newview/llviewerassetstats.h diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index cf59e67955..37c579bdf5 100755 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -98,6 +98,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; @@ -340,6 +341,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) return; } + + if (gShaderProfileFrame) + { + LLGLSLShader::initProfile(); + } + //LLGLState::verify(FALSE); ///////////////////////////////////////////////// @@ -1018,6 +1025,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() @@ -1037,6 +1050,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)); @@ -1085,6 +1099,7 @@ void render_hud_attachments() 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); @@ -1109,6 +1124,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/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index beca08203f..5a27bdca90 100755 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -147,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; @@ -291,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*); @@ -1189,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 // @@ -6920,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"); @@ -7022,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"); @@ -8442,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"); @@ -8460,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"); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 670272e7be..96e701a6cb 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3927,25 +3927,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 { @@ -4024,12 +4038,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(); + + 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) @@ -4064,6 +4084,63 @@ 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); + } + + setChanged(TEXTURE); + if (mDrawable.notNull()) + { + gPipeline.markTextured(mDrawable); + } + } + mTENormalMaps[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); + } + setChanged(TEXTURE); + if (mDrawable.notNull()) + { + gPipeline.markTextured(mDrawable); + } + } + mTESpecularMaps[te] = image; + return retval; +} + //virtual void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image) { @@ -4074,6 +4151,24 @@ 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 ; +} + +void LLViewerObject::changeTESpecularMap(S32 index, LLViewerTexture* new_image) +{ + if(index < 0 || index >= getNumTEs()) + { + return ; + } + mTESpecularMaps[index] = new_image ; +} + S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid) { // Invalid host == get from the agent's sim @@ -4082,6 +4177,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) { @@ -4242,6 +4350,59 @@ 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); + setChanged(TEXTURE); + if (mDrawable.notNull() && retval) + { + gPipeline.markTextured(mDrawable); + } + } + 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; + } + else if (pMaterialParams != tep->getMaterialParams()) + { + retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams); + LL_DEBUGS("Material") << "Changing material params for te " << (S32)te + << ", object " << mID + << " (" << retval << ")" + << LL_ENDL; + setTENormalMap(te, tep->getMaterialParams()->getNormalID()); + setTESpecularMap(te, tep->getMaterialParams()->getSpecularID()); + setChanged(TEXTURE); + if (mDrawable.notNull() && retval) + { + gPipeline.markTextured(mDrawable); + } + } + return retval; +} + S32 LLViewerObject::setTEScale(const U8 te, const F32 s, const F32 t) { @@ -4343,6 +4504,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 316dbce7d0..ba23ad97b0 100755 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -301,7 +301,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); - S32 setTETextureCore(const U8 te, LLViewerTexture *image); + /*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); @@ -318,10 +322,16 @@ 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); /*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 @@ -596,6 +606,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/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index b8b53aa6e4..755462b0c2 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1617,6 +1617,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"); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index ba9818946c..fce06b9e13 100755 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -200,6 +200,7 @@ LLGLSLShader gDeferredEmissiveProgram; LLGLSLShader gDeferredPostProgram; LLGLSLShader gDeferredCoFProgram; LLGLSLShader gDeferredDoFCombineProgram; +LLGLSLShader gDeferredPostGammaCorrectProgram; LLGLSLShader gFXAAProgram; LLGLSLShader gDeferredPostNoDoFProgram; LLGLSLShader gDeferredWLSkyProgram; @@ -207,6 +208,9 @@ LLGLSLShader gDeferredWLCloudProgram; LLGLSLShader gDeferredStarProgram; LLGLSLShader gNormalMapGenProgram; +// Deferred materials shaders +LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; + LLViewerShaderMgr::LLViewerShaderMgr() : mVertexShaderLevel(SHADER_COUNT, 0), mMaxAvatarShaderLevel(0) @@ -271,6 +275,14 @@ 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); @@ -780,9 +792,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 @@ -793,7 +802,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) @@ -801,6 +809,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); @@ -826,12 +842,14 @@ BOOL LLViewerShaderMgr::loadBasicShaders() shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) ); } 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; } @@ -879,11 +897,11 @@ BOOL LLViewerShaderMgr::loadBasicShaders() index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); - + 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; } @@ -1097,12 +1115,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredPostProgram.unload(); gDeferredCoFProgram.unload(); gDeferredDoFCombineProgram.unload(); + gDeferredPostGammaCorrectProgram.unload(); gFXAAProgram.unload(); gDeferredWaterProgram.unload(); gDeferredWLSkyProgram.unload(); gDeferredWLCloudProgram.unload(); gDeferredStarProgram.unload(); gNormalMapGenProgram.unload(); + for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i) + { + gDeferredMaterialProgram[i].unload(); + } return TRUE; } @@ -1196,10 +1219,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 @@ -1216,7 +1242,64 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredBumpProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; 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"); + + #if LL_DARWIN + // include spec exp clamp to fix older mac rendering artifacts + // + if (gGLManager.mIsMobileGF) + { + gDeferredMaterialProgram[i].addPermutation("UGLY_MAC_HACK","1"); + } + #endif + + 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"; @@ -1346,8 +1429,10 @@ 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]; - success = gDeferredAlphaProgram.createShader(NULL, NULL); // Hack @@ -1435,6 +1520,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); } @@ -1444,6 +1530,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); } @@ -1455,6 +1542,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); } @@ -1466,6 +1554,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); } @@ -1477,6 +1566,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); } @@ -1515,8 +1605,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); @@ -1524,6 +1617,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true; gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true; } + + 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) { diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index e3d28f2f5c..5ef5d2234c 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 { @@ -349,6 +350,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; @@ -361,4 +363,7 @@ extern LLGLSLShader gDeferredWLCloudProgram; extern LLGLSLShader gDeferredStarProgram; extern LLGLSLShader gNormalMapGenProgram; +// Deferred materials shaders +extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; + #endif diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp index f9a725547f..f5a4737c59 100755 --- a/indra/newview/llviewerstatsrecorder.cpp +++ b/indra/newview/llviewerstatsrecorder.cpp @@ -254,10 +254,10 @@ void LLViewerStatsRecorder::writeToLog( F32 interval ) << "\t" << (mTextureFetchSize * 8 / delta_time) << "\n"; - data_size = data_msg.str().size(); - if (fwrite(data_msg.str().c_str(), 1, data_size, mObjectCacheFile ) != data_size) + size_t data_size = data_msg.str().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/llviewertexlayer.cpp b/indra/newview/llviewertexlayer.cpp index 777e1f9c76..777e1f9c76 100755..100644 --- a/indra/newview/llviewertexlayer.cpp +++ b/indra/newview/llviewertexlayer.cpp diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index eb6c453e76..8c1c203bd1 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" @@ -73,6 +71,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"); @@ -98,7 +97,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; @@ -425,6 +423,7 @@ void LLViewerTextureManager::cleanup() LLViewerFetchedTexture::sSmokeImagep = NULL; LLViewerFetchedTexture::sMissingAssetImagep = NULL; LLViewerFetchedTexture::sWhiteImagep = NULL; + LLViewerFetchedTexture::sFlatNormalImagep = NULL; LLViewerMediaTexture::cleanUpClass() ; } @@ -565,8 +564,7 @@ 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(); sCameraMovingBias = llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1); @@ -632,9 +630,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(); } @@ -646,7 +649,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(); } @@ -762,38 +767,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]; } @@ -816,6 +840,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) ; } @@ -837,18 +863,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 ; + return; } - if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME) + for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) { - return ; + 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() @@ -1194,9 +1224,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) { - mFaceList[i]->dirtyTexture() ; + llassert(mNumFaces[j] <= mFaceList[j].size()); + + for(U32 i = 0 ; i < mNumFaces[j]; i++) + { + mFaceList[j][i]->dirtyTexture() ; + } } //discard the cached raw image and the saved raw image @@ -1340,11 +1375,8 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/) return FALSE; } - if(!(res = insertToAtlas())) - { - res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel); - resetFaceAtlas() ; - } + res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel); + setActive() ; if (!needsToSaveRawImage()) @@ -1633,28 +1665,32 @@ void LLViewerFetchedTexture::updateVirtualSize() addTextureStats(0.f, FALSE) ;//reset } - for(U32 i = 0 ; i < mNumFaces ; i++) - { - LLFace* facep = mFaceList[i] ; - if( facep ) - { - LLDrawable* drawable = facep->getDrawable(); - if (drawable) + for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) + { + llassert(mNumFaces[ch] <= mFaceList[ch].size()); + + for(U32 i = 0 ; i < mNumFaces[ch]; i++) + { + LLFace* facep = mFaceList[ch][i] ; + if( facep ) { - if(drawable->isRecentlyVisible()) + LLDrawable* drawable = facep->getDrawable(); + if (drawable) { - if (getBoostLevel() == LLViewerTexture::BOOST_NONE && - drawable->getVObj() && drawable->getVObj()->isSelected()) + if(drawable->isRecentlyVisible()) { - setBoostLevel(LLViewerTexture::BOOST_SELECTED); + if (getBoostLevel() == LLViewerTexture::BOOST_NONE && + drawable->getVObj() && drawable->getVObj()->isSelected()) + { + setBoostLevel(LLViewerTexture::BOOST_SELECTED); + } + addTextureStats(facep->getVirtualSize()) ; + setAdditionalDecodePriority(facep->getImportanceToCamera()) ; } - addTextureStats(facep->getVirtualSize()) ; - setAdditionalDecodePriority(facep->getImportanceToCamera()) ; } } } } - //reset whether or not a face was selected after 10 seconds const F32 SELECTION_RESET_TIME = 10.f; @@ -2739,190 +2775,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 @@ -3269,11 +3121,14 @@ 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 i = 0 ; i < end ; i++) + for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) { - mMediaFaceList.push_back((*face_list)[i]) ; + 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]) ; + } } } @@ -3338,7 +3193,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) @@ -3355,19 +3210,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()) @@ -3394,9 +3249,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()) @@ -3414,24 +3269,35 @@ void LLViewerMediaTexture::removeFace(LLFace* facep) } } - // - //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) + std::vector<const LLTextureEntry*> te_list; + + for (U32 ch = 0; ch < 3; ++ch) { - mTextureList.clear() ; - return ; + // + //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. + + 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. + } } - S32 end = getNumFaces() ; - std::vector<const LLTextureEntry*> te_list(end) ; - S32 i = 0 ; - for(U32 j = 0 ; j < mNumFaces ; j++) + + if (te_list.empty()) { - te_list[i++] = mFaceList[j]->getTextureEntry() ;//all textures are in use. + mTextureList.clear() ; + return ; } + + 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. @@ -3476,7 +3342,7 @@ void LLViewerMediaTexture::stopPlaying() mIsPlaying = FALSE ; } -void LLViewerMediaTexture::switchTexture(LLFace* facep) +void LLViewerMediaTexture::switchTexture(U32 ch, LLFace* facep) { if(facep) { @@ -3492,7 +3358,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. { @@ -3508,7 +3374,7 @@ void LLViewerMediaTexture::switchTexture(LLFace* facep) { tex = LLViewerFetchedTexture::sDefaultImagep ; } - facep->switchTexture(tex) ; + facep->switchTexture(ch, tex) ; } } } @@ -3547,14 +3413,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 ; @@ -3576,14 +3445,18 @@ 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] ; - if(facep->getDrawable()->isRecentlyVisible()) + llassert(mNumFaces[ch] <= mFaceList[ch].size()); + for(U32 i = 0 ; i < mNumFaces[ch] ; i++) { - addTextureStats(facep->getVirtualSize()) ; - } - } + LLFace* facep = mFaceList[ch][i] ; + if(facep->getDrawable()->isRecentlyVisible()) + { + addTextureStats(facep->getVirtualSize()) ; + } + } + } } else //media is not in playing { diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index f2e1a90713..d6805a7240 100755 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -34,6 +34,7 @@ #include "llgltypes.h" #include "llrender.h" #include "llmetricperformancetester.h" +#include "llface.h" #include <map> #include <list> @@ -41,7 +42,6 @@ #define MIN_VIDEO_RAM_IN_MEGA_BYTES 32 #define MAX_VIDEO_RAM_IN_MEGA_BYTES 512 // 512MB max for performance reasons. -class LLFace; class LLImageGL ; class LLImageRaw; class LLViewerObject; @@ -98,7 +98,6 @@ public: DYNAMIC_TEXTURE, FETCHED_TEXTURE, LOD_TEXTURE, - ATLAS_TEXTURE, INVALID_TEXTURE_TYPE }; @@ -142,10 +141,11 @@ public: /*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); @@ -182,8 +182,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; @@ -214,8 +214,7 @@ public: static S32 sMaxSmallImageSize ; static BOOL sFreezeImageScalingDown ;//do not scale down image res if set. static F32 sCurrentTime ; - static BOOL sUseTextureAtlas ; - + enum EDebugTexels { DEBUG_TEXELS_OFF, @@ -406,11 +405,6 @@ private: void saveRawImage() ; void setCachedRawImage() ; - //for atlas - void resetFaceAtlas() ; - void invalidateAtlas(BOOL rebuild_geom) ; - BOOL insertToAtlas() ; - private: BOOL mFullyLoaded; BOOL mInDebug; @@ -496,6 +490,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 }; // @@ -553,12 +548,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 d2af48f528..48134869c9 100755 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -119,6 +119,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 diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 06fb23b84b..d19cdd9e4c 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1908,6 +1908,8 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid) LLViewerFetchedTexture *image = getBakedTextureImage(te,uuid); llassert(image); return setTETextureCore(te, image); + llassert(image); + return setTETextureCore(te, image); } static LLFastTimer::DeclareTimer FTM_AVATAR_UPDATE("Avatar Update"); @@ -3989,7 +3991,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass) gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } } - + return num_indices; } @@ -5843,6 +5845,8 @@ BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const + + // virtual void LLVOAvatar::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_result ) { @@ -6476,6 +6480,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) { @@ -7383,6 +7388,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"); @@ -7448,19 +7457,17 @@ 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 ) { - // MULTIPLE_WEARABLES: extend to multiple wearables? - LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); - if( te_image ) - { - std::string uuid_str; - te_image->getID().toString( uuid_str ); - apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str()); - } + std::string uuid_str; + te_image->getID().toString( uuid_str ); + apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str()); } } - } + apr_file_printf( file, "\t</archetype>\n" ); apr_file_printf( file, "\n</linden_genepool>\n" ); diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 0b34bbb90f..65711d2339 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_BINORMAL | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, GL_STREAM_DRAW_ARB); U32 count = LL_MAX_PARTICLE_COUNT; sVB->allocateBuffer(count*4, count*6, true); diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 145a0380d6..a1b36e3c8d 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()) diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h index 52debc85ab..2a7eb21238 100755 --- a/indra/newview/llvotree.h +++ b/indra/newview/llvotree.h @@ -104,10 +104,7 @@ public: F32 twist, F32 droop, F32 branches, - 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); - + F32 alpha); /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face = -1, // which face to check, -1 = ALL_SIDES diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 8730ef66bb..941892a597 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,37 +556,9 @@ 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)); - } - + 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; quat.setQuat(rot, 0, 0, -1.f); @@ -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); } @@ -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,49 @@ S32 LLVOVolume::setTEGlow(const U8 te, const F32 glow) return res; } +void LLVOVolume::setTEMaterialParamsCallback(const LLMaterialID &pMaterialID, const LLMaterialPtr pMaterialParams) +{ + LL_DEBUGS("MaterialTEs") << "materialid " << pMaterialID.asString() << LL_ENDL; + for (U8 i = 0; i < getNumTEs(); i++) + { + if (getTE(i) && (getTE(i)->getMaterialID().isNull() || (getTE(i)->getMaterialID() == pMaterialID))) + { + setTEMaterialParams(i, 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; + if (res) + { + LL_DEBUGS("MaterialTEs") << " " << pMaterialID.asString() << LL_ENDL; + LLMaterialMgr::instance().get(getRegion()->getRegionID(), pMaterialID, boost::bind(&LLVOVolume::setTEMaterialParamsCallback, this, _1, _2)); + gPipeline.markTextured(mDrawable); + 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->asLLSD() << " res " << res + << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" ) + << LL_ENDL; + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + + return res; +} + S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t) { S32 res = LLViewerObject::setTEScale(te, s, t); @@ -3976,6 +4004,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,7 +4027,11 @@ 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_BINORMAL)) + { + LL_WARNS("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL; + } + if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects) { return; @@ -4007,6 +4044,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, BOOL fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) || (type == LLRenderPass::PASS_INVISIBLE) || + (type == LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK) || (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)); if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_NORMAL)) @@ -4045,12 +4083,33 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LLViewerTexture* tex = facep->getTexture(); U8 index = facep->getTextureIndex(); + + LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get(); 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()) { @@ -4079,13 +4138,15 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_vec[idx]->mFullbright == fullbright && draw_vec[idx]->mBump == bump && draw_vec[idx]->mTextureMatrix == tex_mat && - draw_vec[idx]->mModelMatrix == model_mat) + draw_vec[idx]->mModelMatrix == model_mat && + draw_vec[idx]->mMaterial == 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; @@ -4101,12 +4162,62 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 offset = facep->getIndicesStart(); U32 count = facep->getIndicesCount(); LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset, tex, - facep->getVertexBuffer(), fullbright, bump); + facep->getVertexBuffer(), fullbright, bump); draw_info->mGroup = group; draw_info->mVSize = facep->getVirtualSize(); draw_vec.push_back(draw_info); draw_info->mTextureMatrix = tex_mat; draw_info->mModelMatrix = model_mat; + + U8 shiny = facep->getTextureEntry()->getShiny(); + 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; + + if (mat) + { + // We have a material. Update our draw info accordingly. + draw_info->mMaterial = mat; + draw_info->mShaderMask = shader_mask; + + 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); @@ -4223,6 +4334,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; @@ -4262,7 +4376,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } if (vobj->isMesh() && - (vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled())) + ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled())) { continue; } @@ -4389,66 +4503,96 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) LLViewerTexture* tex = facep->getTexture(); U32 type = gPipeline.getPoolTypeFromTE(te, tex); - if (type == LLDrawPool::POOL_ALPHA) + + if (te->getGlow()) { - if (te->getColor().mV[3] > 0.f) + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW); + } + + LLMaterial* mat = LLPipeline::sRenderDeferred ? te->getMaterialParams().get() : NULL; + + if (mat) + { + if (te->getFullbright()) { - if (te->getFullbright()) + if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) { pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); } - else + else if (type == LLDrawPool::POOL_ALPHA) { pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); + } + } + else + { + U32 mask = mat->getShaderMask(); + pool->addRiggedFace(facep, mask); } } - else if (te->getShiny()) + else { - if (te->getFullbright()) + if (type == LLDrawPool::POOL_ALPHA) { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY); + if (te->getColor().mV[3] > 0.f) + { + if (te->getFullbright()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); + } + } } - else + else if (te->getShiny()) { - if (LLPipeline::sRenderDeferred) + if (te->getFullbright()) { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY); } else { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY); + if (LLPipeline::sRenderDeferred) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY); + } } } - } - else - { - if (te->getFullbright()) - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); - } else { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); - } - } - - if (te->getGlow()) - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW); - } - - if (LLPipeline::sRenderDeferred) - { - if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright()) - { - if (te->getBumpmap()) + if (te->getFullbright()) { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP); + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); } else { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE); + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); + } + } + + + if (LLPipeline::sRenderDeferred) + { + if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright()) + { + if (te->getBumpmap()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE); + } } } } @@ -4558,7 +4702,30 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (gPipeline.canUseWindLightShadersOnObjects() && LLPipeline::sRenderBump) { - if (te->getBumpmap()) + if (LLPipeline::sRenderDeferred && te->getMaterialParams().notNull()) + { + LLMaterial* mat = te->getMaterialParams().get(); + if (mat->getNormalID().notNull()) + { + if (mat->getSpecularID().notNull()) + { //has normal and specular maps (needs texcoord1, texcoord2, and binormal) + normspec_faces.push_back(facep); + } + else + { //has normal map (needs texcoord1 and binormal) + 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 + binormal bump_faces.push_back(facep); } @@ -4616,32 +4783,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_BINORMAL; + 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_BINORMAL; + simple_mask = simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX; + alpha_mask = alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_BINORMAL | 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) { @@ -4793,11 +4966,14 @@ struct CompareBatchBreakerModified { return lte->getFullbright() < rte->getFullbright(); } + else if (LLPipeline::sRenderDeferred && lte->getMaterialParams() != rte->getMaterialParams()) + { + return lte->getMaterialParams() < rte->getMaterialParams(); + } else { return lhs->getTexture() < rhs->getTexture(); } - } }; @@ -4811,7 +4987,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); @@ -4881,6 +5057,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) { @@ -4926,6 +5103,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; } @@ -4976,13 +5154,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; @@ -5068,8 +5253,7 @@ 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; @@ -5089,7 +5273,73 @@ 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; + } + + if (mat && LLPipeline::sRenderDeferred && !hud_group) + { + if (fullbright) + { + if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + { + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); + } + else if (is_alpha) + { + registerFace(group, facep, LLRenderPass::PASS_ALPHA); + } + 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 + { + 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 (is_alpha) { // can we safely treat this as an alpha mask? if (facep->getFaceColor().mV[3] <= 0.f) @@ -5114,7 +5364,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 @@ -5131,7 +5382,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: registerFace(group, facep, LLRenderPass::PASS_POST_BUMP); } } - else if (te->getBumpmap()) + else if (te->getBumpmap() && !te->getMaterialParams()) { //register in deferred bump pass registerFace(group, facep, LLRenderPass::PASS_BUMP); } @@ -5158,7 +5409,14 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } else if (fullbright || bake_sunlight) { //fullbright - registerFace(group, facep, LLRenderPass::PASS_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 this is the deferred render and a bump map is present, register in post deferred bump registerFace(group, facep, LLRenderPass::PASS_POST_BUMP); @@ -5166,14 +5424,21 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } else { - if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && te->getBumpmap()) + if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && (te->getBumpmap() && !te->getMaterialParams())) { //non-shiny or fullbright deferred bump registerFace(group, facep, LLRenderPass::PASS_BUMP); } else { //all around simple llassert(mask & LLVertexBuffer::MAP_NORMAL); - registerFace(group, facep, LLRenderPass::PASS_SIMPLE); + 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); + } } } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 5482c80f2b..d1bfefdc70 100755 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -37,6 +37,7 @@ class LLViewerTextureAnim; class LLDrawPool; +class LLMaterialID; class LLSelectNode; class LLObjectMediaDataClient; class LLObjectMediaNavigateClient; @@ -185,6 +186,9 @@ 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); + void setTEMaterialParamsCallback(const LLMaterialID& pMaterialID, const LLMaterialPtr pMaterialParams); + /*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); diff --git a/indra/newview/llwlparamset.cpp b/indra/newview/llwlparamset.cpp index b04d30db55..0b5e0235ee 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) + { + 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 793becf0c8..7996f8a640 100755 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -274,7 +274,9 @@ void LLWorld::removeRegion(const LLHost &host) mActiveRegionList.remove(regionp); mCulledRegionList.remove(regionp); mVisibleRegionList.remove(regionp); - + + mRegionRemovedSignal(regionp); + delete regionp; updateWaterObjects(); @@ -402,6 +404,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) { @@ -1244,6 +1259,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 f350009d10..d0b001ba44 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); @@ -149,6 +150,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. @@ -168,6 +172,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 f320f34f6e..49ea4830d3 100755 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -233,6 +233,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"); @@ -262,6 +263,7 @@ std::string gPoolNames[] = "POOL_GROUND", "POOL_FULLBRIGHT", "POOL_BUMP", + "POOL_MATERIALS", "POOL_TERRAIN," "POOL_SKY", "POOL_WL_SKY", @@ -377,6 +379,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; @@ -398,8 +401,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() : @@ -489,6 +492,7 @@ void LLPipeline::init() getPool(LLDrawPool::POOL_FULLBRIGHT); getPool(LLDrawPool::POOL_INVISIBLE); getPool(LLDrawPool::POOL_BUMP); + getPool(LLDrawPool::POOL_MATERIALS); getPool(LLDrawPool::POOL_GLOW); LLViewerStats::getInstance()->mTrianglesDrawnStat.reset(); @@ -917,11 +921,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; @@ -1016,7 +1031,8 @@ void LLPipeline::updateRenderDeferred() { BOOL deferred = ((RenderDeferred && LLRenderTarget::sUseFBO && - LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && + LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && + LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && VertexShaderEnable && RenderAvatarVP && WindLightUseAtmosShaders) ? TRUE : FALSE) && @@ -1213,7 +1229,7 @@ void LLPipeline::createGLBuffers() for (U32 i = 0; i < 3; i++) { - mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE); + mGlow[i].allocate(512,glow_res, GL_RGBA,FALSE,FALSE); } allocateScreenBuffer(resX,resY); @@ -1264,13 +1280,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"); @@ -1306,11 +1327,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); @@ -1539,7 +1607,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; @@ -1603,19 +1673,40 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima return 0; } - bool alpha = te->getColor().mV[3] < 0.999f; + 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 && te->getMaterialParams()) + { + switch (te->getMaterialParams()->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()) && te->getMaterialID().isNull()) { return LLDrawPool::POOL_BUMP; + } else if (!te->getMaterialID().isNull() && !alpha) + { + return LLDrawPool::POOL_MATERIALS; } else { @@ -3584,8 +3675,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))) { @@ -5007,8 +5098,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(); } @@ -5390,7 +5481,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 ) { @@ -5399,7 +5500,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) } else { - mAlphaPool = new_poolp; + mAlphaPool = (LLDrawPoolAlpha*) new_poolp; } break; @@ -5530,7 +5631,12 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) llassert( poolp == mBumpPool ); mBumpPool = NULL; break; - + + case LLDrawPool::POOL_MATERIALS: + llassert(poolp == mMaterialsPool); + mMaterialsPool = NULL; + break; + case LLDrawPool::POOL_ALPHA: llassert( poolp == mAlphaPool ); mAlphaPool = NULL; @@ -6917,6 +7023,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; + mAlphaPool->pushMaskBatches(type, mask, texture, batch_texture); + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; +} + + void apply_cube_face_rotation(U32 face) { switch (face) @@ -7018,10 +7135,51 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) gGL.loadIdentity(); LLGLDisable test(GL_ALPHA_TEST); - + gGL.setColorMask(true, true); glClearColor(0,0,0,0); + + if (sRenderDeferred) + { + 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; + if (!LLViewerCamera::getInstance()->cameraUnderWater()) + { + 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(); + } + { { LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); @@ -7359,6 +7517,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) mScreen.bindTexture(0, channel); 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); @@ -7400,6 +7565,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]); @@ -7820,6 +7992,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"); @@ -8152,6 +8340,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); @@ -8208,6 +8400,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); @@ -8256,9 +8451,13 @@ void LLPipeline::renderDeferredLighting() fullscreen_lights.pop_front(); col[count] = light_colors.front(); light_colors.pop_front(); - + + col[count].mV[0] = powf(col[count].mV[0], 2.2f); + col[count].mV[1] = powf(col[count].mV[1], 2.2f); + col[count].mV[2] = powf(col[count].mV[2], 2.2f); + far_z = llmin(light[count].mV[2]-sqrtf(light[count].mV[3]), far_z); - + //col[count] = pow4fsrgb(col[count], 2.2f); count++; if (count == max_count || fullscreen_lights.empty()) { @@ -8300,6 +8499,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); @@ -8895,11 +9098,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(); @@ -8966,7 +9180,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 | @@ -8974,10 +9187,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); } @@ -9308,6 +9530,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); @@ -9827,7 +10065,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); } diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index a8db93585e..fbfb2d012f 100755 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -35,7 +35,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" @@ -59,6 +60,7 @@ class LLCullResult; class LLVOAvatar; class LLGLSLShader; class LLCurlRequest; +class LLDrawPoolAlpha; class LLMeshResponder; @@ -95,6 +97,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; @@ -256,6 +259,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); @@ -427,6 +432,7 @@ public: RENDER_TYPE_GRASS = LLDrawPool::POOL_GRASS, 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, @@ -447,6 +453,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, @@ -562,7 +584,8 @@ public: static BOOL sRenderDeferred; static BOOL sMemAllocationThrottled; static S32 sVisibleLightCount; - static F32 sMinRenderSize; + static F32 sMinRenderSize; + static BOOL sRenderingHUDs; //screen texture U32 mScreenWidth; @@ -773,7 +796,7 @@ 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; @@ -784,6 +807,7 @@ protected: 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 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..c4627f926b 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"/> 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_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml index 46ba4bd29d..46ba4bd29d 100755..100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml index 28e032ce5f..28e032ce5f 100755..100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml index e7c2b80da2..e7c2b80da2 100755..100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml index c1ff026a74..c1ff026a74 100755..100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index a11cd13fdb..500c11da74 100755 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2363,6 +2363,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" @@ -2658,6 +2664,12 @@ <menu_item_call.on_click function="Advanced.SelectedTextureInfo" /> </menu_item_call> + <menu_item_call + label="Selected Material Info" + name="Selected Material Info"> + <menu_item_call.on_click + function="Advanced.SelectedMaterialInfo" /> + </menu_item_call> <menu_item_check label="Wireframe" name="Wireframe" @@ -2684,8 +2696,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" /> @@ -2792,16 +2804,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/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..a5425062ec --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -0,0 +1,760 @@ +<?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" /> + <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" /> + <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="10" + 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="180" + min_val="-180" + 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="180" + min_val="-180" + 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 3b57ff5fd6..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> 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..23e8a98e8e 100755 --- a/indra/newview/skins/default/xui/ru/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ru/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="SSAO и сглаживание теней" name="SSAO and Shadow Smoothing"/> <menu_item_check label="Отладка GL" name="Debug GL"/> 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 a331d9aa9e..a331d9aa9e 100755..100644 --- a/indra/newview/tests/llviewerassetstats_test.cpp +++ b/indra/newview/tests/llviewerassetstats_test.cpp diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index bc473f6d62..2d3e67c8a4 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1040,9 +1040,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.*") |