diff options
Diffstat (limited to 'indra/newview')
72 files changed, 2803 insertions, 2913 deletions
| diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index a228920441..b03e20c456 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.4.9 +6.4.10 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index e39f6ffd4e..52dc4744f2 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -812,17 +812,6 @@        <key>Value</key>        <integer>0</integer>      </map> -    <key>FramePerSecondLimit</key> -    <map> -      <key>Comment</key> -      <string>Controls upper limit of frames per second</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>U32</string> -      <key>Value</key> -      <integer>120</integer> -    </map>      <key>BackgroundYieldTime</key>      <map>        <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl index caa4fe1f65..b7036e02cf 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl @@ -1,24 +1,24 @@ -/**  +/**   * @file WLCloudsV.glsl   *   * $LicenseInfo:firstyear=2005&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2005, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -33,26 +33,26 @@ ATTRIBUTE vec2 texcoord0;  ///////////////////////////////////////////////////////////////////////////////  // Output parameters -VARYING vec4 vary_CloudColorSun; -VARYING vec4 vary_CloudColorAmbient; +VARYING vec4  vary_CloudColorSun; +VARYING vec4  vary_CloudColorAmbient;  VARYING float vary_CloudDensity; -VARYING vec2 vary_texcoord0; -VARYING vec2 vary_texcoord1; -VARYING vec2 vary_texcoord2; -VARYING vec2 vary_texcoord3; +VARYING vec2  vary_texcoord0; +VARYING vec2  vary_texcoord1; +VARYING vec2  vary_texcoord2; +VARYING vec2  vary_texcoord3;  VARYING float altitude_blend_factor;  // Inputs  uniform vec3 camPosLocal; -uniform vec4 lightnorm; -uniform vec4 sunlight_color; -uniform vec4 moonlight_color; -uniform int sun_up_factor; -uniform vec4 ambient_color; -uniform vec4 blue_horizon; -uniform vec4 blue_density; +uniform vec4  lightnorm; +uniform vec4  sunlight_color; +uniform vec4  moonlight_color; +uniform int   sun_up_factor; +uniform vec4  ambient_color; +uniform vec4  blue_horizon; +uniform vec4  blue_density;  uniform float haze_horizon;  uniform float haze_density; @@ -60,7 +60,7 @@ uniform float cloud_shadow;  uniform float density_multiplier;  uniform float max_y; -uniform vec4 glow; +uniform vec4  glow;  uniform float sun_moon_glow_factor;  uniform vec4 cloud_color; @@ -70,133 +70,123 @@ uniform float cloud_scale;  // NOTE: Keep these in sync!  //       indra\newview\app_settings\shaders\class1\deferred\skyV.glsl  //       indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl +//       indra\newview\app-settings\shaders\class2\windlight\cloudsV.glsl  //       indra\newview\lllegacyatmospherics.cpp +//       indra\newview\llsettingsvo.cpp  void main()  { - -	// World / view / projection -	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); - -	// Texture coords -	vary_texcoord0 = texcoord0; -	vary_texcoord0.xy -= 0.5; -	vary_texcoord0.xy /= cloud_scale; -	vary_texcoord0.xy += 0.5; - -	vary_texcoord1 = vary_texcoord0; -	vary_texcoord1.x += lightnorm.x * 0.0125; -	vary_texcoord1.y += lightnorm.z * 0.0125; - -	vary_texcoord2 = vary_texcoord0 * 16.; -	vary_texcoord3 = vary_texcoord1 * 16.; - -	// Get relative position -	vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0); - -    altitude_blend_factor = clamp((P.y + 512.0) / max_y, 0.0, 1.0); - -	// Set altitude -	if (P.y > 0.) -	{ -		P *= (max_y / P.y); -	} -	else -	{ -		altitude_blend_factor = 0; // SL-11589 Fix clouds drooping below horizon -		P *= (-32000. / P.y); -	} - -	// Can normalize then -	vec3 Pn = normalize(P); -	float  Plen = length(P); - -	// Initialize temp variables -	vec4 temp1 = vec4(0.); -	vec4 temp2 = vec4(0.); -	vec4 blue_weight; -	vec4 haze_weight; -	//vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color; -	vec4 sunlight = sunlight_color; -	vec4 light_atten; - -    float dens_mul = density_multiplier; - -	// 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)) * (dens_mul * max_y); - -	// Calculate relative weights -	temp1 = abs(blue_density) + vec4(abs(haze_density)); -	blue_weight = blue_density / temp1; -	haze_weight = haze_density / temp1; - -	// Compute sunlight from P & lightnorm (for long rays like sky) -	temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y ); -	temp2.y = 1. / temp2.y; -	sunlight *= exp( - light_atten * temp2.y); - -	// Distance -	temp2.z = Plen * dens_mul; - -	// Transparency (-> temp1) -	// ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati -	// compiler gets confused. -	temp1 = exp(-temp1 * temp2.z); - - -	// Compute haze glow -	temp2.x = dot(Pn, lightnorm.xyz); -	temp2.x = 1. - temp2.x; -		// temp2.x is 0 at the sun and increases away from sun -	temp2.x = max(temp2.x, .001);	 -		// 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 - -    temp2.x *= sun_moon_glow_factor; - -	// Add "minimum anti-solar illumination" -	temp2.x += .25; - -	// Increase ambient when there are more clouds -	vec4 tmpAmbient = ambient_color; -	tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;  - -	// Dim sunlight by cloud shadow percentage -	sunlight *= (1. - cloud_shadow); - -	// Haze color below cloud -	vec4 additiveColorBelowCloud = (	  blue_horizon * blue_weight * (sunlight + tmpAmbient) -				+ (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient) -			 );	 - -	// CLOUDS -	temp2.y = max(0., lightnorm.y * 2.); -	temp2.y = 1. / temp2.y; -	sunlight *= exp( - light_atten * temp2.y); - -	// Cloud color out -	vary_CloudColorSun = (sunlight * temp2.x) * cloud_color; -	vary_CloudColorAmbient = tmpAmbient * cloud_color; -	 -	// Attenuate cloud color by atmosphere -	temp1 = sqrt(temp1);	//less atmos opacity (more transparency) below clouds -	vary_CloudColorSun *= temp1; -	vary_CloudColorAmbient *= temp1; -	vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - temp1); - -	// Make a nice cloud density based on the cloud_shadow value that was passed in. -	vary_CloudDensity = 2. * (cloud_shadow - 0.25); - - -	// Combine these to minimize register use -	vary_CloudColorAmbient += oHazeColorBelowCloud; - -	// needs this to compile on mac -	//vary_AtmosAttenuation = vec3(0.0,0.0,0.0); - -	// END CLOUDS +    // World / view / projection +    gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + +    // Texture coords +    // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll +    vary_texcoord0 = vec2(-texcoord0.x, texcoord0.y);  // See: LLSettingsVOSky::applySpecial + +    vary_texcoord0.xy -= 0.5; +    vary_texcoord0.xy /= cloud_scale; +    vary_texcoord0.xy += 0.5; + +    vary_texcoord1 = vary_texcoord0; +    vary_texcoord1.x += lightnorm.x * 0.0125; +    vary_texcoord1.y += lightnorm.z * 0.0125; + +    vary_texcoord2 = vary_texcoord0 * 16.; +    vary_texcoord3 = vary_texcoord1 * 16.; + +    // Get relative position +    vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0); + +    altitude_blend_factor = clamp((rel_pos.y + 512.0) / max_y, 0.0, 1.0); + +    // Set altitude +    if (rel_pos.y > 0) +    { +        rel_pos *= (max_y / rel_pos.y); +    } +    if (rel_pos.y < 0) +    { +        altitude_blend_factor = 0;  // SL-11589 Fix clouds drooping below horizon +        rel_pos *= (-32000. / rel_pos.y); +    } + +    // Can normalize then +    vec3  rel_pos_norm = normalize(rel_pos); +    float rel_pos_len  = length(rel_pos); + +    // Initialize temp variables +    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); + +    // Calculate relative weights +    vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density)); +    vec4 blue_weight   = blue_density / combined_haze; +    vec4 haze_weight   = haze_density / combined_haze; + +    // Compute sunlight from rel_pos & lightnorm (for long rays like sky) +    float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y); +    sunlight *= exp(-light_atten * off_axis); + +    // Distance +    float density_dist = rel_pos_len * density_multiplier; + +    // Transparency (-> combined_haze) +    // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati +    // compiler gets confused. +    combined_haze = exp(-combined_haze * density_dist); + +    // Compute haze glow +    float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz); +    // haze_glow is 0 at the sun and increases away from sun +    haze_glow = max(haze_glow, .001); +    // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) +    haze_glow *= glow.x; +    // Higher glow.x gives dimmer glow (because next step is 1 / "angle") +    haze_glow = pow(haze_glow, glow.z); +    // glow.z should be negative, so we're doing a sort of (1 / "angle") function + +    haze_glow *= sun_moon_glow_factor; + +    // Add "minimum anti-solar illumination" +    // For sun, add to glow.  For moon, remove glow entirely. SL-13768 +    haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25); + +    // Increase ambient when there are more clouds +    vec4 tmpAmbient = ambient_color; +    tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5; + +    // Dim sunlight by cloud shadow percentage +    sunlight *= (1. - cloud_shadow); + +    // Haze color below cloud +    vec4 additiveColorBelowCloud = +        (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient)); + +    // CLOUDS +    off_axis = 1.0 / max(1e-6, lightnorm.y * 2.); +    sunlight *= exp(-light_atten * off_axis); + +    // Cloud color out +    vary_CloudColorSun     = (sunlight * haze_glow) * cloud_color; +    vary_CloudColorAmbient = tmpAmbient * cloud_color; + +    // Attenuate cloud color by atmosphere +    combined_haze = sqrt(combined_haze);  // less atmos opacity (more transparency) below clouds +    vary_CloudColorSun *= combined_haze; +    vary_CloudColorAmbient *= combined_haze; +    vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - combined_haze); + +    // Make a nice cloud density based on the cloud_shadow value that was passed in. +    vary_CloudDensity = 2. * (cloud_shadow - 0.25); + +    // Combine these to minimize register use +    vary_CloudColorAmbient += oHazeColorBelowCloud; + +    // needs this to compile on mac +    // vary_AtmosAttenuation = vec3(0.0,0.0,0.0); + +    // END CLOUDS  } - diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl index bd0ad3bce8..6b36d00f97 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl @@ -42,6 +42,9 @@ VARYING vec4 vary_position;  uniform samplerCube environmentMap; +// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO; used in LLDrawPoolAlpha::beginRenderPass() +uniform int no_atmo; +  vec3 fullbrightShinyAtmosTransport(vec3 light);  vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);  vec3 fullbrightScaleSoftClip(vec3 light); @@ -51,7 +54,9 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou  vec3 linear_to_srgb(vec3 c);  vec3 srgb_to_linear(vec3 c); - +// See: +//   class1\deferred\fullbrightShinyF.glsl +//   class1\lighting\lightFullbrightShinyF.glsl  void main()  {  #ifdef HAS_DIFFUSE_LOOKUP @@ -59,25 +64,39 @@ void main()  #else  	vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);  #endif -	 +  	color.rgb *= vertex_color.rgb; -	vec3 pos = vary_position.xyz/vary_position.w; -	vec3 sunlit; -	vec3 amblit; -	vec3 additive; -	vec3 atten; +	// SL-9632 HUDs are affected by Atmosphere +	if (no_atmo == 0) +	{ +		vec3 sunlit; +		vec3 amblit; +		vec3 additive; +		vec3 atten; +		vec3 pos = vary_position.xyz/vary_position.w; + +		calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten, false); -	calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten, false); -	 -	vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;	 -	float env_intensity = vertex_color.a; -	color.rgb = mix(color.rgb, envColor.rgb, env_intensity); +		vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb; +		float env_intensity = vertex_color.a;  	//color.rgb = srgb_to_linear(color.rgb); -	 -	color.rgb = fullbrightAtmosTransportFrag(color.rgb, additive, atten); -	color.rgb = fullbrightScaleSoftClip(color.rgb); +		color.rgb = mix(color.rgb, envColor.rgb, env_intensity); + +		color.rgb = fullbrightAtmosTransportFrag(color.rgb, additive, atten); +		color.rgb = fullbrightScaleSoftClip(color.rgb); +	} + +/* +	// NOTE: HUD objects will be full bright. Uncomment if you want "some" environment lighting effecting these HUD objects. +	else +	{ +		vec3  envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb; +		float env_intensity = vertex_color.a; +		color.rgb = mix(color.rgb, envColor.rgb, env_intensity); +	} +*/  	color.a = 1.0; diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index 0afd1a9672..80d19102b6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -1,439 +1,443 @@ -/**
 -* @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$
 -*/
 -
 -/*[EXTRA_CODE_HERE]*/
 -
 -//class1/deferred/materialF.glsl
 -
 -// This shader is used for both writing opaque/masked content to the gbuffer and writing blended content to the framebuffer during the alpha pass.
 -
 -#define DIFFUSE_ALPHA_MODE_NONE     0
 -#define DIFFUSE_ALPHA_MODE_BLEND    1
 -#define DIFFUSE_ALPHA_MODE_MASK     2
 -#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
 -
 -uniform float emissive_brightness;  // fullbright flag, 1.0 == fullbright, 0.0 otherwise
 -uniform int sun_up_factor;
 -
 -#ifdef WATER_FOG
 -vec4 applyWaterFogView(vec3 pos, vec4 color);
 -#endif
 -
 -vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
 -vec3 scaleSoftClipFrag(vec3 l);
 -
 -vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
 -vec3 fullbrightScaleSoftClip(vec3 light);
 -
 -void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
 -
 -vec3 srgb_to_linear(vec3 cs);
 -vec3 linear_to_srgb(vec3 cs);
 -
 -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
 -
 -#ifdef DEFINE_GL_FRAGCOLOR
 -out vec4 frag_color;
 -#else
 -#define frag_color gl_FragColor
 -#endif
 -
 -#ifdef HAS_SUN_SHADOW
 -float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
 -#endif
 -
 -uniform samplerCube environmentMap;
 -uniform sampler2D     lightFunc;
 -
 -// Inputs
 -uniform vec4 morphFactor;
 -uniform vec3 camPosLocal;
 -uniform mat3 env_mat;
 -
 -uniform vec3 sun_dir;
 -uniform vec3 moon_dir;
 -VARYING vec2 vary_fragcoord;
 -
 -VARYING vec3 vary_position;
 -
 -uniform mat4 proj_mat;
 -uniform mat4 inv_proj;
 -uniform vec2 screen_res;
 -
 -uniform vec4 light_position[8];
 -uniform vec3 light_direction[8];
 -uniform vec4 light_attenuation[8];
 -uniform vec3 light_diffuse[8];
 -
 -float getAmbientClamp();
 -
 -vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare, float ambiance)
 -{
 -    vec3 col = vec3(0);
 -
 -    //get light vector
 -    vec3 lv = lp.xyz - v;
 -
 -    //get distance
 -    float dist = length(lv);
 -    float da = 1.0;
 -
 -    dist /= la;
 -
 -    if (dist > 0.0 && la > 0.0)
 -    {
 -        //normalize light vector
 -        lv = normalize(lv);
 -
 -        //distance attenuation
 -        float dist_atten = clamp(1.0 - (dist - 1.0*(1.0 - fa)) / fa, 0.0, 1.0);
 -        dist_atten *= dist_atten;
 -        dist_atten *= 2.0f;
 -
 -        if (dist_atten <= 0.0)
 -        {
 -            return col;
 -        }
 -
 -        // spotlight coefficient.
 -        float spot = max(dot(-ln, lv), is_pointlight);
 -        da *= spot*spot; // GL_SPOT_EXPONENT=2
 -
 -        //angular attenuation
 -        da *= dot(n, lv);
 -
 -        float lit = 0.0f;
 -
 -        float amb_da = ambiance;
 -        if (da >= 0)
 -        {
 -            lit = max(da * dist_atten, 0.0);
 -            col = lit * light_col * diffuse;
 -            amb_da += (da*0.5 + 0.5) * ambiance;
 -        }
 -        amb_da += (da*da*0.5 + 0.5) * ambiance;
 -        amb_da *= dist_atten;
 -        amb_da = min(amb_da, 1.0f - lit);
 -
 -        // SL-10969 need to see why these are blown out
 -        //col.rgb += amb_da * light_col * diffuse;
 -
 -        if (spec.a > 0.0)
 -        {
 -            //vec3 ref = dot(pos+lv, norm);
 -            vec3 h = normalize(lv + npos);
 -            float nh = dot(n, h);
 -            float nv = dot(n, npos);
 -            float vh = dot(npos, h);
 -            float sa = nh;
 -            float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5;
 -
 -            float gtdenom = 2 * nh;
 -            float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
 -
 -            if (nh > 0.0)
 -            {
 -                float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt / (nh*da);
 -                vec3 speccol = lit*scol*light_col.rgb*spec.rgb;
 -                speccol = clamp(speccol, vec3(0), vec3(1));
 -                col += speccol;
 -
 -                float cur_glare = max(speccol.r, speccol.g);
 -                cur_glare = max(cur_glare, speccol.b);
 -                glare = max(glare, speccol.r);
 -                glare += max(cur_glare, 0.0);
 -            }
 -        }
 -    }
 -
 -    return max(col, vec3(0.0, 0.0, 0.0));
 -}
 -
 -#else
 -#ifdef DEFINE_GL_FRAGCOLOR
 -out vec4 frag_data[3];
 -#else
 -#define frag_data gl_FragData
 -#endif
 -#endif
 -
 -uniform sampler2D diffuseMap;  //always in sRGB space
 -
 -#ifdef HAS_NORMAL_MAP
 -uniform sampler2D bumpMap;
 -#endif
 -
 -#ifdef HAS_SPECULAR_MAP
 -uniform sampler2D specularMap;
 -
 -VARYING vec2 vary_texcoord2;
 -#endif
 -
 -uniform float env_intensity;
 -uniform vec4 specular_color;  // specular color RGB and specular exponent (glossiness) in alpha
 -
 -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
 -uniform float minimum_alpha;
 -#endif
 -
 -#ifdef 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);
 -
 -void main()
 -{
 -    vec2 pos_screen = vary_texcoord0.xy;
 -
 -    vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
 -	diffcol.rgb *= vertex_color.rgb;
 -
 -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
 -
 -    // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points
 -    float bias = 0.001953125; // 1/512, or half an 8-bit quantization
 -    if (diffcol.a < minimum_alpha-bias)
 -    {
 -        discard;
 -    }
 -#endif
 -
 -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
 -	vec3 gamma_diff = diffcol.rgb;
 -	diffcol.rgb = srgb_to_linear(diffcol.rgb);
 -#endif
 -
 -#ifdef HAS_SPECULAR_MAP
 -    vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
 -    spec.rgb *= specular_color.rgb;
 -#else
 -    vec4 spec = vec4(specular_color.rgb, 1.0);
 -#endif
 -
 -#ifdef 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 = normalize(tnorm.xyz);
 -
 -    vec2 abnormal = encode_normal(norm.xyz);
 -
 -    vec4 final_color = diffcol;
 -
 -#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
 -	final_color.a = emissive_brightness;
 -#else
 -	final_color.a = max(final_color.a, emissive_brightness);
 -#endif
 -
 -    vec4 final_specular = spec;
 -    
 -#ifdef HAS_SPECULAR_MAP
 -    vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0);
 -	final_specular.a = specular_color.a * norm.a;
 -#else
 -	vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0);
 -	final_specular.a = specular_color.a;
 -#endif
 -
 -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
 -
 -    //forward rendering, output just lit sRGBA
 -    vec3 pos = vary_position;
 -
 -    float shadow = 1.0f;
 -
 -#ifdef HAS_SUN_SHADOW
 -    shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen);
 -#endif
 -
 -    spec = final_specular;
 -    vec4 diffuse = final_color;
 -    float envIntensity = final_normal.z;
 -
 -    vec3 color = vec3(0,0,0);
 -
 -    vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
 -
 -    float bloom = 0.0;
 -    vec3 sunlit;
 -    vec3 amblit;
 -    vec3 additive;
 -    vec3 atten;
 -
 -    calcAtmosphericVars(pos.xyz, light_dir, 1.0, sunlit, amblit, additive, atten, false);
 -    
 -        // This call breaks the Mac GLSL compiler/linker for unknown reasons (17Mar2020)
 -        // The call is either a no-op or a pure (pow) gamma adjustment, depending on GPU level
 -        // TODO: determine if we want to re-apply the gamma adjustment, and if so understand & fix Mac breakage
 -        //color = fullbrightScaleSoftClip(color);
 -
 -    vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
 -
 -    //we're in sRGB space, so gamma correct this dot product so 
 -    // lighting from the sun stays sharp
 -    float da = clamp(dot(normalize(norm.xyz), light_dir.xyz), 0.0, 1.0);
 -    da = pow(da, 1.0 / 1.3);
 -
 -    color = amblit;
 -
 -    //darken ambient for normals perpendicular to light vector so surfaces in shadow 
 -    // and facing away from light still have some definition to them.
 -    // do NOT gamma correct this dot product so ambient lighting stays soft
 -    float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
 -    ambient *= 0.5;
 -    ambient *= ambient;
 -    ambient = (1.0 - ambient);
 -
 -    vec3 sun_contrib = min(da, shadow) * sunlit;
 -    
 -    color *= ambient;
 -
 -    color += sun_contrib;
 -
 -    color *= gamma_diff.rgb;
 -
 -    float glare = 0.0;
 -
 -    if (spec.a > 0.0) // specular reflection
 -    {
 -#if 1 //EEP
 -
 -        vec3 npos = -normalize(pos.xyz);
 -
 -        //vec3 ref = dot(pos+lv, norm);
 -        vec3 h = normalize(light_dir.xyz + npos);
 -        float nh = dot(norm.xyz, h);
 -        float nv = dot(norm.xyz, npos);
 -        float vh = dot(npos, h);
 -        float sa = nh;
 -        float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5;
 -
 -        float gtdenom = 2 * nh;
 -        float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
 -
 -        if (nh > 0.0)
 -        {
 -            float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt / (nh*da);
 -            vec3 sp = sun_contrib*scol / 6.0f;
 -            sp = clamp(sp, vec3(0), vec3(1));
 -            bloom = dot(sp, sp) / 4.0;
 -            color += sp * spec.rgb;
 -        }
 -#else // PRODUCTION
 -        float sa = dot(refnormpersp, sun_dir.xyz);
 -		vec3 dumbshiny = sunlit*shadow*(texture2D(lightFunc, vec2(sa, spec.a)).r);
 -							
 -		// add the two types of shiny together
 -		vec3 spec_contrib = dumbshiny * spec.rgb;
 -		bloom = dot(spec_contrib, spec_contrib) / 6;
 -
 -		glare = max(spec_contrib.r, spec_contrib.g);
 -		glare = max(glare, spec_contrib.b);
 -
 -		color += spec_contrib;
 -#endif
 -    }
 -
 -    color = mix(color.rgb, diffcol.rgb, diffuse.a);
 -    
 -    if (envIntensity > 0.0)
 -    {
 -        //add environmentmap
 -        vec3 env_vec = env_mat * refnormpersp;
 -
 -        vec3 reflected_color = textureCube(environmentMap, env_vec).rgb;
 -
 -        color = mix(color, reflected_color, envIntensity);
 -
 -        float cur_glare = max(reflected_color.r, reflected_color.g);
 -        cur_glare = max(cur_glare, reflected_color.b);
 -        cur_glare *= envIntensity*4.0;
 -        glare += cur_glare;
 -    }
 -
 -    color = atmosFragLighting(color, additive, atten);
 -    color = scaleSoftClipFrag(color);
 -
 -    //convert to linear before adding local lights
 -    color = srgb_to_linear(color);
 -
 -    vec3 npos = normalize(-pos.xyz);
 -
 -    vec3 light = vec3(0, 0, 0);
 -    
 -#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare, light_attenuation[i].w );
 -
 -    LIGHT_LOOP(1)
 -        LIGHT_LOOP(2)
 -        LIGHT_LOOP(3)
 -        LIGHT_LOOP(4)
 -        LIGHT_LOOP(5)
 -        LIGHT_LOOP(6)
 -        LIGHT_LOOP(7)
 -
 -    color += light;
 -
 -    glare = min(glare, 1.0);
 -    float al = max(diffcol.a, glare)*vertex_color.a;
 -
 -    //convert to srgb as this color is being written post gamma correction
 -    color = linear_to_srgb(color);
 -
 -#ifdef WATER_FOG
 -    vec4 temp = applyWaterFogView(pos, vec4(color, al));
 -    color = temp.rgb;
 -    al = temp.a;
 -#endif
 -
 -    frag_color = vec4(color, al);
 -
 -#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer 
 -
 -    // deferred path
 -    frag_data[0] = final_color; //gbuffer is sRGB
 -    frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
 -    frag_data[2] = final_normal; // XY = Normal.  Z = Env. intensity.
 -#endif
 -}
 -
 +/** +* @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$ +*/ + +/*[EXTRA_CODE_HERE]*/ + +//class1/deferred/materialF.glsl + +// This shader is used for both writing opaque/masked content to the gbuffer and writing blended content to the framebuffer during the alpha pass. + +#define DIFFUSE_ALPHA_MODE_NONE     0 +#define DIFFUSE_ALPHA_MODE_BLEND    1 +#define DIFFUSE_ALPHA_MODE_MASK     2 +#define DIFFUSE_ALPHA_MODE_EMISSIVE 3 + +uniform float emissive_brightness;  // fullbright flag, 1.0 == fullbright, 0.0 otherwise +uniform int sun_up_factor; + +#ifdef WATER_FOG +vec4 applyWaterFogView(vec3 pos, vec4 color); +#endif + +vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten); +vec3 scaleSoftClipFrag(vec3 l); + +vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten); +vec3 fullbrightScaleSoftClip(vec3 light); + +void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao); + +vec3 srgb_to_linear(vec3 cs); +vec3 linear_to_srgb(vec3 cs); + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +#ifdef HAS_SUN_SHADOW +float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen); +#endif + +uniform samplerCube environmentMap; +uniform sampler2D     lightFunc; + +// Inputs +uniform vec4 morphFactor; +uniform vec3 camPosLocal; +uniform mat3 env_mat; + +uniform vec3 sun_dir; +uniform vec3 moon_dir; +VARYING vec2 vary_fragcoord; + +VARYING vec3 vary_position; + +uniform mat4 proj_mat; +uniform mat4 inv_proj; +uniform vec2 screen_res; + +uniform vec4 light_position[8]; +uniform vec3 light_direction[8]; +uniform vec4 light_attenuation[8]; +uniform vec3 light_diffuse[8]; + +float getAmbientClamp(); + +vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare, float ambiance) +{ +    vec3 col = vec3(0); + +    //get light vector +    vec3 lv = lp.xyz - v; + +    //get distance +    float dist = length(lv); +    float da = 1.0; + +    dist /= la; + +    if (dist > 0.0 && la > 0.0) +    { +        //normalize light vector +        lv = normalize(lv); + +        //distance attenuation +        float dist_atten = clamp(1.0 - (dist - 1.0*(1.0 - fa)) / fa, 0.0, 1.0); +        dist_atten *= dist_atten; +        dist_atten *= 2.0f; + +        if (dist_atten <= 0.0) +        { +            return col; +        } + +        // spotlight coefficient. +        float spot = max(dot(-ln, lv), is_pointlight); +        da *= spot*spot; // GL_SPOT_EXPONENT=2 + +        //angular attenuation +        da *= dot(n, lv); + +        float lit = 0.0f; + +        float amb_da = ambiance; +        if (da >= 0) +        { +            lit = max(da * dist_atten, 0.0); +            col = lit * light_col * diffuse; +            amb_da += (da*0.5 + 0.5) * ambiance; +        } +        amb_da += (da*da*0.5 + 0.5) * ambiance; +        amb_da *= dist_atten; +        amb_da = min(amb_da, 1.0f - lit); + +        // SL-10969 need to see why these are blown out +        //col.rgb += amb_da * light_col * diffuse; + +        if (spec.a > 0.0) +        { +            //vec3 ref = dot(pos+lv, norm); +            vec3 h = normalize(lv + npos); +            float nh = dot(n, h); +            float nv = dot(n, npos); +            float vh = dot(npos, h); +            float sa = nh; +            float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5; + +            float gtdenom = 2 * nh; +            float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); + +            if (nh > 0.0) +            { +                float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt / (nh*da); +                vec3 speccol = lit*scol*light_col.rgb*spec.rgb; +                speccol = clamp(speccol, vec3(0), vec3(1)); +                col += speccol; + +                float cur_glare = max(speccol.r, speccol.g); +                cur_glare = max(cur_glare, speccol.b); +                glare = max(glare, speccol.r); +                glare += max(cur_glare, 0.0); +            } +        } +    } + +    return max(col, vec3(0.0, 0.0, 0.0)); +} + +#else +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_data[3]; +#else +#define frag_data gl_FragData +#endif +#endif + +uniform sampler2D diffuseMap;  //always in sRGB space + +#ifdef HAS_NORMAL_MAP +uniform sampler2D bumpMap; +#endif + +#ifdef HAS_SPECULAR_MAP +uniform sampler2D specularMap; + +VARYING vec2 vary_texcoord2; +#endif + +uniform float env_intensity; +uniform vec4 specular_color;  // specular color RGB and specular exponent (glossiness) in alpha + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK) +uniform float minimum_alpha; +#endif + +#ifdef 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); + +void main() +{ +    vec2 pos_screen = vary_texcoord0.xy; + +    vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy); +	diffcol.rgb *= vertex_color.rgb; + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK) + +    // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points +    float bias = 0.001953125; // 1/512, or half an 8-bit quantization +    if (diffcol.a < minimum_alpha-bias) +    { +        discard; +    } +#endif + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) +	vec3 gamma_diff = diffcol.rgb; +	diffcol.rgb = srgb_to_linear(diffcol.rgb); +#endif + +#ifdef HAS_SPECULAR_MAP +    vec4 spec = texture2D(specularMap, vary_texcoord2.xy); +    spec.rgb *= specular_color.rgb; +#else +    vec4 spec = vec4(specular_color.rgb, 1.0); +#endif + +#ifdef 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 = normalize(tnorm.xyz); + +    vec2 abnormal = encode_normal(norm.xyz); + +    vec4 final_color = diffcol; + +#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE) +	final_color.a = emissive_brightness; +#else +	final_color.a = max(final_color.a, emissive_brightness); +#endif + +    vec4 final_specular = spec; +     +#ifdef HAS_SPECULAR_MAP +    vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0); +	final_specular.a = specular_color.a * norm.a; +#else +	vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0); +	final_specular.a = specular_color.a; +#endif + +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) + +    //forward rendering, output just lit sRGBA +    vec3 pos = vary_position; + +    float shadow = 1.0f; + +#ifdef HAS_SUN_SHADOW +    shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen); +#endif + +    spec = final_specular; +    vec4 diffuse = final_color; +    float envIntensity = final_normal.z; + +    vec3 color = vec3(0,0,0); + +    vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir; + +    float bloom = 0.0; +    vec3 sunlit; +    vec3 amblit; +    vec3 additive; +    vec3 atten; + +    calcAtmosphericVars(pos.xyz, light_dir, 1.0, sunlit, amblit, additive, atten, false); +     +        // This call breaks the Mac GLSL compiler/linker for unknown reasons (17Mar2020) +        // The call is either a no-op or a pure (pow) gamma adjustment, depending on GPU level +        // TODO: determine if we want to re-apply the gamma adjustment, and if so understand & fix Mac breakage +        //color = fullbrightScaleSoftClip(color); + +    vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); + +    //we're in sRGB space, so gamma correct this dot product so  +    // lighting from the sun stays sharp +    float da = clamp(dot(normalize(norm.xyz), light_dir.xyz), 0.0, 1.0); +    da = pow(da, 1.0 / 1.3); + +    color = amblit; + +    //darken ambient for normals perpendicular to light vector so surfaces in shadow  +    // and facing away from light still have some definition to them. +    // do NOT gamma correct this dot product so ambient lighting stays soft +    float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); +    ambient *= 0.5; +    ambient *= ambient; +    ambient = (1.0 - ambient); + +    vec3 sun_contrib = min(da, shadow) * sunlit; +     +    color *= ambient; + +    color += sun_contrib; + +    color *= gamma_diff.rgb; + +    float glare = 0.0; + +    if (spec.a > 0.0)  // specular reflection +    { +        /*  // Reverting this specular calculation to previous 'dumbshiny' version - DJH 6/17/2020 +            // Preserving the refactored version as a comment for potential reconsideration, +            // overriding the general rule to avoid pollutiong the source with commented code. +            // +            //  If you're reading this in 2021+, feel free to obliterate. + +        vec3 npos = -normalize(pos.xyz); + +        //vec3 ref = dot(pos+lv, norm); +        vec3 h = normalize(light_dir.xyz + npos); +        float nh = dot(norm.xyz, h); +        float nv = dot(norm.xyz, npos); +        float vh = dot(npos, h); +        float sa = nh; +        float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5; + +        float gtdenom = 2 * nh; +        float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); + +        if (nh > 0.0) +        { +            float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt / (nh*da); +            vec3 sp = sun_contrib*scol / 6.0f; +            sp = clamp(sp, vec3(0), vec3(1)); +            bloom = dot(sp, sp) / 4.0; +            color += sp * spec.rgb; +        } +        */ + +        float sa        = dot(refnormpersp, sun_dir.xyz); +        vec3  dumbshiny = sunlit * shadow * (texture2D(lightFunc, vec2(sa, spec.a)).r); + +        // add the two types of shiny together +        vec3 spec_contrib = dumbshiny * spec.rgb; +        bloom             = dot(spec_contrib, spec_contrib) / 6; + +        glare = max(spec_contrib.r, spec_contrib.g); +        glare = max(glare, spec_contrib.b); + +        color += spec_contrib; +    } + +    color = mix(color.rgb, diffcol.rgb, diffuse.a); + +    if (envIntensity > 0.0) +    { +        //add environmentmap +        vec3 env_vec = env_mat * refnormpersp; + +        vec3 reflected_color = textureCube(environmentMap, env_vec).rgb; + +        color = mix(color, reflected_color, envIntensity); + +        float cur_glare = max(reflected_color.r, reflected_color.g); +        cur_glare = max(cur_glare, reflected_color.b); +        cur_glare *= envIntensity*4.0; +        glare += cur_glare; +    } + +    color = atmosFragLighting(color, additive, atten); +    color = scaleSoftClipFrag(color); + +    //convert to linear before adding local lights +    color = srgb_to_linear(color); + +    vec3 npos = normalize(-pos.xyz); + +    vec3 light = vec3(0, 0, 0); +     +#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare, light_attenuation[i].w ); + +    LIGHT_LOOP(1) +        LIGHT_LOOP(2) +        LIGHT_LOOP(3) +        LIGHT_LOOP(4) +        LIGHT_LOOP(5) +        LIGHT_LOOP(6) +        LIGHT_LOOP(7) + +    color += light; + +    glare = min(glare, 1.0); +    float al = max(diffcol.a, glare)*vertex_color.a; + +    //convert to srgb as this color is being written post gamma correction +    color = linear_to_srgb(color); + +#ifdef WATER_FOG +    vec4 temp = applyWaterFogView(pos, vec4(color, al)); +    color = temp.rgb; +    al = temp.a; +#endif + +    frag_color = vec4(color, al); + +#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer  + +    // deferred path +    frag_data[0] = final_color; //gbuffer is sRGB +    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/moonF.glsl b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl index 80f232948a..35068899ee 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl @@ -1,9 +1,9 @@  /**  - * @file moonF.glsl + * @file class1\deferred\moonF.glsl   *   * $LicenseInfo:firstyear=2005&license=viewerlgpl$   * Second Life Viewer Source Code - * Copyright (C) 2005, Linden Research, Inc. + * Copyright (C) 2005, 2020 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 @@ -36,34 +36,33 @@ out vec4 frag_data[3];  uniform vec4 color;  uniform vec4 sunlight_color;  uniform vec4 moonlight_color; -uniform vec3 lumWeights; +uniform vec3 moon_dir;  uniform float moon_brightness; -uniform float minLuminance;  uniform sampler2D diffuseMap; -uniform sampler2D altDiffuseMap; -uniform float blend_factor; // interp factor between moon A/B +  VARYING vec2 vary_texcoord0;  vec3 srgb_to_linear(vec3 c); -void main()  -{ -    vec4 moonA = texture2D(diffuseMap, vary_texcoord0.xy); -    vec4 moonB = texture2D(altDiffuseMap, vary_texcoord0.xy); -    vec4 c     = mix(moonA, moonB, blend_factor); -    c.rgb = srgb_to_linear(c.rgb); +/// Soft clips the light with a gamma correction +vec3 scaleSoftClip(vec3 light); -    // mix factor which blends when sunlight is brighter -    // and shows true moon color at night -    vec3 luma_weights = vec3(0.3, 0.5, 0.3); +void main()  +{ +    // Restore Pre-EEP alpha fade moon near horizon +    float fade = 1.0; +    if( moon_dir.z > 0 ) +        fade = clamp( moon_dir.z*moon_dir.z*4.0, 0.0, 1.0 ); -    vec4 light_color = max(sunlight_color, moonlight_color); -    float mix = 1.0 - dot(normalize(light_color.rgb), luma_weights); +    vec4 c      = texture2D(diffuseMap, vary_texcoord0.xy); +//       c.rgb  = srgb_to_linear(c.rgb); +         c.rgb *= moonlight_color.rgb; +         c.rgb *= moon_brightness; -    vec3 exp = vec3(1.0 - mix * moon_brightness) * 2.0  - 1.0; -    c.rgb = pow(c.rgb, exp); +         c.rgb *= fade; +         c.a   *= fade; -    //c.rgb *= moonlight_color.rgb; +         c.rgb  = scaleSoftClip(c.rgb);      frag_data[0] = vec4(c.rgb, c.a);      frag_data[1] = vec4(0.0); diff --git a/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl b/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl index e1bac4f248..c4922afd7d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl @@ -1,9 +1,9 @@  /**  - * @file moonV.glsl + * @file class1\deferred\moonV.glsl   *    * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code - * Copyright (C) 2007, Linden Research, Inc. + * Copyright (C) 2007, 2020 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 @@ -32,18 +32,13 @@ ATTRIBUTE vec2 texcoord0;  VARYING vec2 vary_texcoord0; -void calcAtmospherics(vec3 eye_pos); -  void main()  {      //transform vertex -    vec3 offset = vec3(0, 0, 50); -    vec4 vert = vec4(position.xyz - offset, 1.0); +    vec4 vert = vec4(position.xyz, 1.0);      vec4 pos = (modelview_matrix * vert);      gl_Position = modelview_projection_matrix*vert; -    calcAtmospherics(pos.xyz); -          vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 0d1cc81786..8c402fcb54 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -1,24 +1,24 @@ -/**  - * @file multiPointLightF.glsl +/** + * @file class1/deferred/multiPointLightF.glsl   *   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2007, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -36,119 +36,112 @@ out vec4 frag_color;  uniform sampler2DRect depthMap;  uniform sampler2DRect diffuseRect;  uniform sampler2DRect specularRect; -uniform samplerCube environmentMap; -uniform sampler2D noiseMap; -uniform sampler2D lightFunc; +uniform samplerCube   environmentMap; +uniform sampler2D     noiseMap; +uniform sampler2D     lightFunc; - -uniform vec3 env_mat[3]; +uniform vec3  env_mat[3];  uniform float sun_wash; +uniform int   light_count; +uniform vec4  light[LIGHT_COUNT]; +uniform vec4  light_col[LIGHT_COUNT]; -uniform int light_count; - -uniform vec4 light[LIGHT_COUNT]; -uniform vec4 light_col[LIGHT_COUNT]; - -VARYING vec4 vary_fragcoord; -uniform vec2 screen_res; - +uniform vec2  screen_res;  uniform float far_z; +uniform mat4  inv_proj; -uniform mat4 inv_proj; +VARYING vec4 vary_fragcoord;  vec4 getPosition(vec2 pos_screen);  vec3 getNorm(vec2 pos_screen);  vec3 srgb_to_linear(vec3 c); -void main()  +void main()  { -	vec3 out_col = vec3(0,0,0); -  #if defined(LOCAL_LIGHT_KILL) -    discard; -#else -	vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res; -	vec3 pos = getPosition(frag.xy).xyz; -	if (pos.z < far_z) -	{ -		discard; -	} -	 -	vec3 norm = getNorm(frag.xy); - -	vec4 spec = texture2DRect(specularRect, frag.xy); -	vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb; -    diff.rgb = srgb_to_linear(diff.rgb); -	 -	float noise = texture2D(noiseMap, frag.xy/128.0).b; -	vec3 npos = normalize(-pos); - -	// As of OSX 10.6.7 ATI Apple's crash when using a variable size loop -	for (int i = 0; i < LIGHT_COUNT; ++i) -	{ -		vec3 lv = light[i].xyz-pos; -		float dist = length(lv); -		dist /= light[i].w; -		if (dist <= 1.0) -		{ -		float da = dot(norm, lv); -			if (da > 0.0) -		{ -			lv = normalize(lv); -			da = dot(norm, lv); -			 -			float fa = light_col[i].a+1.0; -			float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0); -			dist_atten *= dist_atten; -             -            // Tweak falloff slightly to match pre-EEP attenuation -			// NOTE: this magic number also shows up in a great many other places, search for dist_atten *= to audit -			dist_atten *= 2.0; -			 -			dist_atten *= noise; - -			float lit = da * dist_atten; -						 -			vec3 col = light_col[i].rgb*lit*diff; -			 -			//vec3 col = vec3(dist2, light_col[i].a, lit); -			 -			if (spec.a > 0.0) -			{ -				lit = 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 += lit*scol*light_col[i].rgb*spec.rgb; -					//col += spec.rgb; -				} -			} -			 -			out_col += col; -		} -	} -	} +    discard;  // Bail immediately  #endif -	 -	frag_color.rgb = out_col; -	frag_color.a = 0.0; + +    vec3 out_col = vec3(0, 0, 0); +    vec2 frag    = (vary_fragcoord.xy * 0.5 + 0.5) * screen_res; +    vec3 pos     = getPosition(frag.xy).xyz; +    if (pos.z < far_z) +    { +        discard; +    } + +    vec3 norm = getNorm(frag.xy); + +    vec4 spec = texture2DRect(specularRect, frag.xy); +    spec.rgb  = srgb_to_linear(spec.rgb); +    vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb; +    diff.rgb  = srgb_to_linear(diff.rgb); + +    float noise = texture2D(noiseMap, frag.xy / 128.0).b; +    vec3  npos  = normalize(-pos); + +    // As of OSX 10.6.7 ATI Apple's crash when using a variable size loop +    for (int i = 0; i < LIGHT_COUNT; ++i) +    { +        vec3  lv   = light[i].xyz - pos; +        float dist = length(lv); +        dist /= light[i].w; +        if (dist <= 1.0) +        { +            float da = dot(norm, lv); +            if (da > 0.0) +            { +                lv = normalize(lv); +                da = dot(norm, lv); + +                float fa         = light_col[i].a + 1.0; +                float dist_atten = clamp(1.0 - (dist - 1.0 * (1.0 - fa)) / fa, 0.0, 1.0); +                dist_atten *= dist_atten; + +                // Tweak falloff slightly to match pre-EEP attenuation +                // NOTE: this magic number also shows up in a great many other places, search for dist_atten *= to audit +                dist_atten *= 2.0; + +                dist_atten *= noise; + +                float lit = da * dist_atten; + +                vec3 col = light_col[i].rgb * lit * diff; + +                if (spec.a > 0.0) +                { +                    lit        = min(da * 6.0, 1.0) * dist_atten; +                    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 += lit * scol * light_col[i].rgb * spec.rgb; +                    } +                } + +                out_col += col; +            } +        } +    } + +    frag_color.rgb = out_col; +    frag_color.a   = 0.0;  #ifdef IS_AMD_CARD -	// If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts. -	vec4 dummy1 = light[0]; -	vec4 dummy2 = light_col[0]; -	vec4 dummy3 = light[LIGHT_COUNT-1]; -	vec4 dummy4 = light_col[LIGHT_COUNT-1]; +    // If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage +    // awawy which leads to unfun crashes and artifacts. +    vec4 dummy1 = light[0]; +    vec4 dummy2 = light_col[0]; +    vec4 dummy3 = light[LIGHT_COUNT - 1]; +    vec4 dummy4 = light_col[LIGHT_COUNT - 1];  #endif  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl index ead754ec76..28a1faf24f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl @@ -1,24 +1,24 @@ -/**  +/**   * @file WLSkyV.glsl   *   * $LicenseInfo:firstyear=2005&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2005, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -37,13 +37,13 @@ VARYING vec4 vary_HazeColor;  // Inputs  uniform vec3 camPosLocal; -uniform vec4 lightnorm; -uniform vec4 sunlight_color; -uniform vec4 moonlight_color; -uniform int sun_up_factor; -uniform vec4 ambient_color; -uniform vec4 blue_horizon; -uniform vec4 blue_density; +uniform vec4  lightnorm; +uniform vec4  sunlight_color; +uniform vec4  moonlight_color; +uniform int   sun_up_factor; +uniform vec4  ambient_color; +uniform vec4  blue_horizon; +uniform vec4  blue_density;  uniform float haze_horizon;  uniform float haze_density; @@ -52,7 +52,7 @@ uniform float density_multiplier;  uniform float distance_multiplier;  uniform float max_y; -uniform vec4 glow; +uniform vec4  glow;  uniform float sun_moon_glow_factor;  uniform vec4 cloud_color; @@ -63,103 +63,91 @@ uniform vec4 cloud_color;  //       indra\newview\lllegacyatmospherics.cpp  void main()  { - -	// World / view / projection +    // World / view / projection      vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0); -	gl_Position = pos; -	 -	// Get relative position -	vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0); - -	// Set altitude -	if (P.y > 0.) -	{ -		P *= (max_y / P.y); -	} -	else -	{ -		P *= (-32000. / P.y); -	} - -	// Can normalize then -	vec3 Pn = normalize(P); - -	float Plen = length(P); - -	// Initialize temp variables -	vec4 temp1 = vec4(0.); -	vec4 temp2 = vec4(0.); -	vec4 blue_weight; -	vec4 haze_weight; -	vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color; -	vec4 light_atten; - -    float dens_mul = density_multiplier; - -	// 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)) * (dens_mul * max_y); - -	// Calculate relative weights -	temp1 = abs(blue_density) + vec4(abs(haze_density)); -	blue_weight = blue_density / temp1; -	haze_weight = haze_density / temp1; - -	// Compute sunlight from P & lightnorm (for long rays like sky) -    temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y ); -    temp2.y = 1. / temp2.y; -    sunlight *= exp( - light_atten * temp2.y); - -	// Distance -	temp2.z = Plen * dens_mul; - -	// Transparency (-> temp1) -    // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati -    // compiler gets confused. -    temp1 = exp(-temp1 * temp2.z); +    gl_Position = pos; + +    // Get relative position +    vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0); + +    // Adj position vector to clamp altitude +    if (rel_pos.y > 0) +    { +        rel_pos *= (max_y / rel_pos.y); +    } +    if (rel_pos.y < 0) +    { +        rel_pos *= (-32000. / rel_pos.y); +    } + +    // Can normalize then +    vec3 rel_pos_norm = normalize(rel_pos); -	// Compute haze glow -	temp2.x = dot(Pn, lightnorm.xyz); -	temp2.x = 1. - temp2.x; -		// temp2.x is 0 at the sun and increases away from sun -	temp2.x = max(temp2.x, .001);	 -		// 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 +    float rel_pos_len = length(rel_pos); -	// Add "minimum anti-solar illumination" -	temp2.x += .25; +    // Initialize temp variables +    vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color; +    vec4 light_atten; -    vec4 color = (    blue_horizon * blue_weight * (sunlight + ambient_color) -                + (haze_horizon * haze_weight) * (sunlight * temp2.x + ambient_color) -             ); +    // 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); +    // Calculate relative weights +    vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density)); +    vec4 blue_weight   = blue_density / combined_haze; +    vec4 haze_weight   = haze_density / combined_haze; + +    // Compute sunlight from rel_pos & lightnorm (for long rays like sky) +    float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y); +    sunlight *= exp(-light_atten * off_axis); + +    // Distance +    float density_dist = rel_pos_len * density_multiplier; + +    // Transparency (-> combined_haze) +    // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati +    // compiler gets confused. +    combined_haze = exp(-combined_haze * density_dist); + +    // Compute haze glow +    float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz); +    // haze_glow is 0 at the sun and increases away from sun +    haze_glow = max(haze_glow, .001); +    // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) +    haze_glow *= glow.x; +    // Higher glow.x gives dimmer glow (because next step is 1 / "angle") +    haze_glow = pow(haze_glow, glow.z); +    // glow.z should be negative, so we're doing a sort of (1 / "angle") function + +    // Add "minimum anti-solar illumination" +    // For sun, add to glow.  For moon, remove glow entirely. SL-13768 +    haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25); + +    vec4 color = +        (blue_horizon * blue_weight * (sunlight + ambient_color) + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color));      // Final atmosphere additive -    color *= (1. - temp1); +    color *= (1. - combined_haze); -	// Increase ambient when there are more clouds -	vec4 tmpAmbient = ambient_color; -	tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;  +    // Increase ambient when there are more clouds +    vec4 tmpAmbient = ambient_color; +    tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5; -	// Dim sunlight by cloud shadow percentage -	sunlight *= max(0.0, (1. - cloud_shadow)); +    // Dim sunlight by cloud shadow percentage +    sunlight *= max(0.0, (1. - cloud_shadow)); -	// Haze color below cloud -	vec4 additiveColorBelowCloud = (	  blue_horizon * blue_weight * (sunlight + tmpAmbient) -				+ (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient) -			 );	 +    // Haze color below cloud +    vec4 additiveColorBelowCloud = +        (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient)); -	// Attenuate cloud color by atmosphere -	temp1 = sqrt(temp1);	//less atmos opacity (more transparency) below clouds +    // Attenuate cloud color by atmosphere +    combined_haze = sqrt(combined_haze);  // less atmos opacity (more transparency) below clouds -	// At horizon, blend high altitude sky color towards the darker color below the clouds -	color += (additiveColorBelowCloud - color) * (1. - sqrt(temp1)); +    // At horizon, blend high altitude sky color towards the darker color below the clouds +    color += (additiveColorBelowCloud - color) * (1. - sqrt(combined_haze));      // Haze color above cloud -	vary_HazeColor = color;	 +    vary_HazeColor = color;  } - diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index a5804220bc..f80f1a985a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -124,41 +124,15 @@ void main()          if (spec.a > 0.0) // specular reflection          { +            float sa        = dot(refnormpersp, light_dir.xyz); +            vec3  dumbshiny = sunlit * (texture2D(lightFunc, vec2(sa, spec.a)).r); -#if 1 //EEP -            vec3 npos = -normalize(pos.xyz); - -            //vec3 ref = dot(pos+lv, norm); -            vec3 h = normalize(light_dir.xyz+npos); -            float nh = dot(norm.xyz, h); -            float nv = dot(norm.xyz, 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 scontrib = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); -                vec3 sp = sun_contrib*scontrib / 6.0; -                sp = clamp(sp, vec3(0), vec3(1)); -                bloom += dot(sp, sp) / 4.0; -                color += sp * spec.rgb; -            } -#else //PRODUCTION -            float sa = dot(refnormpersp, light_dir.xyz); -            vec3 dumbshiny = sunlit*(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; +            bloom             = dot(spec_contrib, spec_contrib) / 6;              color.rgb += spec_contrib; -#endif -          } -        +         color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a);          if (envIntensity > 0.0) diff --git a/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl b/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl index 50e781fa78..6cd2445522 100644 --- a/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl @@ -23,6 +23,9 @@   * $/LicenseInfo$   */ +// Lambert Azimuthal Equal-Area projection +// See: https://aras-p.info/texts/CompactNormalStorage.html +// Also see: A_bit_more_deferred_-_CryEngine3.ppt  vec2 encode_normal(vec3 n)  {  	float f = sqrt(8 * n.z + 8); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl index f665394b46..0bb48061e0 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl @@ -31,6 +31,9 @@ out vec4 frag_color;  uniform float minimum_alpha; +// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO; +uniform int no_atmo; +  vec3 atmosLighting(vec3 light);  vec3 scaleSoftClip(vec3 light); @@ -41,16 +44,19 @@ void default_lighting()  {  	vec4 color = diffuseLookup(vary_texcoord0.xy); -	color *= vertex_color; -  	if (color.a < minimum_alpha)  	{  		discard;  	} +	 +	color *= vertex_color; -	color.rgb = atmosLighting(color.rgb); - -	color.rgb = scaleSoftClip(color.rgb); +	// SL-9632 HUDs are affected by Atmosphere +	if (no_atmo == 0) +	{ +		color.rgb = atmosLighting(color.rgb); +		color.rgb = scaleSoftClip(color.rgb); +	}  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl index 46390e4a0e..1855cfceeb 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl @@ -30,7 +30,10 @@ out vec4 frag_color;  #endif  uniform float minimum_alpha; -uniform float texture_gamma; +uniform float texture_gamma; // either 1.0 or 2.2; see: "::TEXTURE_GAMMA" + +// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO; used in LLDrawPoolAlpha::beginRenderPass() +uniform int no_atmo;  vec3 fullbrightAtmosTransport(vec3 light);  vec3 fullbrightScaleSoftClip(vec3 light); @@ -50,9 +53,17 @@ void fullbright_lighting()  	color.rgb *= vertex_color.rgb;  	color.rgb = pow(color.rgb, vec3(texture_gamma)); -	color.rgb = fullbrightAtmosTransport(color.rgb); -	 -	color.rgb = fullbrightScaleSoftClip(color.rgb); + +	// SL-9632 HUDs are affected by Atmosphere +	if (no_atmo == 0) +	{ +		color.rgb = fullbrightAtmosTransport(color.rgb); +		color.rgb = fullbrightScaleSoftClip(color.rgb); +	} + +	//*TODO: Are we missing an inverse pow() here? +	// class1\lighting\lightFullbrightF.glsl has: +    //     color.rgb = pow(color.rgb, vec3(1.0/texture_gamma));  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl index b967709c57..5fcdf3107c 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl @@ -34,6 +34,9 @@ VARYING vec2 vary_texcoord0;  uniform float texture_gamma; +// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO; +uniform int no_atmo; +  vec3 fullbrightAtmosTransport(vec3 light);  vec3 fullbrightScaleSoftClip(vec3 light); @@ -43,9 +46,12 @@ void fullbright_lighting()  	color.rgb = pow(color.rgb, vec3(texture_gamma)); -	color.rgb = fullbrightAtmosTransport(color.rgb); -	 -	color.rgb = fullbrightScaleSoftClip(color.rgb); +	// SL-9632 HUDs are affected by Atmosphere +	if (no_atmo == 0) +	{ +		color.rgb = fullbrightAtmosTransport(color.rgb); +		color.rgb = fullbrightScaleSoftClip(color.rgb); +	}  	color.rgb = pow(color.rgb, vec3(1.0/texture_gamma)); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl index 567811cd75..6f7e777d23 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl @@ -35,20 +35,37 @@ VARYING vec3 vary_texcoord1;  uniform samplerCube environmentMap; +// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO; used in LLDrawPoolAlpha::beginRenderPass() +uniform int no_atmo; +  vec3 fullbrightShinyAtmosTransport(vec3 light);  vec3 fullbrightScaleSoftClip(vec3 light); +// See: +//   class1\deferred\fullbrightShinyF.glsl +//   class1\lighting\lightFullbrightShinyF.glsl  void fullbright_shiny_lighting()  {  	vec4 color = diffuseLookup(vary_texcoord0.xy);  	color.rgb *= vertex_color.rgb; -	 -	vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;	 -	color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a*0.75); // MAGIC NUMBER SL-12574; ALM: Off, Quality > Low -	color.rgb = fullbrightShinyAtmosTransport(color.rgb); +	// SL-9632 HUDs are affected by Atmosphere +	if (no_atmo == 0) +	{ +		vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb; +		color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a*0.75); // MAGIC NUMBER SL-12574; ALM: Off, Quality > Low -	color.rgb = fullbrightScaleSoftClip(color.rgb); +		color.rgb = fullbrightShinyAtmosTransport(color.rgb); +		color.rgb = fullbrightScaleSoftClip(color.rgb); +	} +/* +	// NOTE: HUD objects will be full bright. Uncomment if you want "some" environment lighting effecting these HUD objects. +	else +	{ +		vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb; +		color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a*0.75); // MAGIC NUMBER SL-12574; ALM: Off, Quality > Low +	} +*/  	color.a = 1.0; diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl index a59bd9c0a6..9ef7704b70 100644 --- a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl @@ -1,4 +1,4 @@ -/**  +/**   * @file simpleV.glsl   *   * $LicenseInfo:firstyear=2007&license=viewerlgpl$ @@ -28,6 +28,9 @@ uniform mat4 texture_matrix0;  uniform mat4 modelview_matrix;  uniform mat4 modelview_projection_matrix; +// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO; used in LLDrawPoolAlpha::beginRenderPass() +uniform int no_atmo; +  ATTRIBUTE vec3 position;  void passTextureIndex();  ATTRIBUTE vec2 texcoord0; @@ -46,19 +49,23 @@ void main()  {  	//transform vertex  	vec4 vert = vec4(position.xyz,1.0); -	passTextureIndex(); -	vec4 pos = (modelview_matrix * vert);  	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); + +	passTextureIndex();  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0, 0, 1)).xy; -	 -	 -	 -	vec3 norm = normalize(normal_matrix * normal); -	calcAtmospherics(pos.xyz); +	// SL-9632 HUDs are affected by Atmosphere +	if (no_atmo == 1) +	{ +		vertex_color = diffuse_color; +	} +	else +	{ +		vec4 pos = (modelview_matrix * vert); +		vec3 norm = normalize(normal_matrix * normal); -	vec4 color = calcLighting(pos.xyz, norm, diffuse_color); -	vertex_color = color; +		calcAtmospherics(pos.xyz); -	 +		vertex_color = calcLighting(pos.xyz, norm, diffuse_color); +	}  } diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl index dcb02bd1c1..ea2690ba09 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl @@ -1,154 +1,134 @@ -/**  +/**   * @file class1\windlight\atmosphericsFuncs.glsl   *   * $LicenseInfo:firstyear=2005&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2019, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ -uniform vec4 lightnorm; -uniform vec4 sunlight_color; -uniform vec4 moonlight_color; -uniform int sun_up_factor; -uniform vec4 ambient_color; -uniform vec4 blue_horizon; -uniform vec4 blue_density; +uniform vec4  lightnorm; +uniform vec4  sunlight_color; +uniform vec4  moonlight_color; +uniform int   sun_up_factor; +uniform vec4  ambient_color; +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 vec4  glow;  uniform float scene_light_strength; -uniform mat3 ssao_effect_mat; -uniform int no_atmo; +uniform mat3  ssao_effect_mat; +uniform int   no_atmo;  uniform float sun_moon_glow_factor; -float getAmbientClamp() +float getAmbientClamp() { return 1.0f; } + +void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, +                         out vec3 atten, bool use_ao)  { -    return 1.0f; -} +    vec3 rel_pos = inPositionEye; +    //(TERRAIN) limit altitude +    if (abs(rel_pos.y) > max_y) rel_pos *= (max_y / rel_pos.y); -void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao) { +    vec3  rel_pos_norm = normalize(rel_pos); +    float rel_pos_len  = length(rel_pos); +    vec4  sunlight     = (sun_up_factor == 1) ? sunlight_color : moonlight_color; -    vec3 P = inPositionEye; -    -    //(TERRAIN) limit altitude -    if (P.y > max_y) P *= (max_y / P.y); -    if (P.y < -max_y) P *= (-max_y / P.y);  +    // sunlight attenuation effect (hue and brightness) due to atmosphere +    // this is used later for sunlight modulation at various altitudes +    vec4 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 -    vec3 tmpLightnorm = lightnorm.xyz; +    vec4 combined_haze = blue_density + vec4(haze_density); +    vec4 blue_weight   = blue_density / combined_haze; +    vec4 haze_weight   = vec4(haze_density) / combined_haze; -    vec3 Pn = normalize(P); -    float Plen = length(P); +    //(TERRAIN) compute sunlight from lightnorm y component. Factor is roughly cosecant(sun elevation) (for short rays like terrain) +    float above_horizon_factor = 1.0 / max(1e-6, lightnorm.y); +    sunlight *= exp(-light_atten * above_horizon_factor);  // for sun [horizon..overhead] this maps to an exp curve [0..1] + +    // main atmospheric scattering line integral +    float density_dist = rel_pos_len * density_multiplier; -    vec4 temp1 = vec4(0); -    vec3 temp2 = vec3(0); -    vec4 blue_weight; -    vec4 haze_weight; -    vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color; -    vec4 light_atten; +    // Transparency (-> combined_haze) +    // ATI Bugfix -- can't store combined_haze*density_dist*distance_multiplier in a variable because the ati +    // compiler gets confused. +    combined_haze = exp(-combined_haze * density_dist * distance_multiplier); -    float dens_mul = density_multiplier; -    float dist_mul = distance_multiplier; +    // final atmosphere attenuation factor +    atten = combined_haze.rgb; -    //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)) * (dens_mul * 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 +    // compute haze glow +    float haze_glow = dot(rel_pos_norm, lightnorm.xyz); -    temp1 = blue_density + vec4(haze_density); -    blue_weight = blue_density / temp1; -    haze_weight = vec4(haze_density) / temp1; +    // dampen sun additive contrib when not facing it... +    // SL-13539: This "if" clause causes an "additive" white artifact at roughly 77 degreees. +    //    if (length(light_dir) > 0.01) +    haze_glow *= max(0.0f, dot(light_dir, rel_pos_norm)); -    //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) -    temp2.y = max(0.0, tmpLightnorm.y); -    if (abs(temp2.y) > 0.000001f) -    { -        temp2.y = 1. / abs(temp2.y); -    } -    temp2.y = max(0.0000001f, temp2.y); -    sunlight *= exp(-light_atten * temp2.y); +    haze_glow = 1. - haze_glow; +    // haze_glow is 0 at the sun and increases away from sun +    haze_glow = max(haze_glow, .001);  // set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) +    haze_glow *= glow.x; +    // higher glow.x gives dimmer glow (because next step is 1 / "angle") +    haze_glow = pow(haze_glow, glow.z); +    // glow.z should be negative, so we're doing a sort of (1 / "angle") function -    // main atmospheric scattering line integral -    temp2.z = Plen * dens_mul; +    // add "minimum anti-solar illumination" +    haze_glow += .25; -    // Transparency (-> temp1) -    // ATI Bugfix -- can't store temp1*temp2.z*dist_mul in a variable because the ati -    // compiler gets confused. -    temp1 = exp(-temp1 * temp2.z * dist_mul); +    haze_glow *= sun_moon_glow_factor; -    //final atmosphere attenuation factor -    atten = temp1.rgb; -     -    //compute haze glow -    //(can use temp2.x as temp because we haven't used it yet) -    temp2.x = dot(Pn, tmpLightnorm.xyz); +    vec4 amb_color = ambient_color; -    // dampen sun additive contrib when not facing it... -    if (length(light_dir) > 0.01) -    { -        temp2.x *= max(0.0f, dot(light_dir, Pn)); -    } -    temp2.x = 1. - temp2.x; -        //temp2.x is 0 at the sun and increases away from sun -    temp2.x = max(temp2.x, .001);    //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; - -    temp2.x *= sun_moon_glow_factor; -  -    vec4 amb_color = ambient_color;  -     -    //increase ambient when there are more clouds +    // increase ambient when there are more clouds      vec4 tmpAmbient = amb_color + (vec4(1.) - amb_color) * 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(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, +     * ambAlpha);       */      if (use_ao)      {          tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);      } -    //haze color -        additive = -        vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient) -      + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x -          + tmpAmbient)); +    // Similar/Shared Algorithms: +    //     indra\llinventory\llsettingssky.cpp                                        -- LLSettingsSky::calculateLightSettings() +    //     indra\newview\app_settings\shaders\class1\windlight\atmosphericsFuncs.glsl -- calcAtmosphericVars() +    // haze color +    vec3 cs = sunlight.rgb * (1. - cloud_shadow); +    additive = (blue_horizon.rgb * blue_weight.rgb) * (cs + tmpAmbient.rgb) + (haze_horizon * haze_weight.rgb) * (cs * haze_glow + tmpAmbient.rgb); -    //brightness of surface both sunlight and ambient +    // brightness of surface both sunlight and ambient      sunlit = sunlight.rgb * 0.5;      amblit = tmpAmbient.rgb * .25; -    additive *= vec3(1.0 - temp1); +    additive *= vec3(1.0 - combined_haze);  } diff --git a/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl b/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl index 24f3992e32..2425a2ad04 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl @@ -3,7 +3,7 @@   *   * $LicenseInfo:firstyear=2005&license=viewerlgpl$   * Second Life Viewer Source Code - * Copyright (C) 2005, Linden Research, Inc. + * Copyright (C) 2005, 2020 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 @@ -36,28 +36,30 @@ out vec4 frag_color;  uniform vec4 color;  uniform vec4 sunlight_color;  uniform vec4 moonlight_color; -uniform vec3 lumWeights; +uniform vec3 moon_dir;  uniform float moon_brightness; -uniform float minLuminance;  uniform sampler2D diffuseMap; -uniform sampler2D altDiffuseMap; -uniform float blend_factor; // interp factor between moon A/B +  VARYING vec2 vary_texcoord0; +vec3 scaleSoftClip(vec3 light); +  void main()   { -    vec4 moonA = texture2D(diffuseMap, vary_texcoord0.xy); -    vec4 moonB = texture2D(altDiffuseMap, vary_texcoord0.xy); -    vec4 c     = mix(moonA, moonB, blend_factor); +    // Restore Pre-EEP alpha fade moon near horizon +    float fade = 1.0; +    if( moon_dir.z > 0 ) +        fade = clamp( moon_dir.z*moon_dir.z*4.0, 0.0, 1.0 ); + +    vec4 c     = texture2D(diffuseMap, vary_texcoord0.xy); +//       c.rgb = pow(c.rgb, vec3(0.7f)); // can't use "srgb_to_linear(color.rgb)" as that is a deferred only function +         c.rgb *= moonlight_color.rgb; +         c.rgb *= moon_brightness; -    // mix factor which blends when sunlight is brighter -    // and shows true moon color at night -    vec3 luma_weights = vec3(0.3, 0.5, 0.3); -    float mix = 1.0f - dot(normalize(sunlight_color.rgb), luma_weights); +         c.rgb *= fade; +         c.a   *= fade; -    vec3 exp = vec3(1.0 - mix * moon_brightness) * 2.0 - 1.0; -    c.rgb = pow(c.rgb, exp); -    //c.rgb *= moonlight_color.rgb; +         c.rgb  = scaleSoftClip(c.rgb);      frag_color = vec4(c.rgb, c.a);  } diff --git a/indra/newview/app_settings/shaders/class1/windlight/moonV.glsl b/indra/newview/app_settings/shaders/class1/windlight/moonV.glsl index 8cd4b2ef47..2fceb5f743 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/moonV.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/moonV.glsl @@ -3,7 +3,7 @@   *    * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code - * Copyright (C) 2007, Linden Research, Inc. + * Copyright (C) 2007, 2020 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 @@ -30,20 +30,15 @@ uniform mat4 modelview_projection_matrix;  ATTRIBUTE vec3 position;  ATTRIBUTE vec2 texcoord0; -void calcAtmospherics(vec3 inPositionEye); -  VARYING vec2 vary_texcoord0;  void main()  {      //transform vertex -    vec3 offset = vec3(0, 0, 50); -    vec4 vert = vec4(position.xyz - offset, 1.0); +    vec4 vert = vec4(position.xyz, 1.0);      vec4 pos = (modelview_matrix * vert);      gl_Position = modelview_projection_matrix*vert;      vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -     -    calcAtmospherics(pos.xyz);  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl index 1dce85a83b..1485c515a4 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl @@ -1,24 +1,24 @@ -/**  +/**   * @file class2/deferred/skyF.glsl   *   * $LicenseInfo:firstyear=2005&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2005, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -32,13 +32,13 @@ uniform mat4 modelview_projection_matrix;  // Inputs  uniform vec3 camPosLocal; -uniform vec4 lightnorm; -uniform vec4 sunlight_color; -uniform vec4 moonlight_color; -uniform int sun_up_factor; -uniform vec4 ambient_color; -uniform vec4 blue_horizon; -uniform vec4 blue_density; +uniform vec4  lightnorm; +uniform vec4  sunlight_color; +uniform vec4  moonlight_color; +uniform int   sun_up_factor; +uniform vec4  ambient_color; +uniform vec4  blue_horizon; +uniform vec4  blue_density;  uniform float haze_horizon;  uniform float haze_density; @@ -47,7 +47,7 @@ uniform float density_multiplier;  uniform float distance_multiplier;  uniform float max_y; -uniform vec4 glow; +uniform vec4  glow;  uniform float sun_moon_glow_factor;  uniform vec4 cloud_color; @@ -73,16 +73,16 @@ uniform float ice_level;  vec3 rainbow(float d)  { -   d = clamp(d, -1.0, 0.0); -   float rad = (droplet_radius - 5.0f) / 1024.0f; -   return pow(texture2D(rainbow_map, vec2(rad, d)).rgb, vec3(1.8)) * moisture_level; +    d         = clamp(d, -1.0, 0.0); +    float rad = (droplet_radius - 5.0f) / 1024.0f; +    return pow(texture2D(rainbow_map, vec2(rad, d)).rgb, vec3(1.8)) * moisture_level;  }  vec3 halo22(float d)  { -   d = clamp(d, 0.1, 1.0); -   float v = sqrt(clamp(1 - (d * d), 0, 1)); -   return texture2D(halo_map, vec2(0, v)).rgb * ice_level; +    d       = clamp(d, 0.1, 1.0); +    float v = sqrt(clamp(1 - (d * d), 0, 1)); +    return texture2D(halo_map, vec2(0, v)).rgb * ice_level;  }  /// Soft clips the light with a gamma correction @@ -90,115 +90,96 @@ vec3 scaleSoftClip(vec3 light);  void main()  { -      // World / view / projection -    // Get relative position -    vec3 P = pos.xyz - camPosLocal.xyz + vec3(0,50,0); +    // Get relative position (offset why?) +    vec3 rel_pos = pos.xyz - camPosLocal.xyz + vec3(0, 50, 0); -    // Set altitude -    if (P.y > 0.) +    // Adj position vector to clamp altitude +    if (rel_pos.y > 0.)      { -        P *= (max_y / P.y); +        rel_pos *= (max_y / rel_pos.y);      } -    else +    if (rel_pos.y < 0.)      { -        P *= (-32000. / P.y); +        rel_pos *= (-32000. / rel_pos.y);      } -    // Can normalize then -    vec3 Pn = normalize(P); -    float  Plen = length(P); +    // Normalized +    vec3  rel_pos_norm = normalize(rel_pos); +    float rel_pos_len  = length(rel_pos);      // Initialize temp variables -    vec4 temp1 = vec4(0.); -    vec4 temp2 = vec4(0.); -    vec4 blue_weight; -    vec4 haze_weight;      vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color; -    vec4 light_atten; - -    float dens_mul = density_multiplier;      // 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)) * (dens_mul * max_y); +    vec4 light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);      // Calculate relative weights -    temp1 = abs(blue_density) + vec4(abs(haze_density)); -    blue_weight = blue_density / temp1; -    haze_weight = haze_density / temp1; +    vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density)); +    vec4 blue_weight   = blue_density / combined_haze; +    vec4 haze_weight   = haze_density / combined_haze; -    // Compute sunlight from P & lightnorm (for long rays like sky) -    temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y ); -    temp2.y = 1. / temp2.y; -    sunlight *= exp( - light_atten * temp2.y); +    // Compute sunlight from rel_pos & lightnorm (for long rays like sky) +    float off_axis = 1.0 / max(1e-6, max(0, rel_pos_norm.y) + lightnorm.y); +    sunlight *= exp(-light_atten * off_axis);      // Distance -    temp2.z = Plen * dens_mul; +    float density_dist = rel_pos_len * density_multiplier; -    // Transparency (-> temp1) -    // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati +    // Transparency (-> combined_haze) +    // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati      // compiler gets confused. -    temp1 = exp(-temp1 * temp2.z); +    combined_haze = exp(-combined_haze * density_dist);      // Compute haze glow -    temp2.x = dot(Pn, lightnorm.xyz); -    temp2.x = 1. - temp2.x; -        // temp2.x is 0 at the sun and increases away from sun -    temp2.x = max(temp2.x, .001);    -        // 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 +    float haze_glow = dot(rel_pos_norm, lightnorm.xyz); +    haze_glow       = 1. - haze_glow; +    // haze_glow is 0 at the sun and increases away from sun +    haze_glow = max(haze_glow, .001); +    // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) +    haze_glow *= glow.x; +    // Higher glow.x gives dimmer glow (because next step is 1 / "angle") +    haze_glow = pow(haze_glow, 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; - -    temp2.x *= sun_moon_glow_factor; +    // For sun, add to glow.  For moon, remove glow entirely. SL-13768 +    haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (sun_moon_glow_factor * (haze_glow + 0.25));      // Haze color above cloud -    vec4 color = (    blue_horizon * blue_weight * (sunlight + ambient_color) -                + (haze_horizon * haze_weight) * (sunlight * temp2.x + ambient_color) -             );  +    vec4 color = blue_horizon * blue_weight * (sunlight + ambient_color)  +               + haze_horizon * haze_weight * (sunlight * haze_glow + ambient_color);      // Final atmosphere additive -    color *= (1. - temp1); +    color *= (1. - combined_haze);      // Increase ambient when there are more clouds -    vec4 tmpAmbient = ambient_color; -    tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;  +    // TODO 9/20: DJH what does this do?  max(0,(1-ambient)) will change the color +    vec4 ambient = ambient_color + max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;      // Dim sunlight by cloud shadow percentage      sunlight *= max(0.0, (1. - cloud_shadow));      // Haze color below cloud -    vec4 additiveColorBelowCloud = (blue_horizon * blue_weight * (sunlight + tmpAmbient) -                + (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient) -             );  +    vec4 add_below_cloud = blue_horizon * blue_weight * (sunlight + ambient)  +                         + haze_horizon * haze_weight * (sunlight * haze_glow + ambient); -     -          // Attenuate cloud color by atmosphere -    temp1 = sqrt(temp1);    //less atmos opacity (more transparency) below clouds +    combined_haze = sqrt(combined_haze);  // less atmos opacity (more transparency) below clouds      // At horizon, blend high altitude sky color towards the darker color below the clouds -    color += (additiveColorBelowCloud - color) * (1. - sqrt(temp1)); -     -    float optic_d = dot(Pn, lightnorm.xyz); - -    vec3 halo_22 = halo22(optic_d); +    color += (add_below_cloud - color) * (1. - sqrt(combined_haze)); +    float optic_d = dot(rel_pos_norm, lightnorm.xyz); +    vec3  halo_22 = halo22(optic_d);      color.rgb += rainbow(optic_d); -      color.rgb += halo_22; -      color.rgb *= 2.;      color.rgb = scaleSoftClip(color.rgb); -    /// Gamma correct for WL (soft clip effect). +    // Gamma correct for WL (soft clip effect).      frag_data[0] = vec4(color.rgb, 1.0); -    frag_data[1] = vec4(0.0,0.0,0.0,0.0); -    frag_data[2] = vec4(0.0,0.0,0.0,1.0); //1.0 in norm.w masks off fog +    frag_data[1] = vec4(0.0, 0.0, 0.0, 0.0); +    frag_data[2] = vec4(0.0, 0.0, 0.0, 1.0);  // 1.0 in norm.w masks off fog  } - diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index b0dff0c628..f4db53e0b7 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -1,24 +1,24 @@ -/**  +/**   * @file class2/deferred/softenLightF.glsl   *   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2007, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -39,7 +39,7 @@ uniform sampler2DRect specularRect;  uniform sampler2DRect normalMap;  uniform sampler2DRect lightMap;  uniform sampler2DRect depthMap; -uniform samplerCube environmentMap; +uniform samplerCube   environmentMap;  uniform sampler2D     lightFunc;  uniform float blur_size; @@ -50,7 +50,7 @@ uniform mat3 env_mat;  uniform vec3 sun_dir;  uniform vec3 moon_dir; -uniform int sun_up_factor; +uniform int  sun_up_factor;  VARYING vec2 vary_fragcoord;  uniform mat4 inv_proj; @@ -61,10 +61,10 @@ vec4 getPositionWithDepth(vec2 pos_screen, float depth);  void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);  float getAmbientClamp(); -vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten); -vec3 scaleSoftClipFrag(vec3 l); -vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten); -vec3 fullbrightScaleSoftClip(vec3 light); +vec3  atmosFragLighting(vec3 l, vec3 additive, vec3 atten); +vec3  scaleSoftClipFrag(vec3 l); +vec3  fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten); +vec3  fullbrightScaleSoftClip(vec3 light);  vec3 linear_to_srgb(vec3 c);  vec3 srgb_to_linear(vec3 c); @@ -73,128 +73,85 @@ vec3 srgb_to_linear(vec3 c);  vec4 applyWaterFogView(vec3 pos, vec4 color);  #endif -void main()  +void main()  { -    vec2 tc = vary_fragcoord.xy; -    float depth = texture2DRect(depthMap, tc.xy).r; -    vec4 pos = getPositionWithDepth(tc, depth); -    vec4 norm = texture2DRect(normalMap, tc); +    vec2  tc           = vary_fragcoord.xy; +    float depth        = texture2DRect(depthMap, tc.xy).r; +    vec4  pos          = getPositionWithDepth(tc, depth); +    vec4  norm         = texture2DRect(normalMap, tc);      float envIntensity = norm.z; -    norm.xyz = getNorm(tc); -     -    vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir; -    float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0); -    float light_gamma = 1.0/1.3; -    da = pow(da, light_gamma); -     +    norm.xyz           = getNorm(tc); + +    vec3  light_dir   = (sun_up_factor == 1) ? sun_dir : moon_dir; +    float da          = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0); +    float light_gamma = 1.0 / 1.3; +    da                = pow(da, light_gamma); +      vec4 diffuse = texture2DRect(diffuseRect, tc); -     -    vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); +    vec4 spec    = texture2DRect(specularRect, vary_fragcoord.xy);      vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; -    scol_ambocc = pow(scol_ambocc, vec2(light_gamma)); +    scol_ambocc      = pow(scol_ambocc, vec2(light_gamma)); +    float scol       = max(scol_ambocc.r, diffuse.a); +    float ambocc     = scol_ambocc.g; -    float scol = max(scol_ambocc.r, diffuse.a);  +    vec3  color = vec3(0); +    float bloom = 0.0; -    float ambocc = scol_ambocc.g; +    vec3 sunlit; +    vec3 amblit; +    vec3 additive; +    vec3 atten; +    calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, true); -    vec3 color = vec3(0); -    float bloom = 0.0; +    color.rgb = amblit; + +    float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); +    ambient *= 0.5; +    ambient *= ambient; +    ambient = (1.0 - ambient); +    color.rgb *= ambient; + +    vec3 sun_contrib = min(da, scol) * sunlit; +    color.rgb += sun_contrib; +    color.rgb *= diffuse.rgb; + +    vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); + +    if (spec.a > 0.0)  // specular reflection      { -        vec3 sunlit; -        vec3 amblit; -        vec3 additive; -        vec3 atten; -     -        calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, true); - -        color.rgb = amblit; - -        float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); -        ambient *= 0.5; -        ambient *= ambient; -        ambient = (1.0 - ambient); - -        color.rgb *= ambient; - -        vec3 sun_contrib = min(da, scol) * sunlit; - -        color.rgb += sun_contrib; - -        color.rgb *= diffuse.rgb; - -        vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); - -        if (spec.a > 0.0) // specular reflection -        { - -#if 1 //EEP -            vec3 npos = -normalize(pos.xyz); - -            //vec3 ref = dot(pos+lv, norm); -            vec3 h = normalize(light_dir.xyz+npos); -            float nh = dot(norm.xyz, h); -            float nv = dot(norm.xyz, 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 scontrib = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da); -                vec3 sp = sun_contrib*scontrib / 6.0; -                sp = clamp(sp, vec3(0), vec3(1)); -                bloom += dot(sp, sp) / 4.0; -                color += sp * spec.rgb; -            } -#else //PRODUCTION -            float sa = dot(refnormpersp, light_dir.xyz); -            vec3 dumbshiny = sunlit*(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; -            color.rgb += spec_contrib; -#endif +        float sa        = dot(refnormpersp, light_dir.xyz); +        vec3  dumbshiny = sunlit * scol * (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; +        color.rgb += spec_contrib; +    } + +    color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a); -        } -        -       color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a); - -        if (envIntensity > 0.0) -        { //add environmentmap -            vec3 env_vec = env_mat * refnormpersp; -            vec3 reflected_color = textureCube(environmentMap, env_vec).rgb; -            color = mix(color.rgb, reflected_color, envIntensity); -        } -        -        if (norm.w < 0.5) -        { -            color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a); -            color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a); -        } - -        #ifdef WATER_FOG -            vec4 fogged = applyWaterFogView(pos.xyz,vec4(color, bloom)); -            color = fogged.rgb; -            bloom = fogged.a; -        #endif +    if (envIntensity > 0.0) +    {  // add environmentmap +        vec3 env_vec         = env_mat * refnormpersp; +        vec3 reflected_color = textureCube(environmentMap, env_vec).rgb; +        color                = mix(color.rgb, reflected_color, envIntensity); +    } +    if (norm.w < 0.5) +    { +        color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a); +        color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a);      } -// linear debuggables -//color.rgb = vec3(final_da); -//color.rgb = vec3(ambient); -//color.rgb = vec3(scol); -//color.rgb = diffuse_srgb.rgb; +#ifdef WATER_FOG +    vec4 fogged = applyWaterFogView(pos.xyz, vec4(color, bloom)); +    color       = fogged.rgb; +    bloom       = fogged.a; +#endif      // convert to linear as fullscreen lights need to sum in linear colorspace      // and will be gamma (re)corrected downstream... -          frag_color.rgb = srgb_to_linear(color.rgb); -    frag_color.a = bloom; +    frag_color.a   = bloom;  } - diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl index 2c1475d547..1f881eb44b 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl @@ -1,24 +1,24 @@ -/**  +/**   * @file class2\wl\cloudsV.glsl   *   * $LicenseInfo:firstyear=2005&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2005, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ @@ -33,25 +33,26 @@ ATTRIBUTE vec2 texcoord0;  ///////////////////////////////////////////////////////////////////////////////  // Output parameters -VARYING vec4 vary_CloudColorSun; -VARYING vec4 vary_CloudColorAmbient; +VARYING vec4  vary_CloudColorSun; +VARYING vec4  vary_CloudColorAmbient;  VARYING float vary_CloudDensity; -VARYING vec2 vary_texcoord0; -VARYING vec2 vary_texcoord1; -VARYING vec2 vary_texcoord2; -VARYING vec2 vary_texcoord3; + +VARYING vec2  vary_texcoord0; +VARYING vec2  vary_texcoord1; +VARYING vec2  vary_texcoord2; +VARYING vec2  vary_texcoord3;  VARYING float altitude_blend_factor;  // Inputs  uniform vec3 camPosLocal; -uniform vec4 lightnorm; -uniform vec4 sunlight_color; -uniform vec4 moonlight_color; -uniform int sun_up_factor; -uniform vec4 ambient_color; -uniform vec4 blue_horizon; -uniform vec4 blue_density; +uniform vec4  lightnorm; +uniform vec4  sunlight_color; +uniform vec4  moonlight_color; +uniform int   sun_up_factor; +uniform vec4  ambient_color; +uniform vec4  blue_horizon; +uniform vec4  blue_density;  uniform float haze_horizon;  uniform float haze_density; @@ -59,141 +60,133 @@ uniform float cloud_shadow;  uniform float density_multiplier;  uniform float max_y; -uniform vec4 glow; +uniform vec4  glow;  uniform float sun_moon_glow_factor;  uniform vec4 cloud_color;  uniform float cloud_scale; +// NOTE: Keep these in sync! +//       indra\newview\app_settings\shaders\class1\deferred\skyV.glsl +//       indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl +//       indra\newview\app-settings\shaders\class2\windlight\cloudsV.glsl +//       indra\newview\lllegacyatmospherics.cpp +//       indra\newview\llsettingsvo.cpp  void main()  { +    // World / view / projection +    gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + +    // Texture coords +    // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll +    vary_texcoord0 = vec2(-texcoord0.x, texcoord0.y);  // See: LLSettingsVOSky::applySpecial -	// World / view / projection -	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); +    vary_texcoord0.xy -= 0.5; +    vary_texcoord0.xy /= cloud_scale; +    vary_texcoord0.xy += 0.5; -	vary_texcoord0 = texcoord0; +    vary_texcoord1 = vary_texcoord0; +    vary_texcoord1.x += lightnorm.x * 0.0125; +    vary_texcoord1.y += lightnorm.z * 0.0125; -	// Get relative position -	vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0); +    vary_texcoord2 = vary_texcoord0 * 16.; +    vary_texcoord3 = vary_texcoord1 * 16.; + +    // Get relative position +    vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);      // fade clouds beyond a certain point so the bottom of the sky dome doesn't look silly at high altitude -    altitude_blend_factor = clamp((P.y + 512.0) / max_y, 0.0, 1.0); - -	// Set altitude -	if (P.y > 0.) -	{ -		P *= (max_y / P.y); -	} -	else -	{ -		P *= (-32000. / P.y); -	} - -	// Can normalize then -	vec3 Pn = normalize(P); -	float  Plen = length(P); - -	// Initialize temp variables -	vec4 temp1 = vec4(0.); -	vec4 temp2 = vec4(0.); -	vec4 blue_weight; -	vec4 haze_weight; -	//vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color; -	vec4 sunlight = sunlight_color; -	vec4 light_atten; - -    float dens_mul = density_multiplier; - -	// 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)) * (dens_mul * max_y); - -	// Calculate relative weights -	temp1 = abs(blue_density) + vec4(abs(haze_density)); -	blue_weight = blue_density / temp1; -	haze_weight = haze_density / temp1; - -	// Compute sunlight from P & lightnorm (for long rays like sky) -	temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y ); -	temp2.y = 1. / temp2.y; -	sunlight *= exp( - light_atten * temp2.y); - -	// Distance -	temp2.z = Plen * dens_mul; - -	// Transparency (-> temp1) -	// ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati -	// compiler gets confused. -	temp1 = exp(-temp1 * temp2.z); - - -	// Compute haze glow -	temp2.x = dot(Pn, lightnorm.xyz); -	temp2.x = 1. - temp2.x; -		// temp2.x is 0 at the sun and increases away from sun -	temp2.x = max(temp2.x, .001);	 -		// 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 - -    temp2.x *= sun_moon_glow_factor; - -	// Add "minimum anti-solar illumination" -	temp2.x += .25; - -	// Increase ambient when there are more clouds -	vec4 tmpAmbient = ambient_color; -	tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;  - -	// Dim sunlight by cloud shadow percentage -	sunlight *= (1. - cloud_shadow); - -	// Haze color below cloud -	vec4 additiveColorBelowCloud = (	  blue_horizon * blue_weight * (sunlight + tmpAmbient) -				+ (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient) -			 );	 - -	// CLOUDS -	temp2.y = max(0., lightnorm.y * 2.); -	temp2.y = 1. / temp2.y; -	sunlight *= exp( - light_atten * temp2.y); - -	// Cloud color out -	vary_CloudColorSun = (sunlight * temp2.x) * cloud_color; -	vary_CloudColorAmbient = tmpAmbient * cloud_color; -	 -	// Attenuate cloud color by atmosphere -	temp1 = sqrt(temp1);	//less atmos opacity (more transparency) below clouds -	vary_CloudColorSun *= temp1; -	vary_CloudColorAmbient *= temp1; -	vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - temp1); - -	// Make a nice cloud density based on the cloud_shadow value that was passed in. -	vary_CloudDensity = 2. * (cloud_shadow - 0.25); - - -	// Texture coords -	vary_texcoord0 = texcoord0; -	vary_texcoord0.xy -= 0.5; -	vary_texcoord0.xy /= cloud_scale; -	vary_texcoord0.xy += 0.5; - -	vary_texcoord1 = vary_texcoord0; -	vary_texcoord1.x += lightnorm.x * 0.0125; -	vary_texcoord1.y += lightnorm.z * 0.0125; - -	vary_texcoord2 = vary_texcoord0 * 16.; -	vary_texcoord3 = vary_texcoord1 * 16.; - -	// Combine these to minimize register use -	vary_CloudColorAmbient += oHazeColorBelowCloud; - -	// needs this to compile on mac -	//vary_AtmosAttenuation = vec3(0.0,0.0,0.0); - -	// END CLOUDS +    altitude_blend_factor = clamp((rel_pos.y + 512.0) / max_y, 0.0, 1.0); + +    // Adj position vector to clamp altitude +    if (rel_pos.y > 0.) +    { +        rel_pos *= (max_y / rel_pos.y); +    } +    if (rel_pos.y < 0.) +    { +        rel_pos *= (-32000. / rel_pos.y); +    } + +    // Can normalize then +    vec3  rel_pos_norm = normalize(rel_pos); +    float rel_pos_len  = length(rel_pos); + +    // Initialize temp variables +    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); + +    // Calculate relative weights +    vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density)); +    vec4 blue_weight   = blue_density / combined_haze; +    vec4 haze_weight   = haze_density / combined_haze; + +    // Compute sunlight from rel_pos & lightnorm (for long rays like sky) +    float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y); +    sunlight *= exp(-light_atten * off_axis); + +    // Distance +    float density_dist = rel_pos_len * density_multiplier; + +    // Transparency (-> combined_haze) +    // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati +    // compiler gets confused. +    combined_haze = exp(-combined_haze * density_dist); + +    // Compute haze glow +    float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz); +    // haze_glow is 0 at the sun and increases away from sun +    haze_glow = max(haze_glow, .001); +    // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) +    haze_glow *= glow.x; +    // Higher glow.x gives dimmer glow (because next step is 1 / "angle") +    haze_glow = pow(haze_glow, glow.z); +    // glow.z should be negative, so we're doing a sort of (1 / "angle") function + +    haze_glow *= sun_moon_glow_factor; + +    // Add "minimum anti-solar illumination" +    // For sun, add to glow.  For moon, remove glow entirely. SL-13768 +    haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25); + +    // Increase ambient when there are more clouds +    vec4 tmpAmbient = ambient_color; +    tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5; + +    // Dim sunlight by cloud shadow percentage +    sunlight *= (1. - cloud_shadow); + +    // Haze color below cloud +    vec4 additiveColorBelowCloud = +        (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient)); + +    // CLOUDS +    off_axis = 1.0 / max(1e-6, lightnorm.y * 2.); +    sunlight *= exp(-light_atten * off_axis); + +    // Cloud color out +    vary_CloudColorSun     = (sunlight * haze_glow) * cloud_color; +    vary_CloudColorAmbient = tmpAmbient * cloud_color; + +    // Attenuate cloud color by atmosphere +    combined_haze = sqrt(combined_haze);  // less atmos opacity (more transparency) below clouds +    vary_CloudColorSun *= combined_haze; +    vary_CloudColorAmbient *= combined_haze; +    vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - combined_haze); + +    // Make a nice cloud density based on the cloud_shadow value that was passed in. +    vary_CloudDensity = 2. * (cloud_shadow - 0.25); + +    // Combine these to minimize register use +    vary_CloudColorAmbient += oHazeColorBelowCloud; + +    // needs this to compile on mac +    // vary_AtmosAttenuation = vec3(0.0,0.0,0.0); + +    // END CLOUDS  } - diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl index 0d141342ce..a0a33b8642 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl @@ -1,28 +1,28 @@ -/**  +/**   * @file class2\wl\skyV.glsl   *   * $LicenseInfo:firstyear=2005&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2005, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ -  +  uniform mat4 modelview_projection_matrix;  ATTRIBUTE vec3 position; @@ -37,13 +37,13 @@ VARYING vec4 vary_HazeColor;  // Inputs  uniform vec3 camPosLocal; -uniform vec4 lightnorm; -uniform vec4 sunlight_color; -uniform vec4 moonlight_color; -uniform int sun_up_factor; -uniform vec4 ambient_color; -uniform vec4 blue_horizon; -uniform vec4 blue_density; +uniform vec4  lightnorm; +uniform vec4  sunlight_color; +uniform vec4  moonlight_color; +uniform int   sun_up_factor; +uniform vec4  ambient_color; +uniform vec4  blue_horizon; +uniform vec4  blue_density;  uniform float haze_horizon;  uniform float haze_density; @@ -52,110 +52,98 @@ uniform float density_multiplier;  uniform float distance_multiplier;  uniform float max_y; -uniform vec4 glow; +uniform vec4  glow;  uniform float sun_moon_glow_factor;  uniform vec4 cloud_color;  void main()  { - -	// World / view / projection +    // World / view / projection      vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0); -	gl_Position = pos; -	 -	// Get relative position -	vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0); - -	// Set altitude -	if (P.y > 0.) -	{ -		P *= (max_y / P.y); -	} -	else -	{ -		P *= (-32000. / P.y); -	} - -	// Can normalize then -	vec3 Pn = normalize(P); - -	float Plen = length(P); - -	// Initialize temp variables -	vec4 temp1 = vec4(0.); -	vec4 temp2 = vec4(0.); -	vec4 blue_weight; -	vec4 haze_weight; -	vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color; -	vec4 light_atten; - -    float dens_mul = density_multiplier; - -	// 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)) * (dens_mul * max_y); - -	// Calculate relative weights -	temp1 = abs(blue_density) + vec4(abs(haze_density)); -	blue_weight = blue_density / temp1; -	haze_weight = haze_density / temp1; - -	// Compute sunlight from P & lightnorm (for long rays like sky) -    temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y ); -    temp2.y = 1. / temp2.y; -    sunlight *= exp( - light_atten * temp2.y); - -	// Distance -	temp2.z = Plen * dens_mul; - -	// Transparency (-> temp1) -    // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati -    // compiler gets confused. -    temp1 = exp(-temp1 * temp2.z); +    gl_Position = pos; + +    // Get relative position +    vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0); + +    // Adj position vector to clamp altitude +    if (rel_pos.y > 0.) +    { +        rel_pos *= (max_y / rel_pos.y); +    } +    if (rel_pos.y < 0.) +    { +        rel_pos *= (-32000. / rel_pos.y); +    } -	// Compute haze glow -	temp2.x = dot(Pn, lightnorm.xyz); -	temp2.x = 1. - temp2.x; -		// temp2.x is 0 at the sun and increases away from sun -	temp2.x = max(temp2.x, .001);	 -		// 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 +    // Can normalize then +    vec3 rel_pos_norm = normalize(rel_pos); -	// Add "minimum anti-solar illumination" -	temp2.x += .25; +    float rel_pos_len = length(rel_pos); -    vec4 color = (    blue_horizon * blue_weight * (sunlight + ambient_color) -                + (haze_horizon * haze_weight) * (sunlight * temp2.x + ambient_color) -             ); +    // Initialize temp variables +    vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_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); + +    // Calculate relative weights +    vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density)); +    vec4 blue_weight   = blue_density / combined_haze; +    vec4 haze_weight   = haze_density / combined_haze; + +    // Compute sunlight from rel_pos & lightnorm (for long rays like sky) +    float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y); +    sunlight *= exp(-light_atten * off_axis); + +    // Distance +    float density_dist = rel_pos_len * density_multiplier; + +    // Transparency (-> combined_haze) +    // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati +    // compiler gets confused. +    combined_haze = exp(-combined_haze * density_dist); + +    // Compute haze glow +    float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz); +    // haze_glow is 0 at the sun and increases away from sun +    haze_glow = max(haze_glow, .001); +    // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) +    haze_glow *= glow.x; +    // Higher glow.x gives dimmer glow (because next step is 1 / "angle") +    haze_glow = pow(haze_glow, glow.z); +    // glow.z should be negative, so we're doing a sort of (1 / "angle") function + +    // Add "minimum anti-solar illumination" +    // For sun, add to glow.  For moon, remove glow entirely. SL-13768 +    haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25); + +    vec4 color = +        (blue_horizon * blue_weight * (sunlight + ambient_color) + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color));      // Final atmosphere additive -    color *= (1. - temp1); +    color *= (1. - combined_haze); -	// Increase ambient when there are more clouds -	vec4 tmpAmbient = ambient_color; -	tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;  +    // Increase ambient when there are more clouds +    vec4 tmpAmbient = ambient_color; +    tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5; -	// Dim sunlight by cloud shadow percentage -	sunlight *= max(0.0, (1. - cloud_shadow)); +    // Dim sunlight by cloud shadow percentage +    sunlight *= max(0.0, (1. - cloud_shadow)); -	// Haze color below cloud -	vec4 additiveColorBelowCloud = (	  blue_horizon * blue_weight * (sunlight + tmpAmbient) -				+ (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient) -			 );	 +    // Haze color below cloud +    vec4 additiveColorBelowCloud = +        (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient)); -	// Attenuate cloud color by atmosphere -	temp1 = sqrt(temp1);	//less atmos opacity (more transparency) below clouds +    // Attenuate cloud color by atmosphere +    combined_haze = sqrt(combined_haze);  // less atmos opacity (more transparency) below clouds -	// At horizon, blend high altitude sky color towards the darker color below the clouds -	color += (additiveColorBelowCloud - color) * (1. - sqrt(temp1)); +    // At horizon, blend high altitude sky color towards the darker color below the clouds +    color += (additiveColorBelowCloud - color) * (1. - sqrt(combined_haze));      // Haze color above cloud -	vary_HazeColor = color;	 +    vary_HazeColor = color;  } - diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f745bbde25..70b41a0a5f 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -73,6 +73,7 @@  #include "llviewermedia.h"  #include "llviewerparcelaskplay.h"  #include "llviewerparcelmedia.h" +#include "llviewershadermgr.h"  #include "llviewermediafocus.h"  #include "llviewermessage.h"  #include "llviewerobjectlist.h" @@ -688,8 +689,7 @@ LLAppViewer::LLAppViewer()  	mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)),  	mFastTimerLogThread(NULL),  	mSettingsLocationList(NULL), -	mIsFirstRun(false), -	mMinMicroSecPerFrame(0.f) +	mIsFirstRun(false)  {  	if(NULL != sInstance)  	{ @@ -1258,10 +1258,6 @@ bool LLAppViewer::init()  	joystick = LLViewerJoystick::getInstance();  	joystick->setNeedsReset(true); -	/*----------------------------------------------------------------------*/ - -	gSavedSettings.getControl("FramePerSecondLimit")->getSignal()->connect(boost::bind(&LLAppViewer::onChangeFrameLimit, this, _2)); -	onChangeFrameLimit(gSavedSettings.getLLSD("FramePerSecondLimit"));  	return true;  } @@ -1481,21 +1477,6 @@ bool LLAppViewer::doFrame()  				display(); -				static U64 last_call = 0; -				if (!gTeleportDisplay || gGLManager.mIsIntel) // SL-10625...throttle early, throttle often with Intel -				{ -					// Frame/draw throttling -					U64 elapsed_time = LLTimer::getTotalTime() - last_call; -					if (elapsed_time < mMinMicroSecPerFrame) -					{ -						LL_RECORD_BLOCK_TIME(FTM_SLEEP); -						// llclamp for when time function gets funky -						U64 sleep_time = llclamp(mMinMicroSecPerFrame - elapsed_time, (U64)1, (U64)1e6); -						micro_sleep(sleep_time, 0); -					} -				} -				last_call = LLTimer::getTotalTime(); -  				pingMainloopTimeout("Main:Snapshot");  				LLFloaterSnapshot::update(); // take snapshots  					LLFloaterOutfitSnapshot::update(); @@ -5436,19 +5417,6 @@ void LLAppViewer::disconnectViewer()  	LLUrlEntryParcel::setDisconnected(gDisconnected);  } -bool LLAppViewer::onChangeFrameLimit(LLSD const & evt) -{ -	if (evt.asInteger() > 0) -	{ -		mMinMicroSecPerFrame = (U64)(1000000.0f / F32(evt.asInteger())); -	} -	else -	{ -		mMinMicroSecPerFrame = 0; -	} -	return false; -} -  void LLAppViewer::forceErrorLLError()  {     	LL_ERRS() << "This is a deliberate llerror" << LL_ENDL; diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index e8b3464c6e..8f0f54de3b 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -255,8 +255,6 @@ private:      void sendLogoutRequest();      void disconnectViewer(); -	bool onChangeFrameLimit(LLSD const & evt); -  	// *FIX: the app viewer class should be some sort of singleton, no?  	// Perhaps its child class is the singleton and this should be an abstract base.  	static LLAppViewer* sInstance;  @@ -313,10 +311,7 @@ private:  	// llcorehttp library init/shutdown helper  	LLAppCoreHttp mAppCoreHttp; -        bool mIsFirstRun; -	U64 mMinMicroSecPerFrame; // frame throttling - - +    bool mIsFirstRun;  };  // consts from viewer.h diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 8c6cbc020b..2219f20272 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -1178,11 +1178,33 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()  	}  	else if (isRoot())  	{ -		if (mSpatialBridge && (mSpatialBridge->asPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD) != mVObjp->isHUDAttachment()) +		if (mSpatialBridge)  		{ -			// remove obsolete bridge -			mSpatialBridge->markDead(); -			setSpatialBridge(NULL); +			U32 partition_type = mSpatialBridge->asPartition()->mPartitionType; +			bool is_hud = mVObjp->isHUDAttachment(); +			bool is_animesh = mVObjp->isAnimatedObject() && mVObjp->getControlAvatar() != NULL; +			bool is_attachment = mVObjp->isAttachment() && !is_hud && !is_animesh; +			if ((partition_type == LLViewerRegion::PARTITION_HUD) != is_hud) +			{ +				// Was/became HUD +				// remove obsolete bridge +				mSpatialBridge->markDead(); +				setSpatialBridge(NULL); +			} +			else if ((partition_type == LLViewerRegion::PARTITION_CONTROL_AV) != is_animesh) +			{ +				// Was/became part of animesh +				// remove obsolete bridge +				mSpatialBridge->markDead(); +				setSpatialBridge(NULL); +			} +			else if ((partition_type == LLViewerRegion::PARTITION_AVATAR) != is_attachment) +			{ +				// Was/became part of avatar +				// remove obsolete bridge +				mSpatialBridge->markDead(); +				setSpatialBridge(NULL); +			}  		}  		//must be an active volume  		if (!mSpatialBridge) @@ -1191,6 +1213,15 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()  			{  				setSpatialBridge(new LLHUDBridge(this, getRegion()));  			} +			else if (mVObjp->isAnimatedObject() && mVObjp->getControlAvatar()) +			{ +				setSpatialBridge(new LLControlAVBridge(this, getRegion())); +			} +			// check HUD first, because HUD is also attachment +			else if (mVObjp->isAttachment()) +			{ +				setSpatialBridge(new LLAvatarBridge(this, getRegion())); +			}  			else  			{  				setSpatialBridge(new LLVolumeBridge(this, getRegion())); @@ -1698,12 +1729,26 @@ void LLDrawable::updateFaceSize(S32 idx)  LLBridgePartition::LLBridgePartition(LLViewerRegion* regionp)  : LLSpatialPartition(0, FALSE, 0, regionp)   {  -	mDrawableType = LLPipeline::RENDER_TYPE_AVATAR;  +	mDrawableType = LLPipeline::RENDER_TYPE_VOLUME;   	mPartitionType = LLViewerRegion::PARTITION_BRIDGE;  	mLODPeriod = 16;  	mSlopRatio = 0.25f;  } +LLAvatarPartition::LLAvatarPartition(LLViewerRegion* regionp) +	: LLBridgePartition(regionp) +{ +	mDrawableType = LLPipeline::RENDER_TYPE_AVATAR; +	mPartitionType = LLViewerRegion::PARTITION_AVATAR; +} + +LLControlAVPartition::LLControlAVPartition(LLViewerRegion* regionp) +	: LLBridgePartition(regionp) +{ +	mDrawableType = LLPipeline::RENDER_TYPE_CONTROL_AV; +	mPartitionType = LLViewerRegion::PARTITION_CONTROL_AV; +} +  LLHUDBridge::LLHUDBridge(LLDrawable* drawablep, LLViewerRegion* regionp)  : LLVolumeBridge(drawablep, regionp)  { diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 2aee7b450a..d583a692f9 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -86,7 +86,8 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)  		poolp = new LLDrawPoolAlpha();  		break;  	case POOL_AVATAR: -		poolp = new LLDrawPoolAvatar(); +	case POOL_CONTROL_AV: +		poolp = new LLDrawPoolAvatar(type);  		break;  	case POOL_TREE:  		poolp = new LLDrawPoolTree(tex0); @@ -383,16 +384,6 @@ LLRenderPass::~LLRenderPass()  } -LLDrawPool* LLRenderPass::instancePool() -{ -#if LL_RELEASE_FOR_DOWNLOAD -	LL_WARNS() << "Attempting to instance a render pass.  Invalid operation." << LL_ENDL; -#else -	LL_ERRS() << "Attempting to instance a render pass.  Invalid operation." << LL_ENDL; -#endif -	return NULL; -} -  void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture)  {					  	LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; @@ -449,7 +440,7 @@ void LLRenderPass::applyModelMatrix(const LLDrawInfo& params)  	if (params.mModelMatrix != gGLLastMatrix)  	{  		gGLLastMatrix = params.mModelMatrix; -        gGL.matrixMode(LLRender::MM_MODELVIEW); +		gGL.matrixMode(LLRender::MM_MODELVIEW);  		gGL.loadMatrix(gGLModelView);  		if (params.mModelMatrix)  		{ diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index b8562e9077..ecd9bd034f 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -60,6 +60,7 @@ public:  		POOL_GRASS,  		POOL_INVISIBLE, // see below *  		POOL_AVATAR, +		POOL_CONTROL_AV, // Animesh  		POOL_VOIDWATER,  		POOL_WATER,  		POOL_GLOW, @@ -110,7 +111,6 @@ public:  	virtual S32 getShaderLevel() const { return mShaderLevel; }  	static LLDrawPool* createPool(const U32 type, LLViewerTexture *tex0 = NULL); -	virtual LLDrawPool *instancePool() = 0;	// Create an empty new instance of the pool.  	virtual LLViewerTexture* getTexture() = 0;  	virtual BOOL isFacePool() { return FALSE; }  	virtual void resetDrawOrders() = 0; @@ -162,7 +162,6 @@ public:  	LLRenderPass(const U32 type);  	virtual ~LLRenderPass(); -	/*virtual*/ LLDrawPool* instancePool();  	/*virtual*/ LLViewerTexture* getDebugTexture() { return NULL; }  	LLViewerTexture* getTexture() { return NULL; }  	BOOL isDead() { return FALSE; } diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index f3e922ce8e..6fc39f213e 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -106,8 +106,8 @@ S32 cube_channel = -1;  static LLTrace::BlockTimerStatHandle FTM_SHADOW_AVATAR("Avatar Shadow"); -LLDrawPoolAvatar::LLDrawPoolAvatar() :  -	LLFacePool(POOL_AVATAR)	 +LLDrawPoolAvatar::LLDrawPoolAvatar(U32 type) :  +	LLFacePool(type)	  {  } @@ -136,15 +136,6 @@ BOOL LLDrawPoolAvatar::isDead()      }      return TRUE;  } -  -//----------------------------------------------------------------------------- -// instancePool() -//----------------------------------------------------------------------------- -LLDrawPool *LLDrawPoolAvatar::instancePool() -{ -	return new LLDrawPoolAvatar(); -} -  S32 LLDrawPoolAvatar::getShaderLevel() const  { @@ -1815,7 +1806,7 @@ void LLDrawPoolAvatar::getRiggedGeometry(  	}  	else  	{ -		face->setPoolType(LLDrawPool::POOL_AVATAR); +		face->setPoolType(mType); // either POOL_AVATAR or POOL_CONTROL_AV  	}  	//LL_INFOS() << "Rebuilt face " << face->getTEOffset() << " of " << face->getDrawable() << " at " << gFrameTimeSeconds << LL_ENDL; @@ -2499,7 +2490,7 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const  void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type)  {      llassert (facep->isState(LLFace::RIGGED)); -    llassert(getType() == LLDrawPool::POOL_AVATAR); +    llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV);      if (facep->getPool() && facep->getPool() != this)      {          LL_ERRS() << "adding rigged face that's already in another pool" << LL_ENDL; @@ -2521,7 +2512,7 @@ void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type)  void LLDrawPoolAvatar::removeRiggedFace(LLFace* facep)  {      llassert (facep->isState(LLFace::RIGGED)); -    llassert(getType() == LLDrawPool::POOL_AVATAR); +    llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV);      if (facep->getPool() != this)      {          LL_ERRS() << "Tried to remove a rigged face from the wrong pool" << LL_ENDL; diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index cb09eb18e2..92a8538958 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -178,12 +178,10 @@ typedef enum  	virtual S32 getShaderLevel() const; -	LLDrawPoolAvatar(); +	LLDrawPoolAvatar(U32 type);  	static LLMatrix4& getModelView(); -	/*virtual*/ LLDrawPool *instancePool(); -  	/*virtual*/ S32  getNumPasses();  	/*virtual*/ void beginRenderPass(S32 pass);  	/*virtual*/ void endRenderPass(S32 pass); diff --git a/indra/newview/lldrawpoolground.cpp b/indra/newview/lldrawpoolground.cpp index 6bd2631d3b..5b74264dab 100644 --- a/indra/newview/lldrawpoolground.cpp +++ b/indra/newview/lldrawpoolground.cpp @@ -46,11 +46,6 @@ LLDrawPoolGround::LLDrawPoolGround() :  {  } -LLDrawPool *LLDrawPoolGround::instancePool() -{ -	return new LLDrawPoolGround(); -} -  void LLDrawPoolGround::prerender()  {  	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT); diff --git a/indra/newview/lldrawpoolground.h b/indra/newview/lldrawpoolground.h index a4f8a3fcf5..15b1dc60a2 100644 --- a/indra/newview/lldrawpoolground.h +++ b/indra/newview/lldrawpoolground.h @@ -43,8 +43,6 @@ public:  	LLDrawPoolGround(); -	/*virtual*/ LLDrawPool *instancePool(); -  	/*virtual*/ void prerender();  	/*virtual*/ void render(S32 pass = 0);  }; diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp index dbe8724088..b6f55e800a 100644 --- a/indra/newview/lldrawpoolsky.cpp +++ b/indra/newview/lldrawpoolsky.cpp @@ -48,11 +48,6 @@ LLDrawPoolSky::LLDrawPoolSky()  {  } -LLDrawPool *LLDrawPoolSky::instancePool() -{ -	return new LLDrawPoolSky(); -} -  void LLDrawPoolSky::prerender()  {  	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);  @@ -128,23 +123,12 @@ void LLDrawPoolSky::renderSkyFace(U8 index)  		return;  	} -    F32 interp_val = gSky.mVOSkyp ? gSky.mVOSkyp->getInterpVal() : 0.0f; -      if (index < 6) // sky tex...interp      {          llassert(mSkyTex);  	    mSkyTex[index].bindTexture(true); // bind the current tex          face->renderIndexed(); - -        if (interp_val > 0.01f) // iff, we've got enough info to lerp (a to and a from) -	    { -		    LLGLEnable blend(GL_BLEND); -            llassert(mSkyTex); -	        mSkyTex[index].bindTexture(false); // bind the "other" texture -		    gGL.diffuseColor4f(1, 1, 1, interp_val); // lighting is disabled -		    face->renderIndexed(); -	    }      }      else // heavenly body faces, no interp...      { diff --git a/indra/newview/lldrawpoolsky.h b/indra/newview/lldrawpoolsky.h index 916d8c1cbe..d1dcd6b22e 100644 --- a/indra/newview/lldrawpoolsky.h +++ b/indra/newview/lldrawpoolsky.h @@ -49,8 +49,6 @@ public:  	LLDrawPoolSky(); -	/*virtual*/ LLDrawPool *instancePool(); -  	/*virtual*/ S32 getNumPostDeferredPasses() { return getNumPasses(); }  	/*virtual*/ void beginPostDeferredPass(S32 pass) { beginRenderPass(pass); }  	/*virtual*/ void endPostDeferredPass(S32 pass) { endRenderPass(pass); } diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 33a11631fe..37dc80e2b7 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -87,13 +87,6 @@ LLDrawPoolTerrain::~LLDrawPoolTerrain()  	llassert( gPipeline.findPool( getType(), getTexture() ) == NULL );  } - -LLDrawPool *LLDrawPoolTerrain::instancePool() -{ -	return new LLDrawPoolTerrain(mTexturep); -} - -  U32 LLDrawPoolTerrain::getVertexDataMask()   {   	if (LLPipeline::sShadowRender) diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 04e27d9370..5b4558020d 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -49,8 +49,6 @@ public:  	LLDrawPoolTerrain(LLViewerTexture *texturep);  	virtual ~LLDrawPoolTerrain(); -	/*virtual*/ LLDrawPool *instancePool(); -  	/*virtual*/ S32 getNumDeferredPasses() { return 1; }  	/*virtual*/ void beginDeferredPass(S32 pass);  	/*virtual*/ void endDeferredPass(S32 pass); diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index b885008cae..0d5195bdbf 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -51,11 +51,6 @@ LLDrawPoolTree::LLDrawPoolTree(LLViewerTexture *texturep) :  	mTexturep->setAddressMode(LLTexUnit::TAM_WRAP);  } -LLDrawPool *LLDrawPoolTree::instancePool() -{ -	return new LLDrawPoolTree(mTexturep); -} -  void LLDrawPoolTree::prerender()  {  	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); diff --git a/indra/newview/lldrawpooltree.h b/indra/newview/lldrawpooltree.h index 9c1e60f5eb..13f9ec8dce 100644 --- a/indra/newview/lldrawpooltree.h +++ b/indra/newview/lldrawpooltree.h @@ -45,8 +45,6 @@ public:  	LLDrawPoolTree(LLViewerTexture *texturep); -	/*virtual*/ LLDrawPool *instancePool(); -  	/*virtual*/ void prerender();  	/*virtual*/ S32 getNumDeferredPasses() { return 1; } diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 073adfb627..7249f22555 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -104,13 +104,6 @@ void LLDrawPoolWater::restoreGL()      }*/  } -LLDrawPool *LLDrawPoolWater::instancePool() -{ -	LL_ERRS() << "Should never be calling instancePool on a water pool!" << LL_ENDL; -	return NULL; -} - -  void LLDrawPoolWater::prerender()  {  	mShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0; diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h index d436557e1c..a5d163e0d7 100644 --- a/indra/newview/lldrawpoolwater.h +++ b/indra/newview/lldrawpoolwater.h @@ -61,7 +61,6 @@ public:  	LLDrawPoolWater();  	/*virtual*/ ~LLDrawPoolWater(); -	/*virtual*/ LLDrawPool *instancePool();  	static void restoreGL();  	/*virtual*/ S32 getNumPostDeferredPasses() { return 0; } //getNumPasses(); } diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 961d72c62e..d4e7f1600e 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -216,10 +216,11 @@ void LLDrawPoolWLSky::renderSkyHaze(const LLVector3& camPosLocal, F32 camHeightL  	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))  	{ +        LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();          LLGLSPipelineDepthTestSkyBox sky(true, false);          sky_shader->bind();          sky_shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, 1); -        sky_shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, 1.0f); +        sky_shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor());          renderDome(origin, camHeightLocal, sky_shader);	  		sky_shader->unbind();      } @@ -531,8 +532,6 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()          }  	} -    blend_factor = LLEnvironment::instance().getCurrentSky()->getBlendFactor(); -  	face = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON];  	if (gSky.mVOSkyp->getMoon().getDraw() && face && face->getTexture(LLRender::DIFFUSE_MAP) && face->getGeomCount() && moon_shader) @@ -550,17 +549,17 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()              {                  // Bind current and next sun textures                  moon_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, tex_a, LLTexUnit::TT_TEXTURE); -                blend_factor = 0; +                //blend_factor = 0;              }              else if (tex_b && !tex_a)              {                  moon_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, tex_b, LLTexUnit::TT_TEXTURE); -                blend_factor = 0; +                //blend_factor = 0;              }              else if (tex_b != tex_a)              {                  moon_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, tex_a, LLTexUnit::TT_TEXTURE); -                moon_shader->bindTexture(LLShaderMgr::ALTERNATE_DIFFUSE_MAP, tex_b, LLTexUnit::TT_TEXTURE); +                //moon_shader->bindTexture(LLShaderMgr::ALTERNATE_DIFFUSE_MAP, tex_b, LLTexUnit::TT_TEXTURE);              }              LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); @@ -570,7 +569,8 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()              moon_shader->uniform1f(LLShaderMgr::MOON_BRIGHTNESS, moon_brightness);              moon_shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, gSky.mVOSkyp->getMoon().getColor().mV);              moon_shader->uniform4fv(LLShaderMgr::DIFFUSE_COLOR, 1, color.mV); -            moon_shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor); +            //moon_shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor); +            moon_shader->uniform3fv(LLShaderMgr::DEFERRED_MOON_DIR, 1, psky->getMoonDirection().mV); // shader: moon_dir              face->renderIndexed(); @@ -632,11 +632,6 @@ void LLDrawPoolWLSky::prerender()  	//LL_INFOS() << "wlsky prerendering pass." << LL_ENDL;  } -LLDrawPoolWLSky *LLDrawPoolWLSky::instancePool() -{ -	return new LLDrawPoolWLSky(); -} -  LLViewerTexture* LLDrawPoolWLSky::getTexture()  {  	return NULL; diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h index 3acfda4eee..a4f176d6db 100644 --- a/indra/newview/lldrawpoolwlsky.h +++ b/indra/newview/lldrawpoolwlsky.h @@ -62,8 +62,6 @@ public:  	//static LLDrawPool* createPool(const U32 type, LLViewerTexture *tex0 = NULL); -	// Create an empty new instance of the pool. -	/*virtual*/ LLDrawPoolWLSky *instancePool();  ///< covariant override  	/*virtual*/ LLViewerTexture* getTexture();  	/*virtual*/ BOOL isFacePool() { return FALSE; }  	/*virtual*/ void resetDrawOrders(); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 36832d85fd..4a802ad9aa 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -196,7 +196,7 @@ void LLFace::destroy()  	if (mDrawPoolp)  	{ -		if (this->isState(LLFace::RIGGED) && mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR) +		if (this->isState(LLFace::RIGGED) && (mDrawPoolp->getType() == LLDrawPool::POOL_CONTROL_AV || mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR))  		{  			((LLDrawPoolAvatar*) mDrawPoolp)->removeRiggedFace(this);  		} diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index bd834b4260..82ce97f311 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -57,6 +57,9 @@  #include "llviewerobjectlist.h"  #include "boost/foreach.hpp" + +const S32 EVENTS_PER_IDLE_LOOP = 100; +  //  // LLFloaterIMContainer  // @@ -66,7 +69,8 @@ LLFloaterIMContainer::LLFloaterIMContainer(const LLSD& seed, const Params& param  	mConversationsRoot(NULL),  	mConversationsEventStream("ConversationsEvents"),  	mInitialized(false), -	mIsFirstLaunch(true) +	mIsFirstLaunch(true), +	mConversationEventQueue()  {      mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLFloaterIMContainer::isActionChecked, this, _2));  	mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLFloaterIMContainer::onCustomAction,  this, _2)); @@ -424,7 +428,9 @@ void LLFloaterIMContainer::idle(void* user_data)  {  	LLFloaterIMContainer* self = static_cast<LLFloaterIMContainer*>(user_data); -    if (!self->getVisible() || self->isMinimized()) +	self->idleProcessEvents(); + +	if (!self->getVisible() || self->isMinimized())      {          return;      } @@ -485,13 +491,28 @@ void LLFloaterIMContainer::idleUpdate()      }  } +void LLFloaterIMContainer::idleProcessEvents() +{ +	if (!mConversationEventQueue.empty()) +	{ +		S32 events_to_handle = llmin((S32)mConversationEventQueue.size(), EVENTS_PER_IDLE_LOOP); +		for (S32 i = 0; i < events_to_handle; i++) +		{ +			handleConversationModelEvent(mConversationEventQueue.back()); +			mConversationEventQueue.pop_back(); +		} +	} +} +  bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)  { -	// For debug only -	//std::ostringstream llsd_value; -	//llsd_value << LLSDOStreamer<LLSDNotationFormatter>(event) << std::endl; -	//LL_INFOS() << "LLFloaterIMContainer::onConversationModelEvent, event = " << llsd_value.str() << LL_ENDL; -	// end debug +	mConversationEventQueue.push_front(event); +	return true; +} + + +void LLFloaterIMContainer::handleConversationModelEvent(const LLSD& event) +{  	// Note: In conversations, the model is not responsible for creating the view, which is a good thing. This means that  	// the model could change substantially and the view could echo only a portion of this model (though currently the  @@ -508,7 +529,7 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)  	if (!session_view)  	{  		// We skip events that are not associated with a session -		return false; +		return;  	}  	LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);      LLFloaterIMSessionTab *conversation_floater = (session_id.isNull() ? @@ -535,9 +556,9 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)  	{  		LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(mConversationsItems[session_id]);  		LLConversationItemParticipant* participant_model = (session_model ? session_model->findParticipant(participant_id) : NULL); +		LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(session_id);  		if (!participant_view && session_model && participant_model) -		{ -			LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(session_id); +		{	  			if (session_id.isNull() || (im_sessionp && !im_sessionp->isP2PSessionType()))  			{  				participant_view = createConversationViewParticipant(participant_model); @@ -548,7 +569,8 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)  		// Add a participant view to the conversation floater   		if (conversation_floater && participant_model)  		{ -			conversation_floater->addConversationViewParticipant(participant_model); +			bool skip_updating = im_sessionp && im_sessionp->isGroupChat(); +			conversation_floater->addConversationViewParticipant(participant_model, !skip_updating);  		}  	}  	else if (type == "update_participant") @@ -571,12 +593,6 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)  	mConversationViewModel.requestSortAll();  	mConversationsRoot->arrangeAll(); -	if (conversation_floater) -	{ -		conversation_floater->refreshConversation(); -	} -	 -	return false;  }  void LLFloaterIMContainer::draw() diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h index 0f7d0a557e..468b47f1f1 100644 --- a/indra/newview/llfloaterimcontainer.h +++ b/indra/newview/llfloaterimcontainer.h @@ -181,6 +181,7 @@ private:  	bool isParticipantListExpanded();  	void idleUpdate(); // for convenience (self) from static idle +	void idleProcessEvents();  	LLButton* mExpandCollapseBtn;  	LLButton* mStubCollapseBtn; @@ -220,6 +221,7 @@ private:  	LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);  	LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item);  	bool onConversationModelEvent(const LLSD& event); +	void handleConversationModelEvent(const LLSD& event);  	// Conversation list data  	LLPanel* mConversationsListPanel;	// This is the main widget we add conversation widget to @@ -229,6 +231,8 @@ private:  	LLFolderView* mConversationsRoot;  	LLEventStream mConversationsEventStream;  +	std::deque<LLSD> mConversationEventQueue; +  	LLTimer mParticipantRefreshTimer;  }; diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 3aee08482b..d604d0a789 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -465,9 +465,10 @@ void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD &args)  	}  } - +static LLTrace::BlockTimerStatHandle FTM_BUILD_CONVERSATION_VIEW_PARTICIPANT("Build Conversation View");  void LLFloaterIMSessionTab::buildConversationViewParticipant()  { +	LL_RECORD_BLOCK_TIME(FTM_BUILD_CONVERSATION_VIEW_PARTICIPANT);  	// Clear the widget list since we are rebuilding afresh from the model  	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();  	while (widget_it != mConversationsWidgets.end()) @@ -496,14 +497,20 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant()  	}  } -void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* participant_model) +void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* participant_model, bool update_view)  { +	if (!participant_model) +	{ +		// Nothing to do if the model is inexistent +		return; +	} +  	// Check if the model already has an associated view  	LLUUID uuid = participant_model->getUUID();  	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);  	// If not already present, create the participant view and attach it to the root, otherwise, just refresh it -	if (widget) +	if (widget && update_view)  	{  		updateConversationViewParticipant(uuid); // overkill?  	} @@ -524,8 +531,8 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part  	{  		mConversationsRoot->extractItem(widget);  		delete widget; -		mConversationsWidgets.erase(participant_id);  	} +	mConversationsWidgets.erase(participant_id);  }  void LLFloaterIMSessionTab::updateConversationViewParticipant(const LLUUID& participant_id) diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index 1b4922fd73..5357a14ab9 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -84,7 +84,7 @@ public:  	/*virtual*/ void setFocus(BOOL focus);  	// Handle the left hand participant list widgets -	void addConversationViewParticipant(LLConversationItem* item); +	void addConversationViewParticipant(LLConversationItem* item, bool update_view = true);  	void removeConversationViewParticipant(const LLUUID& participant_id);  	void updateConversationViewParticipant(const LLUUID& participant_id);  	void refreshConversation(); diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index d96014bd72..32f88b49ac 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -944,9 +944,13 @@ static void formatDateString(std::string &date_string)  	}  } +static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_MEMBERS_REPLY("Process Group Members"); +  // static  void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)  { +    LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_MEMBERS_REPLY); +  	LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupMembersReply" << LL_ENDL;  	LLUUID agent_id;  	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); @@ -1050,9 +1054,13 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)  	LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA);  } +static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_PROPERTIES_REPLY("Process Group Properties"); +  //static   void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data)  { +    LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_PROPERTIES_REPLY); +  	LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupPropertiesReply" << LL_ENDL;  	if (!msg)  	{ @@ -1131,10 +1139,13 @@ void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data)  	LLGroupMgr::getInstance()->notifyObservers(GC_PROPERTIES);  } +static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_ROLE_DATA_REPLY("Process Group Role Data");  // static  void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data)  { -    LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupRoleDataReply" << LL_ENDL; +    LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_ROLE_DATA_REPLY); + +	LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupRoleDataReply" << LL_ENDL;  	LLUUID agent_id;  	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );  	if (gAgent.getID() != agent_id) @@ -1216,9 +1227,12 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data)  	LLGroupMgr::getInstance()->notifyObservers(GC_ROLE_DATA);  } +static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_ROLE_MEMBERS_REPLY("Process Group Role Members");  // static  void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)  { +    LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_ROLE_MEMBERS_REPLY); +  	LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupRoleMembersReply" << LL_ENDL;  	LLUUID agent_id;  	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); @@ -1600,7 +1614,7 @@ void LLGroupMgr::sendGroupPropertiesRequest(const LLUUID& group_id)  	LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupPropertiesRequest" << LL_ENDL;  	// This will happen when we get the reply  	//LLGroupMgrGroupData* group_datap = createGroupData(group_id); - +	      if (LLGroupMgr::getInstance()->hasPendingPropertyRequest(group_id))      {          LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupPropertiesRequest suppressed repeat for " << group_id << LL_ENDL; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index f127325ced..23394b26f2 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1027,21 +1027,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)  					getChildView("maskcutoff")->setEnabled(editable && mIsAlpha);  					getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha); -					bool allAttachments = true; -					for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin(); -						iter != LLSelectMgr::getInstance()->getSelection()->end();iter++) -					{ -						LLSelectNode* node = *iter; -						LLViewerObject* object = node->getObject(); -						if (!object->isAttachment()) -						{ -							allAttachments = false; -							break; -						} -					} - -					texture_ctrl->setBakeTextureEnabled(allAttachments); -					 +					texture_ctrl->setBakeTextureEnabled(TRUE);  				}  				else if (id.isNull())  					{ @@ -1066,21 +1052,8 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)  					getChildView("label alphamode")->setEnabled(editable && mIsAlpha);  					getChildView("maskcutoff")->setEnabled(editable && mIsAlpha);  					getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha); - -					bool allAttachments = true; -					for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin(); -						iter != LLSelectMgr::getInstance()->getSelection()->end();iter++) -					{ -						LLSelectNode* node = *iter; -						LLViewerObject* object = node->getObject(); -						if (!object->isAttachment()) -						{ -							allAttachments = false; -							break; -				} -			} - -					texture_ctrl->setBakeTextureEnabled(allAttachments); +					 +					texture_ctrl->setBakeTextureEnabled(TRUE);  				}  			} diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 97b5b2a57d..1e5b893cbc 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -678,8 +678,17 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)  	{      shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, light_direction.mV);         +    // Legacy? SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate")      LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]); -    vect_c_p_d1 += LLVector4(LLEnvironment::instance().getCloudScrollDelta()); +    LLVector4 cloud_scroll( LLEnvironment::instance().getCloudScrollDelta() ); + +    // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll +    // Keep in Sync! +    // * indra\newview\llsettingsvo.cpp +    // * indra\newview\app_settings\shaders\class2\windlight\cloudsV.glsl +    // * indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl +    cloud_scroll[0] = -cloud_scroll[0]; +    vect_c_p_d1 += cloud_scroll;      shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, 1, vect_c_p_d1.mV);      LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 2cdba4d9ba..afb25778aa 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -556,7 +556,9 @@ void LLSpatialGroup::shift(const LLVector4a &offset)  	if (!getSpatialPartition()->mRenderByGroup &&   		getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TREE &&  		getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TERRAIN && -		getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_BRIDGE) +		getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_BRIDGE && +		getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_AVATAR && +		getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_CONTROL_AV)  	{  		setState(GEOM_DIRTY);  		gPipeline.markRebuild(this, TRUE); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 7e65da42f7..919f386d29 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -685,6 +685,18 @@ public:  	virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { LLVolumeGeometryManager::addGeometryCount(group, vertex_count, index_count); }  }; +class LLAvatarBridge : public LLVolumeBridge +{ +public: +	LLAvatarBridge(LLDrawable* drawablep, LLViewerRegion* regionp); +}; + +class LLControlAVBridge : public LLVolumeBridge +{ +public: +	LLControlAVBridge(LLDrawable* drawablep, LLViewerRegion* regionp); +}; +  class LLHUDBridge : public LLVolumeBridge  {  public: @@ -702,6 +714,18 @@ public:  	virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) {  }  }; +class LLAvatarPartition : public LLBridgePartition +{ +public: +	LLAvatarPartition(LLViewerRegion* regionp); +}; + +class LLControlAVPartition : public LLBridgePartition +{ +public: +	LLControlAVPartition(LLViewerRegion* regionp); +}; +  class LLHUDPartition : public LLBridgePartition  {  public: diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index de7551d2fe..6ccb2f68e5 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -431,7 +431,7 @@ BOOL LLFloaterTexturePicker::postBuild()  	getChild<LLComboBox>("l_bake_use_texture_combo_box")->setCommitCallback(onBakeTextureSelect, this);  	getChild<LLCheckBoxCtrl>("hide_base_mesh_region")->setCommitCallback(onHideBaseMeshRegionCheck, this); -	setBakeTextureEnabled(FALSE); +	setBakeTextureEnabled(TRUE);  	return TRUE;  } @@ -1156,8 +1156,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)  	mImageAssetID(p.image_id),  	mDefaultImageAssetID(p.default_image_id),  	mDefaultImageName(p.default_image_name), -	mFallbackImage(p.fallback_image), -	mBakeTextureEnabled(FALSE) +	mFallbackImage(p.fallback_image)  {  	// Default of defaults is white image for diff tex @@ -1350,7 +1349,7 @@ void LLTextureCtrl::showPicker(BOOL take_focus)  		}  		if (texture_floaterp)  		{ -			texture_floaterp->setBakeTextureEnabled(mBakeTextureEnabled); +			texture_floaterp->setBakeTextureEnabled(TRUE);  		}  		LLFloater* root_floater = gFloaterView->getParentFloater(this); @@ -1529,7 +1528,6 @@ void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id )  void LLTextureCtrl::setBakeTextureEnabled(BOOL enabled)  { -	mBakeTextureEnabled = enabled;  	LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();  	if (floaterp)  	{ diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index c705c34e21..92f6f89af6 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -238,7 +238,6 @@ private:  	BOOL					 	mShowLoadingPlaceholder;  	std::string				 	mLoadingPlaceholderString;  	S32						 	mLabelWidth; -	BOOL						mBakeTextureEnabled;  };  ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 0d2edc0268..1c4187d30f 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -549,7 +549,7 @@ void LLGLTexMemBar::draw()      U32 texFetchLatMed = U32(recording.getMean(LLTextureFetch::sTexFetchLatency).value() * 1000.0f);      U32 texFetchLatMax = U32(recording.getMax(LLTextureFetch::sTexFetchLatency).value() * 1000.0f); -	text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB", +	text = llformat("GL Tot: %d/%d MB Bound: %4d/%4d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB",  					total_mem.value(),  					max_total_mem.value(),  					bound_mem.value(), diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 12346f16d7..864ce09430 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -671,7 +671,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)  	else  	{  		// perform a separate pick that detects transparent objects since they respond to 1-click actions -		LLPickInfo click_action_pick = gViewerWindow->pickImmediate(x, y, TRUE, pick_rigged); +		LLPickInfo click_action_pick = gViewerWindow->pickImmediate(x, y, FALSE, pick_rigged);  		LLViewerObject* click_action_object = click_action_pick.getObject(); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index f025863072..caf79edfe4 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -710,9 +710,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		LLGLState::checkTextureChannels();  		LLGLState::checkClientArrays(); -		BOOL to_texture = gPipeline.canUseVertexShaders() && -						LLPipeline::sRenderGlow; -  		LLAppViewer::instance()->pingMainloopTimeout("Display:Swap");  		{  @@ -919,31 +916,28 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		stop_glerror(); -		if (to_texture) -		{ -			gGL.setColorMask(true, true); -					 -			if (LLPipeline::sRenderDeferred) -			{ -				gPipeline.mDeferredScreen.bindTarget(); -				glClearColor(1,0,1,1); -				gPipeline.mDeferredScreen.clear(); -			} -			else -			{ -				gPipeline.mScreen.bindTarget(); -				if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders()) -				{ -					const LLColor4 &col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor(); -					glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); -				} -				gPipeline.mScreen.clear(); -			} -			 -			gGL.setColorMask(true, false); -		} -		 -		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderGeom"); +        gGL.setColorMask(true, true); + +        if (LLPipeline::sRenderDeferred) +        { +            gPipeline.mDeferredScreen.bindTarget(); +            glClearColor(1, 0, 1, 1); +            gPipeline.mDeferredScreen.clear(); +        } +        else +        { +            gPipeline.mScreen.bindTarget(); +            if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders()) +            { +                const LLColor4 &col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor(); +                glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); +            } +            gPipeline.mScreen.clear(); +        } + +        gGL.setColorMask(true, false); + +        LLAppViewer::instance()->pingMainloopTimeout("Display:RenderGeom");  		if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot())  				&& !gRestoreGL) @@ -1005,38 +999,20 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			}  		} -		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");		 -		 -		if (to_texture) -		{ -			if (LLPipeline::sRenderDeferred) -			{ -				gPipeline.mDeferredScreen.flush(); -				if(LLRenderTarget::sUseFBO) -				{ -					LLRenderTarget::copyContentsToFramebuffer(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(),  -															  gPipeline.mDeferredScreen.getHeight(), 0, 0,  -															  gPipeline.mDeferredScreen.getWidth(),  -															  gPipeline.mDeferredScreen.getHeight(),  -															  GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); -				} -			} -			else -			{ -				gPipeline.mScreen.flush(); -				if(LLRenderTarget::sUseFBO) -				{				 -					LLRenderTarget::copyContentsToFramebuffer(gPipeline.mScreen, 0, 0, gPipeline.mScreen.getWidth(),  -															  gPipeline.mScreen.getHeight(), 0, 0,  -															  gPipeline.mScreen.getWidth(),  -															  gPipeline.mScreen.getHeight(),  -															  GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); -				} -			} -		} +		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush"); -		if (LLPipeline::sRenderDeferred) -		{ +        LLRenderTarget &rt = (gPipeline.sRenderDeferred ? gPipeline.mDeferredScreen : gPipeline.mScreen); +        rt.flush(); + +        if (rt.sUseFBO) +        { +            LLRenderTarget::copyContentsToFramebuffer(rt, 0, 0, rt.getWidth(), rt.getHeight(), 0, 0, rt.getWidth(), +                                                      rt.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, +                                                      GL_NEAREST); +        } + +        if (LLPipeline::sRenderDeferred) +        {  			gPipeline.renderDeferredLighting(&gPipeline.mScreen);  		} @@ -1300,19 +1276,12 @@ void render_ui(F32 zoom_factor, int subfield)  		gGL.popMatrix();  	} -	{ -		BOOL to_texture = gPipeline.canUseVertexShaders() && -							LLPipeline::sRenderGlow; +    // Finalize scene +    gPipeline.renderFinalize(); -		if (to_texture) -		{ -			gPipeline.renderBloom(gSnapshot, zoom_factor, subfield); -		} -		 -		LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD); -		render_hud_elements(); -		render_hud_attachments(); -	} +    LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD); +    render_hud_elements(); +	render_hud_attachments();  	LLGLSDefault gls_default;  	LLGLSUIDefault gls_ui; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index b6c7be2ed3..e6bd20b58f 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -740,6 +740,10 @@ U32 render_type_from_string(std::string render_type)  	{  		return LLPipeline::RENDER_TYPE_AVATAR;  	} +	else if ("controlAV" == render_type) // Animesh +	{ +		return LLPipeline::RENDER_TYPE_CONTROL_AV; +	}  	else if ("surfacePatch" == render_type)  	{  		return LLPipeline::RENDER_TYPE_TERRAIN; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 06a8ebbe89..ea9dba3c4e 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2220,8 +2220,12 @@ protected:  	}  }; +static LLTrace::BlockTimerStatHandle FTM_PROCESS_IMPROVED_IM("Process IM"); +  void process_improved_im(LLMessageSystem *msg, void **user_data)  { +    LL_RECORD_BLOCK_TIME(FTM_PROCESS_IMPROVED_IM); +      LLUUID from_id;      BOOL from_group;      LLUUID to_id; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 9c91cde09a..aa775b2bab 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -284,6 +284,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe  	mOnActiveList(FALSE),  	mOnMap(FALSE),  	mStatic(FALSE), +	mSeatCount(0),  	mNumFaces(0),  	mRotTime(0.f),  	mAngularVelocityRot(), @@ -895,7 +896,12 @@ void LLViewerObject::addChild(LLViewerObject *childp)  	if(childp->setParent(this))  	{  		mChildList.push_back(childp); -        childp->afterReparent(); +		childp->afterReparent(); + +		if (childp->isAvatar()) +		{ +			mSeatCount++; +		}  	}  } @@ -924,6 +930,11 @@ void LLViewerObject::removeChild(LLViewerObject *childp)  			{  				childp->setParent(NULL);			  			} + +			if (childp->isAvatar()) +			{ +				mSeatCount--; +			}  			break;  		}  	} @@ -981,21 +992,10 @@ BOOL LLViewerObject::isChild(LLViewerObject *childp) const  	return FALSE;  } -  // returns TRUE if at least one avatar is sitting on this object  BOOL LLViewerObject::isSeat() const  { -	for (child_list_t::const_iterator iter = mChildList.begin(); -		 iter != mChildList.end(); iter++) -	{ -		LLViewerObject* child = *iter; -		if (child->isAvatar()) -		{ -			return TRUE; -		} -	} -	return FALSE; - +	return mSeatCount > 0;  }  BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp) diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 03c5403a1e..12a9b47307 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -832,6 +832,7 @@ protected:  	BOOL			mOnActiveList;  	BOOL			mOnMap;						// On the map.  	BOOL			mStatic;					// Object doesn't move. +	S32				mSeatCount;  	S32				mNumFaces;  	F32				mRotTime;					// Amount (in seconds) that object has rotated according to angular velocity (llSetTargetOmega) diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index b9cf4b07dc..a30c5156fa 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -102,6 +102,7 @@ const U32 DEFAULT_MAX_REGION_WIDE_PRIM_COUNT = 15000;  BOOL LLViewerRegion::sVOCacheCullingEnabled = FALSE;  S32  LLViewerRegion::sLastCameraUpdated = 0;  S32  LLViewerRegion::sNewObjectCreationThrottle = -1; +LLViewerRegion::vocache_entry_map_t LLViewerRegion::sRegionCacheCleanup;  typedef std::map<std::string, std::string> CapabilityMap; @@ -624,6 +625,8 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,  	mImpl->mObjectPartition.push_back(new LLGrassPartition(this));		//PARTITION_GRASS  	mImpl->mObjectPartition.push_back(new LLVolumePartition(this));	//PARTITION_VOLUME  	mImpl->mObjectPartition.push_back(new LLBridgePartition(this));	//PARTITION_BRIDGE +	mImpl->mObjectPartition.push_back(new LLAvatarPartition(this));	//PARTITION_AVATAR +	mImpl->mObjectPartition.push_back(new LLControlAVPartition(this));	//PARTITION_CONTROL_AV  	mImpl->mObjectPartition.push_back(new LLHUDParticlePartition(this));//PARTITION_HUD_PARTICLE  	mImpl->mObjectPartition.push_back(new LLVOCachePartition(this)); //PARTITION_VO_CACHE  	mImpl->mObjectPartition.push_back(NULL);					//PARTITION_NONE @@ -648,6 +651,9 @@ void LLViewerRegion::initStats()  	mAlive = false;					// can become false if circuit disconnects  } +static LLTrace::BlockTimerStatHandle FTM_CLEANUP_REGION_OBJECTS("Cleanup Region Objects"); +static LLTrace::BlockTimerStatHandle FTM_SAVE_REGION_CACHE("Save Region Cache"); +  LLViewerRegion::~LLViewerRegion()   {  	mDead = TRUE; @@ -662,7 +668,10 @@ LLViewerRegion::~LLViewerRegion()  	disconnectAllNeighbors();  	LLViewerPartSim::getInstance()->cleanupRegion(this); -	gObjectList.killObjects(this); +    { +        LL_RECORD_BLOCK_TIME(FTM_CLEANUP_REGION_OBJECTS); +        gObjectList.killObjects(this); +    }  	delete mImpl->mCompositionp;  	delete mParcelOverlay; @@ -673,7 +682,10 @@ LLViewerRegion::~LLViewerRegion()  #endif	  	std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer()); -	saveObjectCache(); +    { +        LL_RECORD_BLOCK_TIME(FTM_SAVE_REGION_CACHE); +        saveObjectCache(); +    }  	delete mImpl;  	mImpl = NULL; @@ -742,6 +754,8 @@ void LLViewerRegion::saveObjectCache()  		mCacheDirty = FALSE;  	} +	// Map of LLVOCacheEntry takes time to release, store map for cleanup on idle +	sRegionCacheCleanup.insert(mImpl->mCacheMap.begin(), mImpl->mCacheMap.end());  	mImpl->mCacheMap.clear();  } @@ -1503,6 +1517,16 @@ void LLViewerRegion::idleUpdate(F32 max_update_time)  	return;  } +// static +void LLViewerRegion::idleCleanup(F32 max_update_time) +{ +    LLTimer update_timer; +    while (!sRegionCacheCleanup.empty() && (max_update_time - update_timer.getElapsedTimeF32() > 0)) +    { +        sRegionCacheCleanup.erase(sRegionCacheCleanup.begin()); +    } +} +  //update the throttling number for new object creation  void LLViewerRegion::calcNewObjectCreationThrottle()  { diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 1b226ac2c6..477aabb971 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -86,6 +86,8 @@ public:  		PARTITION_GRASS,  		PARTITION_VOLUME,  		PARTITION_BRIDGE, +		PARTITION_AVATAR, +		PARTITION_CONTROL_AV, // Animesh  		PARTITION_HUD_PARTICLE,  		PARTITION_VO_CACHE,  		PARTITION_NONE, @@ -230,6 +232,9 @@ public:  	F32	getWidth() const						{ return mWidth; } +	// regions are expensive to release, this function gradually releases cache from memory +	static void idleCleanup(F32 max_update_time); +  	void idleUpdate(F32 max_update_time);  	void lightIdleUpdate();  	bool addVisibleGroup(LLViewerOctreeGroup* group); @@ -548,6 +553,9 @@ private:  	LLSD mSimulatorFeatures; +    typedef std::map<U32, LLPointer<LLVOCacheEntry> >	   vocache_entry_map_t; +    static vocache_entry_map_t sRegionCacheCleanup; +  	// the materials capability throttle  	LLFrameTimer mMaterialsCapThrottleTimer;  	LLFrameTimer mRenderInfoRequestTimer; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index bc4ee09bcc..0aee4a3398 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2470,7 +2470,7 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)  		return;  	}	 -	if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR)) +	if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR))  		&& !(gSavedSettings.getBOOL("DisableAllRenderTypes")) && !isSelf())  	{  		return; @@ -2600,8 +2600,8 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)      if ((LLFrameTimer::getFrameCount() + mID.mData[0]) % compl_upd_freq == 0)      {          LL_RECORD_BLOCK_TIME(FTM_AVATAR_UPDATE_COMPLEXITY); -        idleUpdateRenderComplexity(); -    } +	idleUpdateRenderComplexity(); +}      idleUpdateDebugInfo();  } @@ -4438,8 +4438,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)      if (visible)      { -        // System avatar mesh vertices need to be reskinned. -        mNeedsSkin = TRUE; +	// System avatar mesh vertices need to be reskinned. +	mNeedsSkin = TRUE;      }  	return visible; @@ -6897,13 +6897,13 @@ LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline)  	pipeline->allocDrawable(this);  	mDrawable->setLit(FALSE); -	LLDrawPoolAvatar *poolp = (LLDrawPoolAvatar*) gPipeline.getPool(LLDrawPool::POOL_AVATAR); +	LLDrawPoolAvatar *poolp = (LLDrawPoolAvatar*)gPipeline.getPool(mIsControlAvatar ? LLDrawPool::POOL_CONTROL_AV : LLDrawPool::POOL_AVATAR);  	// Only a single face (one per avatar)  	//this face will be splitted into several if its vertex buffer is too long.  	mDrawable->setState(LLDrawable::ACTIVE);  	mDrawable->addFace(poolp, NULL); -	mDrawable->setRenderType(LLPipeline::RENDER_TYPE_AVATAR); +	mDrawable->setRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR);  	mNumInitFaces = mDrawable->getNumFaces() ; @@ -6928,7 +6928,7 @@ static LLTrace::BlockTimerStatHandle FTM_UPDATE_AVATAR("Update Avatar");  BOOL LLVOAvatar::updateGeometry(LLDrawable *drawable)  {  	LL_RECORD_BLOCK_TIME(FTM_UPDATE_AVATAR); - 	if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR))) +	if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR)))  	{  		return TRUE;  	} @@ -10084,7 +10084,7 @@ void LLVOAvatar::onActiveOverrideMeshesChanged()  U32 LLVOAvatar::getPartitionType() const  {   	// Avatars merely exist as drawables in the bridge partition -	return LLViewerRegion::PARTITION_BRIDGE; +	return mIsControlAvatar ? LLViewerRegion::PARTITION_CONTROL_AV : LLViewerRegion::PARTITION_AVATAR;  }  //static diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 07660ca6ac..689eeee0e3 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -347,36 +347,24 @@ void LLVOCacheEntry::dump() const  BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const  { -	BOOL success; -	success = check_write(apr_file, (void*)&mLocalID, sizeof(U32)); -	if(success) -	{ -		success = check_write(apr_file, (void*)&mCRC, sizeof(U32)); -	} -	if(success) -	{ -		success = check_write(apr_file, (void*)&mHitCount, sizeof(S32)); -	} -	if(success) -	{ -		success = check_write(apr_file, (void*)&mDupeCount, sizeof(S32)); -	} -	if(success) -	{ -		success = check_write(apr_file, (void*)&mCRCChangeCount, sizeof(S32)); -	} -	if(success) -	{ -		S32 size = mDP.getBufferSize(); -		success = check_write(apr_file, (void*)&size, sizeof(S32)); -	 -		if(success) -		{ -			success = check_write(apr_file, (void*)mBuffer, size); -		} -	} - -	return success ; +    static const S32 data_buffer_size = 6 * sizeof(S32); +    static U8 data_buffer[data_buffer_size]; +    S32 size = mDP.getBufferSize(); + +    memcpy(data_buffer, &mLocalID, sizeof(U32)); +    memcpy(data_buffer + sizeof(U32), &mCRC, sizeof(U32)); +    memcpy(data_buffer + (2 * sizeof(U32)), &mHitCount, sizeof(S32)); +    memcpy(data_buffer + (3 * sizeof(U32)), &mDupeCount, sizeof(S32)); +    memcpy(data_buffer + (4 * sizeof(U32)), &mCRCChangeCount, sizeof(S32)); +    memcpy(data_buffer + (5 * sizeof(U32)), &size, sizeof(S32)); + +    BOOL success = check_write(apr_file, (void*)data_buffer, data_buffer_size); +    if (success) +    { +        success = check_write(apr_file, (void*)mBuffer, size); +    } + +    return success;  }  //static  @@ -1537,7 +1525,8 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:  		{  			S32 num_entries = cache_entry_map.size() ;  			success = check_write(&apr_file, &num_entries, sizeof(S32)); -	 + +			// This can have a lot of entries, so might be better to dump them into buffer first and write in one go.  			for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); success && iter != cache_entry_map.end(); ++iter)  			{  				if(!removal_enabled || iter->second->isValid()) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 659b533b86..ef39faa814 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4893,6 +4893,14 @@ U32 LLVOVolume::getPartitionType() const  	{  		return LLViewerRegion::PARTITION_HUD;  	} +	if (isAnimatedObject() && getControlAvatar()) +	{ +		return LLViewerRegion::PARTITION_CONTROL_AV; +	} +	if (isAttachment()) +	{ +		return LLViewerRegion::PARTITION_AVATAR; +	}  	return LLViewerRegion::PARTITION_VOLUME;  } @@ -4923,6 +4931,20 @@ LLVolumeGeometryManager()  	mSlopRatio = 0.25f;  } +LLAvatarBridge::LLAvatarBridge(LLDrawable* drawablep, LLViewerRegion* regionp) +	: LLVolumeBridge(drawablep, regionp) +{ +	mDrawableType = LLPipeline::RENDER_TYPE_AVATAR; +	mPartitionType = LLViewerRegion::PARTITION_AVATAR; +} + +LLControlAVBridge::LLControlAVBridge(LLDrawable* drawablep, LLViewerRegion* regionp) +	: LLVolumeBridge(drawablep, regionp) +{ +	mDrawableType = LLPipeline::RENDER_TYPE_CONTROL_AV; +	mPartitionType = LLViewerRegion::PARTITION_CONTROL_AV; +} +  bool can_batch_texture(LLFace* facep)  {  	if (facep->getTextureEntry()->getBumpmap()) @@ -5267,7 +5289,8 @@ static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)  				LLDrawPool* drawpool = face->getPool();  				if (drawpool)  				{ -					if (drawpool->getType() == LLDrawPool::POOL_AVATAR) +					if (drawpool->getType() == LLDrawPool::POOL_AVATAR +						|| drawpool->getType() == LLDrawPool::POOL_CONTROL_AV)  					{  						return (LLDrawPoolAvatar*) drawpool;  					} @@ -5546,7 +5569,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  						//remove face from old pool if it exists  						LLDrawPool* old_pool = facep->getPool(); -						if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR) +						if (old_pool +							&& (old_pool->getType() == LLDrawPool::POOL_AVATAR || old_pool->getType() == LLDrawPool::POOL_CONTROL_AV))  						{  							((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep);  						} diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index 368a3f2335..d428cb1568 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -99,6 +99,9 @@ LLDrawable * LLVOWLSky::createDrawable(LLPipeline * pipeline)  inline F32 LLVOWLSky::calcPhi(U32 i)  { +    // Calc: PI/8 * 1-((1-t^4)*(1-t^4))  { 0<t<1 } +    // Demos: \pi/8*\left(1-((1-x^{4})*(1-x^{4}))\right)\ \left\{0<x\le1\right\} +  	// i should range from [0..SKY_STACKS] so t will range from [0.f .. 1.f]  	F32 t = float(i) / float(getNumStacks()); diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 8989bae96a..a1a1db35d6 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -730,11 +730,20 @@ void LLWorld::updateRegions(F32 max_update_time)  		{  			//perform some necessary but very light updates.  			(*iter)->lightIdleUpdate(); -		}		 +		} +	} + +	if(max_time > 0.f) +	{ +		max_time = llmin((F32)(max_update_time - update_timer.getElapsedTimeF32()), max_update_time * 0.25f); +	} +	if(max_time > 0.f) +	{ +		LLViewerRegion::idleCleanup(max_time);  	}  	sample(sNumActiveCachedObjects, mNumOfActiveCachedObjects); -		} +}  void LLWorld::clearAllVisibleObjects()  { @@ -1208,11 +1217,14 @@ public:  	}  }; +static LLTrace::BlockTimerStatHandle FTM_DISABLE_REGION("Disable Region");  // disable the circuit to this simulator  // Called in response to "DisableSimulator" message.  void process_disable_simulator(LLMessageSystem *mesgsys, void **user_data) -{	 -	LLHost host = mesgsys->getSender(); +{ +    LL_RECORD_BLOCK_TIME(FTM_DISABLE_REGION); + +    LLHost host = mesgsys->getSender();  	//LL_INFOS() << "Disabling simulator with message from " << host << LL_ENDL;  	LLWorld::getInstance()->removeRegion(host); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 39c4d487e0..604c5f770d 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1049,25 +1049,19 @@ void LLPipeline::updateRenderBump()  	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");  } -//static +// static  void LLPipeline::updateRenderDeferred()  { -	bool deferred = (bool(RenderDeferred &&  -					 LLRenderTarget::sUseFBO && -					 LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&	  -					 LLPipeline::sRenderBump && -					 RenderAvatarVP && -					 WindLightUseAtmosShaders)) && -					!gUseWireframe; - -	sRenderDeferred = deferred;	 -	if (deferred) -	{ //must render glow when rendering deferred since post effect pass is needed to present any lighting at all -		sRenderGlow = true; -	} +    sRenderDeferred = !gUseWireframe && +                      RenderDeferred && +                      LLRenderTarget::sUseFBO && +                      LLPipeline::sRenderBump && +                      RenderAvatarVP && +                      WindLightUseAtmosShaders && +                      (bool) LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");  } -//static +// static  void LLPipeline::refreshCachedSettings()  {  	LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred"); @@ -1259,24 +1253,20 @@ void LLPipeline::createGLBuffers()  	GLuint resX = gViewerWindow->getWorldViewWidthRaw();  	GLuint resY = gViewerWindow->getWorldViewHeightRaw(); -	 -	if (LLPipeline::sRenderGlow) -	{ //screen space glow buffers -		const U32 glow_res = llmax(1,  -			llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow"))); -		for (U32 i = 0; i < 3; i++) -		{ -			mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE); -		} +    // allocate screen space glow buffers +    const U32 glow_res = llmax(1, llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow"))); +    for (U32 i = 0; i < 3; i++) +    { +        mGlow[i].allocate(512, glow_res, GL_RGBA, FALSE, FALSE); +    } -		allocateScreenBuffer(resX,resY); -		mScreenWidth = 0; -		mScreenHeight = 0; -	} -	 -	if (sRenderDeferred) -	{ +    allocateScreenBuffer(resX, resY); +    mScreenWidth = 0; +    mScreenHeight = 0; + +    if (sRenderDeferred) +    {  		if (!mNoiseMap)  		{  			const U32 noiseRes = 128; @@ -1609,6 +1599,7 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)  		break;  	case LLDrawPool::POOL_AVATAR: +	case LLDrawPool::POOL_CONTROL_AV:  		break; // Do nothing  	case LLDrawPool::POOL_SKY: @@ -1995,7 +1986,7 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list)  		drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED);  		if (done)  		{ -			if (drawablep->isRoot()) +			if (drawablep->isRoot() && !drawablep->isState(LLDrawable::ACTIVE))  			{  				drawablep->makeStatic();  			} @@ -3362,6 +3353,7 @@ static LLTrace::BlockTimerStatHandle FTM_RESET_DRAWORDER("Reset Draw Order");  void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)  {  	if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR, +					  LLPipeline::RENDER_TYPE_CONTROL_AV,  					  LLPipeline::RENDER_TYPE_GROUND,  					  LLPipeline::RENDER_TYPE_TERRAIN,  					  LLPipeline::RENDER_TYPE_TREE, @@ -5774,6 +5766,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )  		break;  	case LLDrawPool::POOL_AVATAR: +	case LLDrawPool::POOL_CONTROL_AV:  		break; // Do nothing  	case LLDrawPool::POOL_SKY: @@ -5922,6 +5915,7 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )  		break;  	case LLDrawPool::POOL_AVATAR: +	case LLDrawPool::POOL_CONTROL_AV:  		break; // Do nothing  	case LLDrawPool::POOL_SKY: @@ -6427,41 +6421,9 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)  		light->setAmbient(LLColor4::black);  		light->setSpecular(LLColor4::black);  	} -	if (gAgentAvatarp && -		gAgentAvatarp->mSpecialRenderMode == 3) -	{ -		LLColor4  light_color = LLColor4::white; -		light_color.mV[3] = 0.0f; - -		LLVector3 light_pos(LLViewerCamera::getInstance()->getOrigin()); -		LLVector4 light_pos_gl(light_pos, 1.0f); - -		F32 light_radius = 16.f; - -			F32 x = 3.f; -		float linatten = x / (light_radius); // % of brightness at radius - -		if (LLPipeline::sRenderDeferred) -		{ -			/*light_color.mV[0] = powf(light_color.mV[0], 2.2f); -			light_color.mV[1] = powf(light_color.mV[1], 2.2f); -			light_color.mV[2] = powf(light_color.mV[2], 2.2f);*/ -		} -		mHWLightColors[2] = light_color; -		LLLightState* light = gGL.getLight(2); - -		light->setPosition(light_pos_gl); -		light->setDiffuse(light_color); -        light->setDiffuseB(light_color * 0.25f); -		light->setAmbient(LLColor4::black); -		light->setSpecular(LLColor4::black); -		light->setQuadraticAttenuation(0.f); -		light->setConstantAttenuation(0.f); -		light->setLinearAttenuation(linatten); -		light->setSpotExponent(0.f); -		light->setSpotCutoff(180.f); -	} +    // Bookmark comment to allow searching for mSpecialRenderMode == 3 (avatar edit mode), +    // prev site of forward (non-deferred) character light injection, removed by SL-13522 09/20  	// Init GL state  	if (!LLGLSLShader::sNoFixedFunction) @@ -7151,7 +7113,8 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start,  		for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++)  		{  			if ((j == LLViewerRegion::PARTITION_VOLUME) ||  -				(j == LLViewerRegion::PARTITION_BRIDGE) ||  +				(j == LLViewerRegion::PARTITION_BRIDGE) || +				(j == LLViewerRegion::PARTITION_CONTROL_AV) ||  				(j == LLViewerRegion::PARTITION_TERRAIN) ||  				(j == LLViewerRegion::PARTITION_TREE) ||  				(j == LLViewerRegion::PARTITION_GRASS))  // only check these partitions for now @@ -7213,7 +7176,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start,  		{  			LLViewerRegion* region = *iter; -			LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE); +			LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_AVATAR);  			if (part && hasRenderType(part->mDrawableType))  			{  				LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, face_hit, &position, tex_coord, normal, tangent); @@ -7539,641 +7502,633 @@ void LLPipeline::bindScreenToTexture()  static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom"); -void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield) +void LLPipeline::renderFinalize()  { -	if (!(gPipeline.canUseVertexShaders() && -		sRenderGlow)) -	{ -		return; -	} +    LLVertexBuffer::unbind(); +    LLGLState::checkStates(); +    LLGLState::checkTextureChannels(); -	LLVertexBuffer::unbind(); -	LLGLState::checkStates(); -	LLGLState::checkTextureChannels(); +    assertInitialized(); -	assertInitialized(); +    if (gUseWireframe) +    { +        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +    } -	if (gUseWireframe) -	{ -		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -	} +    LLVector2 tc1(0, 0); +    LLVector2 tc2((F32) mScreen.getWidth() * 2, (F32) mScreen.getHeight() * 2); -	LLVector2 tc1(0,0); -	LLVector2 tc2((F32) mScreen.getWidth()*2, -				  (F32) mScreen.getHeight()*2); +    LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM); +    gGL.color4f(1, 1, 1, 1); +    LLGLDepthTest depth(GL_FALSE); +    LLGLDisable blend(GL_BLEND); +    LLGLDisable cull(GL_CULL_FACE); -	LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM); -	gGL.color4f(1,1,1,1); -	LLGLDepthTest depth(GL_FALSE); -	LLGLDisable blend(GL_BLEND); -	LLGLDisable cull(GL_CULL_FACE); -	 -	enableLightsFullbright(); +    enableLightsFullbright(); -	gGL.matrixMode(LLRender::MM_PROJECTION); -	gGL.pushMatrix(); -	gGL.loadIdentity(); -	gGL.matrixMode(LLRender::MM_MODELVIEW); -	gGL.pushMatrix(); -	gGL.loadIdentity(); +    gGL.matrixMode(LLRender::MM_PROJECTION); +    gGL.pushMatrix(); +    gGL.loadIdentity(); +    gGL.matrixMode(LLRender::MM_MODELVIEW); +    gGL.pushMatrix(); +    gGL.loadIdentity(); -	LLGLDisable test(GL_ALPHA_TEST); +    LLGLDisable test(GL_ALPHA_TEST); -	gGL.setColorMask(true, true); -	glClearColor(0,0,0,0); -		 -	{ -		{ -			LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); -			mGlow[2].bindTarget(); -			mGlow[2].clear(); -		} -		 -		gGlowExtractProgram.bind(); -		F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f); -		F32 maxAlpha = RenderGlowMaxExtractAlpha;		 -		F32 warmthAmount = RenderGlowWarmthAmount;	 -		LLVector3 lumWeights = RenderGlowLumWeights; -		LLVector3 warmthWeights = RenderGlowWarmthWeights; - - -		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum); -		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha); -		gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1], lumWeights.mV[2]); -		gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1], warmthWeights.mV[2]); -		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount); -		LLGLEnable blend_on(GL_BLEND); -		LLGLEnable test(GL_ALPHA_TEST); -		 -		gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); -		 -		mScreen.bindTexture(0, 0, LLTexUnit::TFO_POINT); -		 -		gGL.color4f(1,1,1,1); -		gPipeline.enableLightsFullbright(); -		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(0)->unbind(mScreen.getUsage()); +    gGL.setColorMask(true, true); +    glClearColor(0, 0, 0, 0); -		mGlow[2].flush(); -	} +    if (sRenderGlow) +    { +        { +            LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); +            mGlow[2].bindTarget(); +            mGlow[2].clear(); +        } -	tc1.setVec(0,0); -	tc2.setVec(2,2); +        gGlowExtractProgram.bind(); +        F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f); +        F32 maxAlpha = RenderGlowMaxExtractAlpha; +        F32 warmthAmount = RenderGlowWarmthAmount; +        LLVector3 lumWeights = RenderGlowLumWeights; +        LLVector3 warmthWeights = RenderGlowWarmthWeights; + +        gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum); +        gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha); +        gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1], +                                      lumWeights.mV[2]); +        gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1], +                                      warmthWeights.mV[2]); +        gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount); +         +        { +            LLGLEnable blend_on(GL_BLEND); +            LLGLEnable test(GL_ALPHA_TEST); -	// power of two between 1 and 1024 -	U32 glowResPow = RenderGlowResolutionPow; -	const U32 glow_res = llmax(1,  -		llmin(1024, 1 << glowResPow)); +            gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); -	S32 kernel = RenderGlowIterations*2; -	F32 delta = RenderGlowWidth / glow_res; -	// Use half the glow width if we have the res set to less than 9 so that it looks -	// almost the same in either case. -	if (glowResPow < 9) -	{ -		delta *= 0.5f; -	} -	F32 strength = RenderGlowStrength; +            mScreen.bindTexture(0, 0, LLTexUnit::TFO_POINT); -	gGlowProgram.bind(); -	gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength); +            gGL.color4f(1, 1, 1, 1); +            gPipeline.enableLightsFullbright(); +            gGL.begin(LLRender::TRIANGLE_STRIP); +            gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +            gGL.vertex2f(-1, -1); -	for (S32 i = 0; i < kernel; i++) -	{ -		{ -			LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); -			mGlow[i%2].bindTarget(); -			mGlow[i%2].clear(); -		} -			 -		if (i == 0) -		{ -			gGL.getTexUnit(0)->bind(&mGlow[2]); -		} -		else -		{ -			gGL.getTexUnit(0)->bind(&mGlow[(i-1)%2]); -		} +            gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +            gGL.vertex2f(-1, 3); -		if (i%2 == 0) -		{ -			gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0); -		} -		else -		{ -			gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta); -		} +            gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +            gGL.vertex2f(3, -1); -		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(); -		 -		mGlow[i%2].flush(); -	} +            gGL.end(); -	gGlowProgram.unbind(); +            gGL.getTexUnit(0)->unbind(mScreen.getUsage()); -	/*if (LLRenderTarget::sUseFBO) -	{ -		LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); -		glBindFramebuffer(GL_FRAMEBUFFER, 0); -	}*/ +            mGlow[2].flush(); -	gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; -	gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; -	gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); -	gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); -	glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); +            tc1.setVec(0, 0); +            tc2.setVec(2, 2);  +        } -	tc2.setVec((F32) mScreen.getWidth(), -			(F32) mScreen.getHeight()); +        // power of two between 1 and 1024 +        U32 glowResPow = RenderGlowResolutionPow; +        const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow)); -	gGL.flush(); -	 -	LLVertexBuffer::unbind(); +        S32 kernel = RenderGlowIterations * 2; +        F32 delta = RenderGlowWidth / glow_res; +        // Use half the glow width if we have the res set to less than 9 so that it looks +        // almost the same in either case. +        if (glowResPow < 9) +        { +            delta *= 0.5f; +        } +        F32 strength = RenderGlowStrength; -	if (LLPipeline::sRenderDeferred) -	{ +        gGlowProgram.bind(); +        gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength); -		bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() && -			(RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && -							RenderDepthOfField; +        for (S32 i = 0; i < kernel; i++) +        { +            { +                LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); +                mGlow[i % 2].bindTarget(); +                mGlow[i % 2].clear(); +            } +            if (i == 0) +            { +                gGL.getTexUnit(0)->bind(&mGlow[2]); +            } +            else +            { +                gGL.getTexUnit(0)->bind(&mGlow[(i - 1) % 2]); +            } -		bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete(); +            if (i % 2 == 0) +            { +                gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0); +            } +            else +            { +                gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta); +            } -		gViewerWindow->setup3DViewport(); -				 -		if (dof_enabled) -		{ -			LLGLSLShader* shader = &gDeferredPostProgram; -			LLGLDisable blend(GL_BLEND); +            gGL.begin(LLRender::TRIANGLE_STRIP); +            gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +            gGL.vertex2f(-1, -1); -			//depth of field focal plane calculations -			static F32 current_distance = 16.f; -			static F32 start_distance = 16.f; -			static F32 transition_time = 1.f; +            gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +            gGL.vertex2f(-1, 3); -			LLVector3 focus_point; +            gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +            gGL.vertex2f(3, -1); -			LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); -			if (obj && obj->mDrawable && obj->isSelected()) -			{ //focus on selected media object -				S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); -				if (obj && obj->mDrawable) -				{ -					LLFace* face = obj->mDrawable->getFace(face_idx); -					if (face) -					{ -						focus_point = face->getPositionAgent(); -					} -				} -			} -		 -			if (focus_point.isExactlyZero()) -			{ -				if (LLViewerJoystick::getInstance()->getOverrideCamera()) -				{ //focus on point under cursor -					focus_point.set(gDebugRaycastIntersection.getF32ptr()); -				} -				else if (gAgentCamera.cameraMouselook()) -				{ //focus on point under mouselook crosshairs -					LLVector4a result; -					result.clear(); +            gGL.end(); -					gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, -													NULL, -													&result); +            mGlow[i % 2].flush(); +        } -					focus_point.set(result.getF32ptr()); -				} -				else -				{ -					//focus on alt-zoom target -					LLViewerRegion* region = gAgent.getRegion(); -					if (region) -					{ -						focus_point = LLVector3(gAgentCamera.getFocusGlobal()-region->getOriginGlobal()); -					} -				} -			} +        gGlowProgram.unbind(); +    } +    else // !sRenderGlow, skip the glow ping-pong and just clear the result target +    { +        mGlow[1].bindTarget(); +        mGlow[1].clear(); +        mGlow[1].flush(); +    } -			LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); -			F32 target_distance = 16.f; -			if (!focus_point.isExactlyZero()) -			{ -				target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point-eye); -			} +    gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; +    gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; +    gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); +    gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); +    glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); -			if (transition_time >= 1.f && -				fabsf(current_distance-target_distance)/current_distance > 0.01f) -			{ //large shift happened, interpolate smoothly to new target distance -				transition_time = 0.f; -				start_distance = current_distance; -			} -			else if (transition_time < 1.f) -			{ //currently in a transition, continue interpolating -				transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds.value(); -				transition_time = llmin(transition_time, 1.f); +    tc2.setVec((F32) mScreen.getWidth(), (F32) mScreen.getHeight()); -				F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f; -				current_distance = start_distance + (target_distance-start_distance)*t; -			} -			else -			{ //small or no change, just snap to target distance -				current_distance = target_distance; -			} +    gGL.flush(); -			//convert to mm -			F32 subject_distance = current_distance*1000.f; -			F32 fnumber = CameraFNumber; -			F32 default_focal_length = CameraFocalLength; +    LLVertexBuffer::unbind(); -			F32 fov = LLViewerCamera::getInstance()->getView(); -		 -			const F32 default_fov = CameraFieldOfView * F_PI/180.f; -		 -			//F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight(); -		 -			F32 dv = 2.f*default_focal_length * tanf(default_fov/2.f); +    if (LLPipeline::sRenderDeferred) +    { -			F32 focal_length = dv/(2*tanf(fov/2.f)); -		  -			//F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); -	 -			// from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) -			// where	 N = fnumber -			//			 s2 = dot distance -			//			 s1 = subject distance -			//			 f = focal length -			//	 +        bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() && +                           (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && +                           RenderDepthOfField; -			F32 blur_constant = focal_length*focal_length/(fnumber*(subject_distance-focal_length)); -			blur_constant /= 1000.f; //convert to meters for shader -			F32 magnification = focal_length/(subject_distance-focal_length); +        bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete(); -			{ //build diffuse+bloom+CoF -				mDeferredLight.bindTarget(); -				shader = &gDeferredCoFProgram; +        gViewerWindow->setup3DViewport(); -				bindDeferredShader(*shader); +        if (dof_enabled) +        { +            LLGLSLShader *shader = &gDeferredPostProgram; +            LLGLDisable blend(GL_BLEND); -				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); -				if (channel > -1) -				{ -					mScreen.bindTexture(0, channel); -				} +            // depth of field focal plane calculations +            static F32 current_distance = 16.f; +            static F32 start_distance = 16.f; +            static F32 transition_time = 1.f; -				shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance/1000.f); -				shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); -				shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f/LLDrawable::sCurPixelAngle)); -				shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); -				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); -				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); +            LLVector3 focus_point; -				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(); +            LLViewerObject *obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); +            if (obj && obj->mDrawable && obj->isSelected()) +            { // focus on selected media object +                S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); +                if (obj && obj->mDrawable) +                { +                    LLFace *face = obj->mDrawable->getFace(face_idx); +                    if (face) +                    { +                        focus_point = face->getPositionAgent(); +                    } +                } +            } -				unbindDeferredShader(*shader); -				mDeferredLight.flush(); -			} +            if (focus_point.isExactlyZero()) +            { +                if (LLViewerJoystick::getInstance()->getOverrideCamera()) +                { // focus on point under cursor +                    focus_point.set(gDebugRaycastIntersection.getF32ptr()); +                } +                else if (gAgentCamera.cameraMouselook()) +                { // focus on point under mouselook crosshairs +                    LLVector4a result; +                    result.clear(); -			U32 dof_width = (U32) (mScreen.getWidth()*CameraDoFResScale); -			U32 dof_height = (U32) (mScreen.getHeight()*CameraDoFResScale); -			 -			{ //perform DoF sampling at half-res (preserve alpha channel) -				mScreen.bindTarget(); -				glViewport(0,0, dof_width, dof_height); -				gGL.setColorMask(true, false); +                    gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, NULL, &result); -				shader = &gDeferredPostProgram; -				bindDeferredShader(*shader); -				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); -				if (channel > -1) -				{ -					mDeferredLight.bindTexture(0, channel); -				} +                    focus_point.set(result.getF32ptr()); +                } +                else +                { +                    // focus on alt-zoom target +                    LLViewerRegion *region = gAgent.getRegion(); +                    if (region) +                    { +                        focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); +                    } +                } +            } -				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); -				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); -				 -				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(); +            LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); +            F32 target_distance = 16.f; +            if (!focus_point.isExactlyZero()) +            { +                target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye); +            } -				unbindDeferredShader(*shader); -				mScreen.flush(); -				gGL.setColorMask(true, true); -			} -	 -			{ //combine result based on alpha -				if (multisample) -				{ -					mDeferredLight.bindTarget(); -					glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); -				} -				else -				{ -					gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; -					gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; -					gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); -					gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); -					glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); -				} +            if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f) +            { // large shift happened, interpolate smoothly to new target distance +                transition_time = 0.f; +                start_distance = current_distance; +            } +            else if (transition_time < 1.f) +            { // currently in a transition, continue interpolating +                transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value(); +                transition_time = llmin(transition_time, 1.f); -				shader = &gDeferredDoFCombineProgram; -				bindDeferredShader(*shader); -				 -				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); -				if (channel > -1) -				{ -					mScreen.bindTexture(0, channel); -				} +                F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f; +                current_distance = start_distance + (target_distance - start_distance) * t; +            } +            else +            { // small or no change, just snap to target distance +                current_distance = target_distance; +            } -				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); -				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); -				shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width-1); -				shader->uniform1f(LLShaderMgr::DOF_HEIGHT, dof_height-1); +            // convert to mm +            F32 subject_distance = current_distance * 1000.f; +            F32 fnumber = CameraFNumber; +            F32 default_focal_length = CameraFocalLength; -				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(); +            F32 fov = LLViewerCamera::getInstance()->getView(); -				unbindDeferredShader(*shader); +            const F32 default_fov = CameraFieldOfView * F_PI / 180.f; -				if (multisample) -				{ -					mDeferredLight.flush(); -				} -			} -		} -		else -		{ -			if (multisample) -			{ -				mDeferredLight.bindTarget(); -			} -			LLGLSLShader* shader = &gDeferredPostNoDoFProgram; -			 -			bindDeferredShader(*shader); -							 -			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); -			if (channel > -1) -			{ -				mScreen.bindTexture(0, channel); -			} +            // F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight(); -			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(); +            F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f); -			unbindDeferredShader(*shader); +            F32 focal_length = dv / (2 * tanf(fov / 2.f)); -			if (multisample) -			{ -				mDeferredLight.flush(); -			} -		} +            // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); -		if (multisample) -		{ -			//bake out texture2D with RGBL for FXAA shader -			mFXAABuffer.bindTarget(); -			 -			S32 width = mScreen.getWidth(); -			S32 height = mScreen.getHeight(); -			glViewport(0, 0, width, height); +            // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) +            // where	 N = fnumber +            //			 s2 = dot distance +            //			 s1 = subject distance +            //			 f = focal length +            // -			LLGLSLShader* shader = &gGlowCombineFXAAProgram; +            F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length)); +            blur_constant /= 1000.f; // convert to meters for shader +            F32 magnification = focal_length / (subject_distance - focal_length); -			shader->bind(); -			shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); +            { // build diffuse+bloom+CoF +                mDeferredLight.bindTarget(); +                shader = &gDeferredCoFProgram; -			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); -			if (channel > -1) -			{ -				mDeferredLight.bindTexture(0, channel); -			} -						 -			gGL.begin(LLRender::TRIANGLE_STRIP); -			gGL.vertex2f(-1,-1); -			gGL.vertex2f(-1,3); -			gGL.vertex2f(3,-1); -			gGL.end(); +                bindDeferredShader(*shader); -			gGL.flush(); +                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); +                if (channel > -1) +                { +                    mScreen.bindTexture(0, channel); +                } -			shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); -			shader->unbind(); -			 -			mFXAABuffer.flush(); +                shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f); +                shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); +                shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle)); +                shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); +                shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); +                shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); -			shader = &gFXAAProgram; -			shader->bind(); +                gGL.begin(LLRender::TRIANGLE_STRIP); +                gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +                gGL.vertex2f(-1, -1); -			channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage()); -			if (channel > -1) -			{ -				mFXAABuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); -			} -			 -			gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; -			gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; -			gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); -			gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); -			glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - -			F32 scale_x = (F32) width/mFXAABuffer.getWidth(); -			F32 scale_y = (F32) height/mFXAABuffer.getHeight(); -			shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); -			shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f/width*scale_x, 1.f/height*scale_y); -			shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f/width*scale_x, -0.5f/height*scale_y, 0.5f/width*scale_x, 0.5f/height*scale_y); -			shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f/width*scale_x, -2.f/height*scale_y, 2.f/width*scale_x, 2.f/height*scale_y); -			 -			gGL.begin(LLRender::TRIANGLE_STRIP); -			gGL.vertex2f(-1,-1); -			gGL.vertex2f(-1,3); -			gGL.vertex2f(3,-1); -			gGL.end(); +                gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +                gGL.vertex2f(-1, 3); -			gGL.flush(); -			shader->unbind(); -		} -	} -	else -	{ -		U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1; -		LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0); -		buff->allocateBuffer(3,0,TRUE); +                gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +                gGL.vertex2f(3, -1); -		LLStrider<LLVector3> v; -		LLStrider<LLVector2> uv1; -		LLStrider<LLVector2> uv2; +                gGL.end(); -		buff->getVertexStrider(v); -		buff->getTexCoord0Strider(uv1); -		buff->getTexCoord1Strider(uv2); -		 -		uv1[0] = LLVector2(0, 0); -		uv1[1] = LLVector2(0, 2); -		uv1[2] = LLVector2(2, 0); -		 -		uv2[0] = LLVector2(0, 0); -		uv2[1] = LLVector2(0, tc2.mV[1]*2.f); -		uv2[2] = LLVector2(tc2.mV[0]*2.f, 0); -		 -		v[0] = LLVector3(-1,-1,0); -		v[1] = LLVector3(-1,3,0); -		v[2] = LLVector3(3,-1,0); -				 -		buff->flush(); +                unbindDeferredShader(*shader); +                mDeferredLight.flush(); +            } -		LLGLDisable blend(GL_BLEND); +            U32 dof_width = (U32)(mScreen.getWidth() * CameraDoFResScale); +            U32 dof_height = (U32)(mScreen.getHeight() * CameraDoFResScale); -		if (LLGLSLShader::sNoFixedFunction) -		{ -			gGlowCombineProgram.bind(); -		} -		else -		{ -			//tex unit 0 -			gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR); -			//tex unit 1 -			gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); -		} -		 -		gGL.getTexUnit(0)->bind(&mGlow[1]); -		gGL.getTexUnit(1)->bind(&mScreen); -		 -		LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); -		 -		buff->setBuffer(mask); -		buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3); -		 -		if (LLGLSLShader::sNoFixedFunction) -		{ -			gGlowCombineProgram.unbind(); -		} -		else -		{ -			gGL.getTexUnit(1)->disable(); -			gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT); +            { // perform DoF sampling at half-res (preserve alpha channel) +                mScreen.bindTarget(); +                glViewport(0, 0, dof_width, dof_height); +                gGL.setColorMask(true, false); -			gGL.getTexUnit(0)->activate(); -			gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); -		} -		 -	} +                shader = &gDeferredPostProgram; +                bindDeferredShader(*shader); +                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); +                if (channel > -1) +                { +                    mDeferredLight.bindTexture(0, channel); +                } -	gGL.setSceneBlendType(LLRender::BT_ALPHA); +                shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); +                shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); -	if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) -	{ -		if (LLGLSLShader::sNoFixedFunction) -		{ -			gSplatTextureRectProgram.bind(); -		} +                gGL.begin(LLRender::TRIANGLE_STRIP); +                gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +                gGL.vertex2f(-1, -1); -		gGL.setColorMask(true, false); +                gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +                gGL.vertex2f(-1, 3); -		LLVector2 tc1(0,0); -		LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw()*2, -				  (F32) gViewerWindow->getWorldViewHeightRaw()*2); +                gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +                gGL.vertex2f(3, -1); -		LLGLEnable blend(GL_BLEND); -		gGL.color4f(1,1,1,0.75f); +                gGL.end(); -		gGL.getTexUnit(0)->bind(&mPhysicsDisplay); +                unbindDeferredShader(*shader); +                mScreen.flush(); +                gGL.setColorMask(true, true); +            } -		gGL.begin(LLRender::TRIANGLES); -		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.flush(); +            { // combine result based on alpha +                if (multisample) +                { +                    mDeferredLight.bindTarget(); +                    glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); +                } +                else +                { +                    gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; +                    gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; +                    gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); +                    gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); +                    glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); +                } -		if (LLGLSLShader::sNoFixedFunction) -		{ -			gSplatTextureRectProgram.unbind(); -		} -	} +                shader = &gDeferredDoFCombineProgram; +                bindDeferredShader(*shader); -	 -	if (LLRenderTarget::sUseFBO) -	{ //copy depth buffer from mScreen to framebuffer -		LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(),  -			0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); -	} -	 +                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); +                if (channel > -1) +                { +                    mScreen.bindTexture(0, channel); +                } -	gGL.matrixMode(LLRender::MM_PROJECTION); -	gGL.popMatrix(); -	gGL.matrixMode(LLRender::MM_MODELVIEW); -	gGL.popMatrix(); +                shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); +                shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); +                shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width - 1); +                shader->uniform1f(LLShaderMgr::DOF_HEIGHT, dof_height - 1); -	LLVertexBuffer::unbind(); +                gGL.begin(LLRender::TRIANGLE_STRIP); +                gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +                gGL.vertex2f(-1, -1); -	LLGLState::checkStates(); -	LLGLState::checkTextureChannels(); +                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(); + +                unbindDeferredShader(*shader); + +                if (multisample) +                { +                    mDeferredLight.flush(); +                } +            } +        } +        else +        { +            if (multisample) +            { +                mDeferredLight.bindTarget(); +            } +            LLGLSLShader *shader = &gDeferredPostNoDoFProgram; + +            bindDeferredShader(*shader); + +            S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); +            if (channel > -1) +            { +                mScreen.bindTexture(0, channel); +            } + +            gGL.begin(LLRender::TRIANGLE_STRIP); +            gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +            gGL.vertex2f(-1, -1); + +            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(); + +            unbindDeferredShader(*shader); + +            if (multisample) +            { +                mDeferredLight.flush(); +            } +        } + +        if (multisample) +        { +            // bake out texture2D with RGBL for FXAA shader +            mFXAABuffer.bindTarget(); + +            S32 width = mScreen.getWidth(); +            S32 height = mScreen.getHeight(); +            glViewport(0, 0, width, height); + +            LLGLSLShader *shader = &gGlowCombineFXAAProgram; + +            shader->bind(); +            shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); + +            S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); +            if (channel > -1) +            { +                mDeferredLight.bindTexture(0, channel); +            } + +            gGL.begin(LLRender::TRIANGLE_STRIP); +            gGL.vertex2f(-1, -1); +            gGL.vertex2f(-1, 3); +            gGL.vertex2f(3, -1); +            gGL.end(); + +            gGL.flush(); + +            shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); +            shader->unbind(); + +            mFXAABuffer.flush(); + +            shader = &gFXAAProgram; +            shader->bind(); + +            channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage()); +            if (channel > -1) +            { +                mFXAABuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); +            } + +            gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; +            gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; +            gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); +            gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); +            glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + +            F32 scale_x = (F32) width / mFXAABuffer.getWidth(); +            F32 scale_y = (F32) height / mFXAABuffer.getHeight(); +            shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); +            shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y); +            shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y, +                              0.5f / width * scale_x, 0.5f / height * scale_y); +            shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y, +                              2.f / width * scale_x, 2.f / height * scale_y); + +            gGL.begin(LLRender::TRIANGLE_STRIP); +            gGL.vertex2f(-1, -1); +            gGL.vertex2f(-1, 3); +            gGL.vertex2f(3, -1); +            gGL.end(); + +            gGL.flush(); +            shader->unbind(); +        } +    } +    else // not deferred +    { +        U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1; +        LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0); +        buff->allocateBuffer(3, 0, TRUE); + +        LLStrider<LLVector3> v; +        LLStrider<LLVector2> uv1; +        LLStrider<LLVector2> uv2; + +        buff->getVertexStrider(v); +        buff->getTexCoord0Strider(uv1); +        buff->getTexCoord1Strider(uv2); + +        uv1[0] = LLVector2(0, 0); +        uv1[1] = LLVector2(0, 2); +        uv1[2] = LLVector2(2, 0); + +        uv2[0] = LLVector2(0, 0); +        uv2[1] = LLVector2(0, tc2.mV[1] * 2.f); +        uv2[2] = LLVector2(tc2.mV[0] * 2.f, 0); + +        v[0] = LLVector3(-1, -1, 0); +        v[1] = LLVector3(-1, 3, 0); +        v[2] = LLVector3(3, -1, 0); + +        buff->flush(); + +        LLGLDisable blend(GL_BLEND); + +        if (LLGLSLShader::sNoFixedFunction) +        { +            gGlowCombineProgram.bind(); +        } +        else +        { +            // tex unit 0 +            gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR); +            // tex unit 1 +            gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, +                                                    LLTexUnit::TBS_PREV_COLOR); +        } + +        gGL.getTexUnit(0)->bind(&mGlow[1]); +        gGL.getTexUnit(1)->bind(&mScreen); + +        LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); + +        buff->setBuffer(mask); +        buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3); + +        if (LLGLSLShader::sNoFixedFunction) +        { +            gGlowCombineProgram.unbind(); +        } +        else +        { +            gGL.getTexUnit(1)->disable(); +            gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT); + +            gGL.getTexUnit(0)->activate(); +            gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +        } +    } + +    gGL.setSceneBlendType(LLRender::BT_ALPHA); + +    if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) +    { +        if (LLGLSLShader::sNoFixedFunction) +        { +            gSplatTextureRectProgram.bind(); +        } + +        gGL.setColorMask(true, false); +        LLVector2 tc1(0, 0); +        LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw() * 2, +                      (F32) gViewerWindow->getWorldViewHeightRaw() * 2); + +        LLGLEnable blend(GL_BLEND); +        gGL.color4f(1, 1, 1, 0.75f); + +        gGL.getTexUnit(0)->bind(&mPhysicsDisplay); + +        gGL.begin(LLRender::TRIANGLES); +        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.flush(); + +        if (LLGLSLShader::sNoFixedFunction) +        { +            gSplatTextureRectProgram.unbind(); +        } +    } + +    if (LLRenderTarget::sUseFBO) +    { // copy depth buffer from mScreen to framebuffer +        LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), 0, 0, +                                                  mScreen.getWidth(), mScreen.getHeight(), +                                                  GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); +    } + +    gGL.matrixMode(LLRender::MM_PROJECTION); +    gGL.popMatrix(); +    gGL.matrixMode(LLRender::MM_MODELVIEW); +    gGL.popMatrix(); + +    LLVertexBuffer::unbind(); + +    LLGLState::checkStates(); +    LLGLState::checkTextureChannels();  }  static LLTrace::BlockTimerStatHandle FTM_BIND_DEFERRED("Bind Deferred"); @@ -8453,292 +8408,301 @@ static LLTrace::BlockTimerStatHandle FTM_FULLSCREEN_LIGHTS("Fullscreen Lights");  static LLTrace::BlockTimerStatHandle FTM_PROJECTORS("Projectors");  static LLTrace::BlockTimerStatHandle FTM_POST("Post"); - -void LLPipeline::renderDeferredLighting(LLRenderTarget* screen_target) +void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)  { -	if (!sCull) -	{ -		return; -	} +    if (!sCull) +    { +        return; +    } -    LLRenderTarget* deferred_target       = &mDeferredScreen; -    LLRenderTarget* deferred_depth_target = &mDeferredDepth; -    LLRenderTarget* deferred_light_target = &mDeferredLight; +    LLRenderTarget *deferred_target       = &mDeferredScreen; +    LLRenderTarget *deferred_depth_target = &mDeferredDepth; +    LLRenderTarget *deferred_light_target = &mDeferredLight; -	{ -		LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED); -		LLViewerCamera* camera = LLViewerCamera::getInstance(); -		{ -			LLGLDepthTest depth(GL_TRUE); -            deferred_depth_target->copyContents(*deferred_target, 0, 0, deferred_target->getWidth(), deferred_target->getHeight(), -                            0, 0, deferred_depth_target->getWidth(), deferred_depth_target->getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);   -		} +    { +        LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED); +        LLViewerCamera *camera = LLViewerCamera::getInstance(); +        { +            LLGLDepthTest depth(GL_TRUE); +            deferred_depth_target->copyContents(*deferred_target, +                                                0, +                                                0, +                                                deferred_target->getWidth(), +                                                deferred_target->getHeight(), +                                                0, +                                                0, +                                                deferred_depth_target->getWidth(), +                                                deferred_depth_target->getHeight(), +                                                GL_DEPTH_BUFFER_BIT, +                                                GL_NEAREST); +        } -		LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); +        LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); -		if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) -		{ -			gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); -		} +        if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) +        { +            gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); +        } -		//ati doesn't seem to love actually using the stencil buffer on FBO's -		LLGLDisable stencil(GL_STENCIL_TEST); -		//glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); -		//glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); +        // ati doesn't seem to love actually using the stencil buffer on FBO's +        LLGLDisable stencil(GL_STENCIL_TEST); +        // glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); +        // glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); -		gGL.setColorMask(true, true); -		 -		//draw a cube around every light -		LLVertexBuffer::unbind(); +        gGL.setColorMask(true, true); -		LLGLEnable cull(GL_CULL_FACE); -		LLGLEnable blend(GL_BLEND); +        // draw a cube around every light +        LLVertexBuffer::unbind(); + +        LLGLEnable cull(GL_CULL_FACE); +        LLGLEnable blend(GL_BLEND);          glh::matrix4f mat = copy_matrix(gGLModelView); -		LLStrider<LLVector3> vert;  -		mDeferredVB->getVertexStrider(vert); -		 -		vert[0].set(-1,1,0); -		vert[1].set(-1,-3,0); -		vert[2].set(3,1,0); -		 -        setupHWLights(NULL); //to set mSun/MoonDir; +        LLStrider<LLVector3> vert; +        mDeferredVB->getVertexStrider(vert); + +        vert[0].set(-1, 1, 0); +        vert[1].set(-1, -3, 0); +        vert[2].set(3, 1, 0); + +        setupHWLights(NULL);  // to set mSun/MoonDir;          glh::vec4f tc(mSunDir.mV); -			mat.mult_matrix_vec(tc); -			mTransformedSunDir.set(tc.v); +        mat.mult_matrix_vec(tc); +        mTransformedSunDir.set(tc.v);          glh::vec4f tc_moon(mMoonDir.mV);          mat.mult_matrix_vec(tc_moon);          mTransformedMoonDir.set(tc_moon.v); -		gGL.pushMatrix(); -		gGL.loadIdentity(); -		gGL.matrixMode(LLRender::MM_PROJECTION); -		gGL.pushMatrix(); -		gGL.loadIdentity(); +        gGL.pushMatrix(); +        gGL.loadIdentity(); +        gGL.matrixMode(LLRender::MM_PROJECTION); +        gGL.pushMatrix(); +        gGL.loadIdentity(); -		if (RenderDeferredSSAO || RenderShadowDetail > 0) -		{ +        if (RenderDeferredSSAO || RenderShadowDetail > 0) +        {              deferred_light_target->bindTarget(); -			{ //paint shadow/SSAO light map (direct lighting lightmap) -				LL_RECORD_BLOCK_TIME(FTM_SUN_SHADOW); +            {  // paint shadow/SSAO light map (direct lighting lightmap) +                LL_RECORD_BLOCK_TIME(FTM_SUN_SHADOW);                  bindDeferredShader(gDeferredSunProgram, deferred_light_target); -				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -				glClearColor(1,1,1,1); +                mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +                glClearColor(1, 1, 1, 1);                  deferred_light_target->clear(GL_COLOR_BUFFER_BIT); -				glClearColor(0,0,0,0); +                glClearColor(0, 0, 0, 0);                  glh::matrix4f inv_trans = get_current_modelview().inverse().transpose(); -				const U32 slice = 32; -				F32 offset[slice*3]; -				for (U32 i = 0; i < 4; i++) -				{ -					for (U32 j = 0; j < 8; j++) -					{ -						glh::vec3f v; -						v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); -						v.normalize(); -						inv_trans.mult_matrix_vec(v); -						v.normalize(); -						offset[(i*8+j)*3+0] = v.v[0]; -						offset[(i*8+j)*3+1] = v.v[2]; -						offset[(i*8+j)*3+2] = v.v[1]; -					} -				} +                const U32 slice = 32; +                F32       offset[slice * 3]; +                for (U32 i = 0; i < 4; i++) +                { +                    for (U32 j = 0; j < 8; j++) +                    { +                        glh::vec3f v; +                        v.set_value(sinf(6.284f / 8 * j), cosf(6.284f / 8 * j), -(F32) i); +                        v.normalize(); +                        inv_trans.mult_matrix_vec(v); +                        v.normalize(); +                        offset[(i * 8 + j) * 3 + 0] = v.v[0]; +                        offset[(i * 8 + j) * 3 + 1] = v.v[2]; +                        offset[(i * 8 + j) * 3 + 2] = v.v[1]; +                    } +                } -				gDeferredSunProgram.uniform3fv(sOffset, slice, offset); -                gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, deferred_light_target->getWidth(), deferred_light_target->getHeight()); -				 -				{ -					LLGLDisable blend(GL_BLEND); -					LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); -					stop_glerror(); -					mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); -					stop_glerror(); -				} -				 -				unbindDeferredShader(gDeferredSunProgram); -			} +                gDeferredSunProgram.uniform3fv(sOffset, slice, offset); +                gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, +                                              deferred_light_target->getWidth(), +                                              deferred_light_target->getHeight()); + +                { +                    LLGLDisable   blend(GL_BLEND); +                    LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); +                    stop_glerror(); +                    mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); +                    stop_glerror(); +                } + +                unbindDeferredShader(gDeferredSunProgram); +            }              deferred_light_target->flush(); -		} -		 -		if (RenderDeferredSSAO) -		{ //soften direct lighting lightmap -			LL_RECORD_BLOCK_TIME(FTM_SOFTEN_SHADOW); -			//blur lightmap +        } + +        if (RenderDeferredSSAO) +        {  // soften direct lighting lightmap +            LL_RECORD_BLOCK_TIME(FTM_SOFTEN_SHADOW); +            // blur lightmap              screen_target->bindTarget(); -			glClearColor(1,1,1,1); +            glClearColor(1, 1, 1, 1);              screen_target->clear(GL_COLOR_BUFFER_BIT); -			glClearColor(0,0,0,0); -			 -			bindDeferredShader(gDeferredBlurLightProgram); -			mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -			LLVector3 go = RenderShadowGaussian; -			const U32 kern_length = 4; -			F32 blur_size = RenderShadowBlurSize; -			F32 dist_factor = RenderShadowBlurDistFactor; +            glClearColor(0, 0, 0, 0); -			// sample symmetrically with the middle sample falling exactly on 0.0 -			F32 x = 0.f; +            bindDeferredShader(gDeferredBlurLightProgram); +            mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +            LLVector3 go          = RenderShadowGaussian; +            const U32 kern_length = 4; +            F32       blur_size   = RenderShadowBlurSize; +            F32       dist_factor = RenderShadowBlurDistFactor; -			LLVector3 gauss[32]; // xweight, yweight, offset +            // sample symmetrically with the middle sample falling exactly on 0.0 +            F32 x = 0.f; -			for (U32 i = 0; i < kern_length; i++) -			{ -				gauss[i].mV[0] = llgaussian(x, go.mV[0]); -				gauss[i].mV[1] = llgaussian(x, go.mV[1]); -				gauss[i].mV[2] = x; -				x += 1.f; -			} +            LLVector3 gauss[32];  // xweight, yweight, offset + +            for (U32 i = 0; i < kern_length; i++) +            { +                gauss[i].mV[0] = llgaussian(x, go.mV[0]); +                gauss[i].mV[1] = llgaussian(x, go.mV[1]); +                gauss[i].mV[2] = x; +                x += 1.f; +            } + +            gDeferredBlurLightProgram.uniform2f(sDelta, 1.f, 0.f); +            gDeferredBlurLightProgram.uniform1f(sDistFactor, dist_factor); +            gDeferredBlurLightProgram.uniform3fv(sKern, kern_length, gauss[0].mV); +            gDeferredBlurLightProgram.uniform1f(sKernScale, blur_size * (kern_length / 2.f - 0.5f)); + +            { +                LLGLDisable   blend(GL_BLEND); +                LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); +                stop_glerror(); +                mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); +                stop_glerror(); +            } -			gDeferredBlurLightProgram.uniform2f(sDelta, 1.f, 0.f); -			gDeferredBlurLightProgram.uniform1f(sDistFactor, dist_factor); -			gDeferredBlurLightProgram.uniform3fv(sKern, kern_length, gauss[0].mV); -			gDeferredBlurLightProgram.uniform1f(sKernScale, blur_size * (kern_length/2.f - 0.5f)); -		 -			{ -				LLGLDisable blend(GL_BLEND); -				LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); -				stop_glerror(); -				mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); -				stop_glerror(); -			} -			              screen_target->flush(); -			unbindDeferredShader(gDeferredBlurLightProgram); +            unbindDeferredShader(gDeferredBlurLightProgram);              bindDeferredShader(gDeferredBlurLightProgram, screen_target); -			mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +            mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);              deferred_light_target->bindTarget(); -			gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f); +            gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f); -			{ -				LLGLDisable blend(GL_BLEND); -				LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); -				stop_glerror(); -				mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); -				stop_glerror(); -			} +            { +                LLGLDisable   blend(GL_BLEND); +                LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); +                stop_glerror(); +                mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); +                stop_glerror(); +            }              deferred_light_target->flush(); -			unbindDeferredShader(gDeferredBlurLightProgram); -		} +            unbindDeferredShader(gDeferredBlurLightProgram); +        } -		stop_glerror(); -		gGL.popMatrix(); -		stop_glerror(); -		gGL.matrixMode(LLRender::MM_MODELVIEW); -		stop_glerror(); -		gGL.popMatrix(); -		stop_glerror(); +        stop_glerror(); +        gGL.popMatrix(); +        stop_glerror(); +        gGL.matrixMode(LLRender::MM_MODELVIEW); +        stop_glerror(); +        gGL.popMatrix(); +        stop_glerror();          screen_target->bindTarget(); -		// clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky -		glClearColor(0,0,0,0); +        // clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky +        glClearColor(0, 0, 0, 0);          screen_target->clear(GL_COLOR_BUFFER_BIT); -		 -		if (RenderDeferredAtmospheric) -		{ //apply sunlight contribution  -            LLGLSLShader& soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram; -			LL_RECORD_BLOCK_TIME(FTM_ATMOSPHERICS); -            bindDeferredShader(soften_shader);   +        if (RenderDeferredAtmospheric) +        {  // apply sunlight contribution +            LLGLSLShader &soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram; -            LLEnvironment& environment = LLEnvironment::instance(); +            LL_RECORD_BLOCK_TIME(FTM_ATMOSPHERICS); +            bindDeferredShader(soften_shader); + +            LLEnvironment &environment = LLEnvironment::instance();              soften_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);              soften_shader.uniform4fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV); -			{ -				LLGLDepthTest depth(GL_FALSE); -				LLGLDisable blend(GL_BLEND); -				LLGLDisable test(GL_ALPHA_TEST); +            { +                LLGLDepthTest depth(GL_FALSE); +                LLGLDisable   blend(GL_BLEND); +                LLGLDisable   test(GL_ALPHA_TEST); -				//full screen blit -				gGL.pushMatrix(); -				gGL.loadIdentity(); -				gGL.matrixMode(LLRender::MM_PROJECTION); -				gGL.pushMatrix(); -				gGL.loadIdentity(); +                // full screen blit +                gGL.pushMatrix(); +                gGL.loadIdentity(); +                gGL.matrixMode(LLRender::MM_PROJECTION); +                gGL.pushMatrix(); +                gGL.loadIdentity(); -				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -				 -				mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); +                mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -				gGL.popMatrix(); -				gGL.matrixMode(LLRender::MM_MODELVIEW); -				gGL.popMatrix(); -			} +                mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); -			unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram); -		} +                gGL.popMatrix(); +                gGL.matrixMode(LLRender::MM_MODELVIEW); +                gGL.popMatrix(); +            } -		{ //render non-deferred geometry (fullbright, alpha, etc) -			LLGLDisable blend(GL_BLEND); -			LLGLDisable stencil(GL_STENCIL_TEST); -			gGL.setSceneBlendType(LLRender::BT_ALPHA); +            unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram); +        } -			gPipeline.pushRenderTypeMask(); -			 -			gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, -										LLPipeline::RENDER_TYPE_CLOUDS, -										LLPipeline::RENDER_TYPE_WL_SKY, -										LLPipeline::END_RENDER_TYPES); -								 -			 -			renderGeomPostDeferred(*LLViewerCamera::getInstance(), false); -			gPipeline.popRenderTypeMask(); -		} +        {  // render non-deferred geometry (fullbright, alpha, etc) +            LLGLDisable blend(GL_BLEND); +            LLGLDisable stencil(GL_STENCIL_TEST); +            gGL.setSceneBlendType(LLRender::BT_ALPHA); -		bool render_local = RenderLocalLights; -				 -		if (render_local) -		{ -			gGL.setSceneBlendType(LLRender::BT_ADD); -			std::list<LLVector4> fullscreen_lights; -			LLDrawable::drawable_list_t spot_lights; -			LLDrawable::drawable_list_t fullscreen_spot_lights; +            gPipeline.pushRenderTypeMask(); -			for (U32 i = 0; i < 2; i++) -			{ -				mTargetShadowSpotLight[i] = NULL; -			} +            gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, +                                        LLPipeline::RENDER_TYPE_CLOUDS, +                                        LLPipeline::RENDER_TYPE_WL_SKY, +                                        LLPipeline::END_RENDER_TYPES); -			std::list<LLVector4> light_colors; +            renderGeomPostDeferred(*LLViewerCamera::getInstance(), false); +            gPipeline.popRenderTypeMask(); +        } -			LLVertexBuffer::unbind(); +        bool render_local = RenderLocalLights; -			{ -				bindDeferredShader(gDeferredLightProgram); -				 -				if (mCubeVB.isNull()) -				{ -					mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); -				} +        if (render_local) +        { +            gGL.setSceneBlendType(LLRender::BT_ADD); +            std::list<LLVector4>        fullscreen_lights; +            LLDrawable::drawable_list_t spot_lights; +            LLDrawable::drawable_list_t fullscreen_spot_lights; -				mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -				 -				LLGLDepthTest depth(GL_TRUE, GL_FALSE); -				for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) -				{ -					LLDrawable* drawablep = *iter; -					 -					LLVOVolume* volume = drawablep->getVOVolume(); -					if (!volume) -					{ -						continue; -					} +            for (U32 i = 0; i < 2; i++) +            { +                mTargetShadowSpotLight[i] = NULL; +            } -					if (volume->isAttachment()) -					{ -						if (!sRenderAttachedLights) -						{ -							continue; -						} -					} +            std::list<LLVector4> light_colors; + +            LLVertexBuffer::unbind(); + +            { +                bindDeferredShader(gDeferredLightProgram); + +                if (mCubeVB.isNull()) +                { +                    mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); +                } + +                mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + +                LLGLDepthTest depth(GL_TRUE, GL_FALSE); +                for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) +                { +                    LLDrawable *drawablep = *iter; + +                    LLVOVolume *volume = drawablep->getVOVolume(); +                    if (!volume) +                    { +                        continue; +                    } + +                    if (volume->isAttachment()) +                    { +                        if (!sRenderAttachedLights) +                        { +                            continue; +                        } +                    }                      const LLViewerObject *vobj = drawablep->getVObj();                      if (vobj) @@ -8756,325 +8720,324 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget* screen_target)                          continue;                      } -					LLVector4a center; -					center.load3(position.mV); -					const F32* c = center.getF32ptr(); -					F32 s = volume->getLightRadius()*1.5f; +                    LLVector4a center; +                    center.load3(position.mV); +                    const F32 *c = center.getF32ptr(); +                    F32        s = volume->getLightRadius() * 1.5f; -                    //send light color to shader in linear space +                    // send light color to shader in linear space                      LLColor3 col = volume->getLightLinearColor(); -					 -					if (col.magVecSquared() < 0.001f) -					{ -						continue; -					} -					if (s <= 0.001f) -					{ -						continue; -					} +                    if (col.magVecSquared() < 0.001f) +                    { +                        continue; +                    } -					LLVector4a sa; -					sa.splat(s); -					if (camera->AABBInFrustumNoFarClip(center, sa) == 0) -					{ -						continue; -					} +                    if (s <= 0.001f) +                    { +                        continue; +                    } -					sVisibleLightCount++; -										 -					if (camera->getOrigin().mV[0] > c[0] + s + 0.2f || -						camera->getOrigin().mV[0] < c[0] - s - 0.2f || -						camera->getOrigin().mV[1] > c[1] + s + 0.2f || -						camera->getOrigin().mV[1] < c[1] - s - 0.2f || -						camera->getOrigin().mV[2] > c[2] + s + 0.2f || -						camera->getOrigin().mV[2] < c[2] - s - 0.2f) -					{ //draw box if camera is outside box -						if (render_local) -						{ -							if (volume->isLightSpotlight()) -							{ -								drawablep->getVOVolume()->updateSpotLightPriority(); -								spot_lights.push_back(drawablep); -								continue; -							} -							 -							LL_RECORD_BLOCK_TIME(FTM_LOCAL_LIGHTS); -							gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); -							gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); -							gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); +                    LLVector4a sa; +                    sa.splat(s); +                    if (camera->AABBInFrustumNoFarClip(center, sa) == 0) +                    { +                        continue; +                    } + +                    sVisibleLightCount++; + +                    if (camera->getOrigin().mV[0] > c[0] + s + 0.2f || camera->getOrigin().mV[0] < c[0] - s - 0.2f || +                        camera->getOrigin().mV[1] > c[1] + s + 0.2f || camera->getOrigin().mV[1] < c[1] - s - 0.2f || +                        camera->getOrigin().mV[2] > c[2] + s + 0.2f || camera->getOrigin().mV[2] < c[2] - s - 0.2f) +                    {  // draw box if camera is outside box +                        if (render_local) +                        { +                            if (volume->isLightSpotlight()) +                            { +                                drawablep->getVOVolume()->updateSpotLightPriority(); +                                spot_lights.push_back(drawablep); +                                continue; +                            } + +                            LL_RECORD_BLOCK_TIME(FTM_LOCAL_LIGHTS); +                            gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); +                            gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); +                            gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);                              gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF)); -							gGL.syncMatrices(); -							 -							mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); -							stop_glerror(); -						} -					} -					else -					{	 -						if (volume->isLightSpotlight()) -						{ -							drawablep->getVOVolume()->updateSpotLightPriority(); -							fullscreen_spot_lights.push_back(drawablep); -							continue; -						} +                            gGL.syncMatrices(); -						glh::vec3f tc(c); -						mat.mult_matrix_vec(tc); -					 -						fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s)); +                            mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); +                            stop_glerror(); +                        } +                    } +                    else +                    { +                        if (volume->isLightSpotlight()) +                        { +                            drawablep->getVOVolume()->updateSpotLightPriority(); +                            fullscreen_spot_lights.push_back(drawablep); +                            continue; +                        } + +                        glh::vec3f tc(c); +                        mat.mult_matrix_vec(tc); + +                        fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s));                          light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF))); -					} -				} -				unbindDeferredShader(gDeferredLightProgram); -			} +                    } +                } -			if (!spot_lights.empty()) -			{ -				LLGLDepthTest depth(GL_TRUE, GL_FALSE); -				bindDeferredShader(gDeferredSpotLightProgram); +                // Bookmark comment to allow searching for mSpecialRenderMode == 3 (avatar edit mode), +                // prev site of appended deferred character light, removed by SL-13522 09/20 -				mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +                unbindDeferredShader(gDeferredLightProgram); +            } -				gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); +            if (!spot_lights.empty()) +            { +                LLGLDepthTest depth(GL_TRUE, GL_FALSE); +                bindDeferredShader(gDeferredSpotLightProgram); -				for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter) -				{ -					LL_RECORD_BLOCK_TIME(FTM_PROJECTORS); -					LLDrawable* drawablep = *iter; +                mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -					LLVOVolume* volume = drawablep->getVOVolume(); +                gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); -					LLVector4a center; -					center.load3(drawablep->getPositionAgent().mV); -					const F32* c = center.getF32ptr(); -					F32 s = volume->getLightRadius()*1.5f; +                for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter) +                { +                    LL_RECORD_BLOCK_TIME(FTM_PROJECTORS); +                    LLDrawable *drawablep = *iter; -					sVisibleLightCount++; +                    LLVOVolume *volume = drawablep->getVOVolume(); -					setupSpotLight(gDeferredSpotLightProgram, drawablep); -					 -                    //send light color to shader in linear space +                    LLVector4a center; +                    center.load3(drawablep->getPositionAgent().mV); +                    const F32 *c = center.getF32ptr(); +                    F32        s = volume->getLightRadius() * 1.5f; + +                    sVisibleLightCount++; + +                    setupSpotLight(gDeferredSpotLightProgram, drawablep); + +                    // send light color to shader in linear space                      LLColor3 col = volume->getLightLinearColor(); -					 -					gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); -					gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); -					gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); + +                    gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); +                    gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); +                    gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);                      gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF)); -					gGL.syncMatrices(); -										 -					mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); -				} -				gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); -				unbindDeferredShader(gDeferredSpotLightProgram); -			} +                    gGL.syncMatrices(); -			//reset mDeferredVB to fullscreen triangle -			mDeferredVB->getVertexStrider(vert); -			vert[0].set(-1,1,0); -			vert[1].set(-1,-3,0); -			vert[2].set(3,1,0); +                    mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); +                } +                gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); +                unbindDeferredShader(gDeferredSpotLightProgram); +            } -			{ -				LLGLDepthTest depth(GL_FALSE); +            // reset mDeferredVB to fullscreen triangle +            mDeferredVB->getVertexStrider(vert); +            vert[0].set(-1, 1, 0); +            vert[1].set(-1, -3, 0); +            vert[2].set(3, 1, 0); -				//full screen blit -				gGL.pushMatrix(); -				gGL.loadIdentity(); -				gGL.matrixMode(LLRender::MM_PROJECTION); -				gGL.pushMatrix(); -				gGL.loadIdentity(); +            { +                LLGLDepthTest depth(GL_FALSE); -				U32 count = 0; +                // full screen blit +                gGL.pushMatrix(); +                gGL.loadIdentity(); +                gGL.matrixMode(LLRender::MM_PROJECTION); +                gGL.pushMatrix(); +                gGL.loadIdentity(); -				const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT; -				LLVector4 light[max_count]; -				LLVector4 col[max_count]; +                U32 count = 0; -				F32 far_z = 0.f; +                const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT; +                LLVector4 light[max_count]; +                LLVector4 col[max_count]; -				while (!fullscreen_lights.empty()) -				{ -					LL_RECORD_BLOCK_TIME(FTM_FULLSCREEN_LIGHTS); -					light[count] = fullscreen_lights.front(); -					fullscreen_lights.pop_front(); -					col[count] = light_colors.front(); -					light_colors.pop_front(); - -					far_z = llmin(light[count].mV[2]-light[count].mV[3], far_z); -					count++; -					if (count == max_count || fullscreen_lights.empty()) -					{ -						U32 idx = count-1; -						bindDeferredShader(gDeferredMultiLightProgram[idx]); -						gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count); -						gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light); -						gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col); -						gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z); -						far_z = 0.f; -						count = 0;  -      mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -						mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); -						unbindDeferredShader(gDeferredMultiLightProgram[idx]); -					} -				} -				 -				bindDeferredShader(gDeferredMultiSpotLightProgram); +                F32 far_z = 0.f; -				gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); +                while (!fullscreen_lights.empty()) +                { +                    LL_RECORD_BLOCK_TIME(FTM_FULLSCREEN_LIGHTS); +                    light[count] = fullscreen_lights.front(); +                    fullscreen_lights.pop_front(); +                    col[count] = light_colors.front(); +                    light_colors.pop_front(); + +                    far_z = llmin(light[count].mV[2] - light[count].mV[3], far_z); +                    count++; +                    if (count == max_count || fullscreen_lights.empty()) +                    { +                        U32 idx = count - 1; +                        bindDeferredShader(gDeferredMultiLightProgram[idx]); +                        gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count); +                        gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat *) light); +                        gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat *) col); +                        gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z); +                        far_z = 0.f; +                        count = 0; +                        mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +                        mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); +                        unbindDeferredShader(gDeferredMultiLightProgram[idx]); +                    } +                } -				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +                bindDeferredShader(gDeferredMultiSpotLightProgram); -				for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter) -				{ -					LL_RECORD_BLOCK_TIME(FTM_PROJECTORS); -					LLDrawable* drawablep = *iter; -					 -					LLVOVolume* volume = drawablep->getVOVolume(); +                gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); -					LLVector3 center = drawablep->getPositionAgent(); -					F32* c = center.mV; -                    F32 light_size_final = volume->getLightRadius()*1.5f; -                    F32 light_falloff_final = volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF); +                mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -					sVisibleLightCount++; +                for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter) +                { +                    LL_RECORD_BLOCK_TIME(FTM_PROJECTORS); +                    LLDrawable *drawablep           = *iter; +                    LLVOVolume *volume              = drawablep->getVOVolume(); +                    LLVector3   center              = drawablep->getPositionAgent(); +                    F32 *       c                   = center.mV; +                    F32         light_size_final    = volume->getLightRadius() * 1.5f; +                    F32         light_falloff_final = volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF); -					glh::vec3f tc(c); -					mat.mult_matrix_vec(tc); -					 -					setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); +                    sVisibleLightCount++; + +                    glh::vec3f tc(c); +                    mat.mult_matrix_vec(tc); -                    //send light color to shader in linear space +                    setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); + +                    // send light color to shader in linear space                      LLColor3 col = volume->getLightLinearColor(); -					 -					gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v); + +                    gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);                      gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, light_size_final); -					gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); +                    gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);                      gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, light_falloff_final); -					mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); -				} +                    mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); +                } -				gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); -				unbindDeferredShader(gDeferredMultiSpotLightProgram); +                gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); +                unbindDeferredShader(gDeferredMultiSpotLightProgram); -				gGL.popMatrix(); -				gGL.matrixMode(LLRender::MM_MODELVIEW); -				gGL.popMatrix(); -			} -		} +                gGL.popMatrix(); +                gGL.matrixMode(LLRender::MM_MODELVIEW); +                gGL.popMatrix(); +            } +        } -		gGL.setColorMask(true, true); -	} +        gGL.setColorMask(true, true); +    }      screen_target->flush(); -	//gamma correct lighting -	gGL.matrixMode(LLRender::MM_PROJECTION); -	gGL.pushMatrix(); -	gGL.loadIdentity(); -	gGL.matrixMode(LLRender::MM_MODELVIEW); -	gGL.pushMatrix(); -	gGL.loadIdentity(); +    // gamma correct lighting +    gGL.matrixMode(LLRender::MM_PROJECTION); +    gGL.pushMatrix(); +    gGL.loadIdentity(); +    gGL.matrixMode(LLRender::MM_MODELVIEW); +    gGL.pushMatrix(); +    gGL.loadIdentity(); -	{ -		LLGLDepthTest depth(GL_FALSE, GL_FALSE); +    { +        LLGLDepthTest depth(GL_FALSE, GL_FALSE); -		LLVector2 tc1(0,0); -        LLVector2 tc2((F32) screen_target->getWidth()*2, -                  (F32) screen_target->getHeight()*2); +        LLVector2 tc1(0, 0); +        LLVector2 tc2((F32) screen_target->getWidth() * 2, (F32) screen_target->getHeight() * 2);          screen_target->bindTarget(); -		// Apply gamma correction to the frame here. -		gDeferredPostGammaCorrectProgram.bind(); -		//mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -		S32 channel = 0; -        channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screen_target->getUsage()); -		if (channel > -1) -		{ +        // Apply gamma correction to the frame here. +        gDeferredPostGammaCorrectProgram.bind(); +        // mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +        S32 channel = 0; +        channel     = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screen_target->getUsage()); +        if (channel > -1) +        {              screen_target->bindTexture(0, channel, LLTexUnit::TFO_POINT); -		} -		 +        } +          gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screen_target->getWidth(), screen_target->getHeight()); -		 -		F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); -		gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); -		 -		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(); -		 +        F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); + +        gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f)); + +        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(screen_target->getUsage()); -		gDeferredPostGammaCorrectProgram.unbind(); +        gDeferredPostGammaCorrectProgram.unbind();          screen_target->flush(); -	} +    } -	gGL.matrixMode(LLRender::MM_PROJECTION); -	gGL.popMatrix(); -	gGL.matrixMode(LLRender::MM_MODELVIEW); -	gGL.popMatrix();	 +    gGL.matrixMode(LLRender::MM_PROJECTION); +    gGL.popMatrix(); +    gGL.matrixMode(LLRender::MM_MODELVIEW); +    gGL.popMatrix();      screen_target->bindTarget(); -	{ //render non-deferred geometry (alpha, fullbright, glow) -		LLGLDisable blend(GL_BLEND); -		LLGLDisable stencil(GL_STENCIL_TEST); - -		pushRenderTypeMask(); -		andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, -						 LLPipeline::RENDER_TYPE_FULLBRIGHT, -						 LLPipeline::RENDER_TYPE_VOLUME, -						 LLPipeline::RENDER_TYPE_GLOW, -						 LLPipeline::RENDER_TYPE_BUMP, -						 LLPipeline::RENDER_TYPE_PASS_SIMPLE, -						 LLPipeline::RENDER_TYPE_PASS_ALPHA, -						 LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, -						 LLPipeline::RENDER_TYPE_PASS_BUMP, -						 LLPipeline::RENDER_TYPE_PASS_POST_BUMP, -						 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, -						 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, -						 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, -						 LLPipeline::RENDER_TYPE_PASS_GLOW, -						 LLPipeline::RENDER_TYPE_PASS_GRASS, -						 LLPipeline::RENDER_TYPE_PASS_SHINY, -						 LLPipeline::RENDER_TYPE_PASS_INVISIBLE, -						 LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, -						 LLPipeline::RENDER_TYPE_AVATAR, -						 LLPipeline::RENDER_TYPE_ALPHA_MASK, -						 LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, -						 END_RENDER_TYPES); -		 -		renderGeomPostDeferred(*LLViewerCamera::getInstance()); -		popRenderTypeMask(); -	} +    {  // render non-deferred geometry (alpha, fullbright, glow) +        LLGLDisable blend(GL_BLEND); +        LLGLDisable stencil(GL_STENCIL_TEST); + +        pushRenderTypeMask(); +        andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, +                          LLPipeline::RENDER_TYPE_FULLBRIGHT, +                          LLPipeline::RENDER_TYPE_VOLUME, +                          LLPipeline::RENDER_TYPE_GLOW, +                          LLPipeline::RENDER_TYPE_BUMP, +                          LLPipeline::RENDER_TYPE_PASS_SIMPLE, +                          LLPipeline::RENDER_TYPE_PASS_ALPHA, +                          LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, +                          LLPipeline::RENDER_TYPE_PASS_BUMP, +                          LLPipeline::RENDER_TYPE_PASS_POST_BUMP, +                          LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, +                          LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, +                          LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, +                          LLPipeline::RENDER_TYPE_PASS_GLOW, +                          LLPipeline::RENDER_TYPE_PASS_GRASS, +                          LLPipeline::RENDER_TYPE_PASS_SHINY, +                          LLPipeline::RENDER_TYPE_PASS_INVISIBLE, +                          LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, +                          LLPipeline::RENDER_TYPE_AVATAR, +                          LLPipeline::RENDER_TYPE_CONTROL_AV, +                          LLPipeline::RENDER_TYPE_ALPHA_MASK, +                          LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, +                          END_RENDER_TYPES); + +        renderGeomPostDeferred(*LLViewerCamera::getInstance()); +        popRenderTypeMask(); +    } -	{ -		//render highlights, etc. -		renderHighlights(); -		mHighlightFaces.clear(); +    { +        // render highlights, etc. +        renderHighlights(); +        mHighlightFaces.clear(); -		renderDebug(); +        renderDebug(); -		LLVertexBuffer::unbind(); +        LLVertexBuffer::unbind(); -		if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) -		{ -			// Render debugging beacons. -			gObjectList.renderObjectBeacons(); -			gObjectList.resetObjectBeacons(); +        if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) +        { +            // Render debugging beacons. +            gObjectList.renderObjectBeacons(); +            gObjectList.resetObjectBeacons();              gSky.addSunMoonBeacons(); -		} -	} +        } +    } -	screen_target->flush();                         +    screen_target->flush();  }  void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) @@ -9291,7 +9254,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  		gPipeline.pushRenderTypeMask(); -        glh::matrix4f projection = get_current_projection(); +        glh::matrix4f saved_modelview  = get_current_modelview(); +        glh::matrix4f saved_projection = get_current_projection();  		glh::matrix4f mat;          S32 detail = RenderReflectionDetail; @@ -9330,8 +9294,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  			//disable occlusion culling for reflection map for now  			LLPipeline::sUseOcclusion = 0; -        glh::matrix4f current = get_current_modelview(); -          if (!camera_is_underwater)          {   //generate planar reflection map @@ -9340,15 +9302,10 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)              gGL.matrixMode(LLRender::MM_MODELVIEW);              gGL.pushMatrix(); -            glh::matrix4f mat; -            camera.getOpenGLTransform(mat.m); - -            glh::matrix4f scal; -            scal.set_scale(glh::vec3f(1, 1, -1)); -            mat = scal * mat; +            mat.set_scale(glh::vec3f(1, 1, -1)); +            mat.set_translate(glh::vec3f(0,0,water_height*2.f)); +            mat = saved_modelview * mat; -            // convert from CFR to OGL coord sys... -            mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat;              mReflectionModelView = mat; @@ -9357,6 +9314,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  			LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE); +            glh::vec3f    origin(0, 0, 0); +            glh::matrix4f inv_mat = mat.inverse(); +            inv_mat.mult_matrix_vec(origin); + +            camera.setOrigin(origin.v); +  			glCullFace(GL_FRONT);  			if (LLDrawPoolWater::sNeedsReflectionUpdate) @@ -9401,7 +9364,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  						clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES);  						if (detail < 3)  						{ -							clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); +                            clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, LLPipeline::RENDER_TYPE_CONTROL_AV, END_RENDER_TYPES);  							if (detail < 2)  							{  								clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES); @@ -9409,7 +9372,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  						}  					} -                    LLGLUserClipPlane clip_plane(plane, mReflectionModelView, projection); +                    LLGLUserClipPlane clip_plane(plane, mReflectionModelView, saved_projection);  					LLGLDisable cull(GL_CULL_FACE);                      updateCull(camera, mReflectedObjects, -water_clip, &plane);                      stateSort(camera, mReflectedObjects); @@ -9423,7 +9386,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)              gGL.matrixMode(LLRender::MM_MODELVIEW);  			gGL.popMatrix(); -            set_current_modelview(current);          +            set_current_modelview(saved_modelview);  		}          //LLPipeline::sUseOcclusion = occlusion; @@ -9479,7 +9442,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)                  //clip out geometry on the same side of water as the camera w/ enough margin to not include the water geo itself,                  // but not so much as to clip out parts of avatars that should be seen under the water in the distortion map                  LLPlane plane(-pnorm, water_dist); -                LLGLUserClipPlane clip_plane(plane, current, projection); +                LLGLUserClipPlane clip_plane(plane, saved_modelview, saved_projection);  				gGL.setColorMask(true, true);  				mWaterDis.clear(); @@ -10116,6 +10079,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  					LLPipeline::RENDER_TYPE_BUMP,  					LLPipeline::RENDER_TYPE_VOLUME,  					LLPipeline::RENDER_TYPE_AVATAR, +					LLPipeline::RENDER_TYPE_CONTROL_AV,  					LLPipeline::RENDER_TYPE_TREE,   					LLPipeline::RENDER_TYPE_TERRAIN,  					LLPipeline::RENDER_TYPE_WATER, @@ -10909,7 +10873,9 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  	if (visually_muted || too_complex)  	{ -		andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); +		andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, +							LLPipeline::RENDER_TYPE_CONTROL_AV, +							END_RENDER_TYPES);  	}  	else  	{ @@ -10932,6 +10898,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  						LLPipeline::RENDER_TYPE_PASS_INVISIBLE,  						LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,  			LLPipeline::RENDER_TYPE_AVATAR, +			LLPipeline::RENDER_TYPE_CONTROL_AV,  			LLPipeline::RENDER_TYPE_ALPHA_MASK,  			LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,  			LLPipeline::RENDER_TYPE_INVISIBLE, diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 68ce3fe88d..600bdd9d06 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -139,7 +139,7 @@ public:  	void resetVertexBuffers(LLDrawable* drawable);  	void generateImpostor(LLVOAvatar* avatar);  	void bindScreenToTexture(); -	void renderBloom(bool for_snapshot, F32 zoom_factor = 1.f, int subfield = 0); +	void renderFinalize();  	void init();  	void cleanup(); @@ -453,6 +453,7 @@ public:  		RENDER_TYPE_BUMP						= LLDrawPool::POOL_BUMP,  		RENDER_TYPE_MATERIALS					= LLDrawPool::POOL_MATERIALS,  		RENDER_TYPE_AVATAR						= LLDrawPool::POOL_AVATAR, +		RENDER_TYPE_CONTROL_AV					= LLDrawPool::POOL_CONTROL_AV, // Animesh  		RENDER_TYPE_TREE						= LLDrawPool::POOL_TREE,  		RENDER_TYPE_INVISIBLE					= LLDrawPool::POOL_INVISIBLE,  		RENDER_TYPE_VOIDWATER					= LLDrawPool::POOL_VOIDWATER, diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 873b95926b..5fa1847d1b 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1733,6 +1733,16 @@ function="World.EnvPreset"                   parameter="character" />              </menu_item_check>              <menu_item_check +             label="Animeshes" +             name="Rendering Type Control Avatar"> +                <menu_item_check.on_check +                 function="Advanced.CheckRenderType" +                 parameter="controlAV" /> +                <menu_item_check.on_click +                 function="Advanced.ToggleRenderType" +                 parameter="controlAV" /> +            </menu_item_check> +            <menu_item_check               label="Surface Patch"               name="Rendering Type Surface Patch"               shortcut="control|alt|shift|5"> diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml index bec793bbee..6f82a0efa1 100644 --- a/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml +++ b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml @@ -203,10 +203,10 @@                          Ice Level:                      </text>                      <slider -                            decimal_digits="1" +                            decimal_digits="3"                              follows="left|top"                              height="14" -                            increment="0.1" +                            increment="0.001"                              initial_value="0"                              left_delta="5"                              top_delta="20" | 
