diff --git a/autobuild.xml b/autobuild.xml
index 4c52a6199b..e74a504656 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -290,7 +290,7 @@
version
1.2.15
-
+
apr_suite
+ skipupdatecheck
+
+ desc
+ Skips update check at startup.
+ map-to
+ CmdLineSkipUpdater
+
+
-
-
diff --git a/indra/newview/app_settings/low_graphics.xml b/indra/newview/app_settings/low_graphics.xml
index df3f67a5a1..0ee8e7a059 100644
--- a/indra/newview/app_settings/low_graphics.xml
+++ b/indra/newview/app_settings/low_graphics.xml
@@ -33,8 +33,6 @@
-
-
diff --git a/indra/newview/app_settings/mid_graphics.xml b/indra/newview/app_settings/mid_graphics.xml
index a10c02b79f..c89e060307 100644
--- a/indra/newview/app_settings/mid_graphics.xml
+++ b/indra/newview/app_settings/mid_graphics.xml
@@ -33,8 +33,6 @@
-
-
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index efd0bde0b8..ecb16e5145 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -2786,6 +2786,17 @@
Value
1
+ BulkChangeIncludeSettings
+
+ Comment
+ Bulk permission changes affect environment settings
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
BulkChangeEveryoneCopy
Comment
@@ -3499,18 +3510,18 @@
Value
- CmdLineLoginURI1
+ CmdLineSkipUpdater
Comment
- Command line specified login server and CGI prefix to use.
+ Command line skip updater check.
Persist
0
Type
- String
+ Boolean
Value
-
+ 0
- ConnectAsGod
+ ConnectAsGod
Comment
Log in as god if you have god access.
@@ -9389,6 +9400,17 @@
Value
0
+ MouseMoon
+
+ Comment
+
+ Persist
+ 0
+ Type
+ Boolean
+ Value
+ 0
+
MuteAmbient
Comment
@@ -11284,6 +11306,28 @@ Change of this parameter will affect the layout of buttons in notification toast
0
+ RenderAlphaBatchFullbrights
+
+ Comment
+ Render fullbright alpha content more efficiently, but with possible visual differences from prev viewers.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
+ RenderAlphaBatchEmissives
+
+ Comment
+ Render emissive alpha content more efficiently, but with possible visual differences from prev viewers.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
RenderAnisotropic
Comment
@@ -11792,6 +11836,17 @@ Change of this parameter will affect the layout of buttons in notification toast
Backup
0
+ RenderDebugSH
+
+ Comment
+ Enable SH indirect lighting visualization.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
RenderMaxTextureIndex
Comment
@@ -11973,7 +12028,7 @@ Change of this parameter will affect the layout of buttons in notification toast
Type
F32
Value
- -0.008
+ -0.004
Backup
0
@@ -13186,6 +13241,17 @@ Change of this parameter will affect the layout of buttons in notification toast
Value
0
+ RenderUseAdvancedAtmospherics
+
+ Comment
+ Use fancy precomputed atmospherics and stuff.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
RenderUseTriStrips
Comment
@@ -14928,6 +14994,21 @@ Change of this parameter will affect the layout of buttons in notification toast
Backup
0
+ SkyMoonDefaultPosition
+
+ Comment
+ Default position of sun in sky (direction in world coordinates)
+ Persist
+ 1
+ Type
+ Vector3
+ Value
+
+ -1.0
+ 0.0
+ -0.1
+
+
SkyNightColorShift
Comment
@@ -15304,6 +15385,39 @@ Change of this parameter will affect the layout of buttons in notification toast
Backup
0
+ AmbientDisable
+
+ Comment
+ If TRUE, ambient light has no effect
+ Persist
+ 0
+ Type
+ Boolean
+ Value
+ 0
+
+ SunlightDisable
+
+ Comment
+ If TRUE, sunlight has no effect
+ Persist
+ 0
+ Type
+ Boolean
+ Value
+ 0
+
+ LocalLightDisable
+
+ Comment
+ If TRUE, local lights have no effect
+ Persist
+ 0
+ Type
+ Boolean
+ Value
+ 0
+
TextureDiscardLevel
Comment
@@ -17209,17 +17323,6 @@ Change of this parameter will affect the layout of buttons in notification toast
Value
1
- UseEnvironmentFromRegion
-
- Comment
- Choose whether to use the region's environment settings, or override them with the local settings.
- Persist
- 1
- Type
- Boolean
- Value
- 1
-
EnvironmentPersistAcrossLogin
Comment
@@ -17666,6 +17769,7 @@ Change of this parameter will affect the layout of buttons in notification toast
Value
1
+
VivoxAutoPostCrashDumps
Comment
@@ -18431,6 +18536,28 @@ Change of this parameter will affect the layout of buttons in notification toast
Value
0
+ sunbeacon
+
+ Comment
+ Show direction to the Sun
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
+ moonbeacon
+
+ Comment
+ Show direction to the Moon
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
ShowDeviceSettings
Comment
@@ -18998,50 +19125,6 @@ Change of this parameter will affect the layout of buttons in notification toast
bw
- FSWLParcelEnabled
-
- Comment
- Enables auto setting WL from parcel desc flags
- Persist
- 1
- Type
- Boolean
- Value
- 1
-
- FSWLWhitelistFriends
-
- Comment
- Whitelist friend's land for Phoenix WL sharing
- Persist
- 1
- Type
- Boolean
- Value
- 1
-
- FSWLWhitelistGroups
-
- Comment
- Whitelist group land on groups you are member of for Phoenix WL sharing
- Persist
- 1
- Type
- Boolean
- Value
- 1
-
- FSWLWhitelistAll
-
- Comment
- Allow all land for Phoenix WL sharing
- Persist
- 1
- Type
- Boolean
- Value
- 0
-
FSIgnoreClientsideMeshValidation
Comment
@@ -20118,6 +20201,28 @@ Change of this parameter will affect the layout of buttons in notification toast
Value
0
+ SettingsNextOwnerModify
+
+ Comment
+ Newly created Environment setting can be modified by next owner
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
+ SettingsNextOwnerTransfer
+
+ Comment
+ Newly created Environment setting can be resold or given away by next owner
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
DefaultUploadPermissionsConverted
Comment
@@ -20618,50 +20723,6 @@ Change of this parameter will affect the layout of buttons in notification toast
Value
3
- UseEnvironmentFromRegionAlways
-
- Comment
- Choose whether to always use the region's environment settings when they are available or to allow the manual selections to remain unchanged.
- Persist
- 1
- Type
- Boolean
- Value
- 1
-
- FSInterpolateSky
-
- Comment
- FSInterpolateSky
- Persist
- 1
- Type
- Boolean
- Value
- 1
-
- FSInterpolateWater
-
- Comment
- FSInterpolateWater
- Persist
- 1
- Type
- Boolean
- Value
- 1
-
- FSWindlightInterpolateTime
-
- Comment
- Timespan for interpolating between Windlight settings
- Persist
- 1
- Type
- F32
- Value
- 3.0
-
_NACL_MLFovValues
Comment
@@ -22543,17 +22604,6 @@ Change of this parameter will affect the layout of buttons in notification toast
Value
0
- FSOpenSimLightshare
-
- Comment
- Enables Lightshare WindLight on compatible OpenSim regions
- Persist
- 1
- Type
- Boolean
- Value
- 1
-
FSAlwaysOpaqueCameraControls
Comment
@@ -22674,17 +22724,6 @@ Change of this parameter will affect the layout of buttons in notification toast
Backup
0
- FSCloudTexture
-
- Comment
- Windlight cloud texture (don't edit by hand)
- Persist
- 1
- Type
- String
- Value
- Default.tga
-
FSLoginDontSavePassword
Comment
diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl
index 19203ab670..0543a26642 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl
@@ -34,7 +34,7 @@ VARYING vec2 vary_texcoord0;
uniform vec4 color;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
mat4 getSkinnedTransform();
void calcAtmospherics(vec3 inPositionEye);
@@ -62,7 +62,7 @@ void main()
calcAtmospherics(pos.xyz);
- vec4 col = calcLighting(pos.xyz, norm, color, vec4(0,0,0,0));
+ vec4 col = calcLighting(pos.xyz, norm, color);
vertex_color = col;
}
diff --git a/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl b/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl
index 82db15c3ae..fac1599c6b 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl
@@ -36,7 +36,7 @@ ATTRIBUTE vec2 texcoord0;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol);
+vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor);
void calcAtmospherics(vec3 inPositionEye);
void main()
@@ -52,7 +52,7 @@ void main()
calcAtmospherics(pos.xyz);
vec4 specular = vec4(1.0);
- vec4 color = calcLightingSpecular(pos, norm, diffuse_color, specular, vec4(0.0));
+ vec4 color = calcLightingSpecular(pos, norm, diffuse_color, specular);
vertex_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
index 0028ee7ef6..dc484317e9 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
@@ -22,7 +22,9 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
+//class1/deferred/alphaF.glsl
+
#extension GL_ARB_texture_rectangle : enable
/*[EXTRA_CODE_HERE]*/
@@ -37,39 +39,9 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
-uniform float display_gamma;
-uniform vec4 gamma;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 ambient;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
-uniform float haze_horizon;
-uniform float haze_density;
-uniform float cloud_shadow;
-uniform float density_multiplier;
-uniform float distance_multiplier;
-uniform float max_y;
-uniform vec4 glow;
-uniform float scene_light_strength;
uniform mat3 env_mat;
-uniform mat3 ssao_effect_mat;
-
uniform vec3 sun_dir;
-
-#if HAS_SHADOW
-uniform sampler2DShadow shadowMap0;
-uniform sampler2DShadow shadowMap1;
-uniform sampler2DShadow shadowMap2;
-uniform sampler2DShadow shadowMap3;
-
-uniform vec2 shadow_res;
-
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-uniform float shadow_bias;
-
-#endif
+uniform vec3 moon_dir;
#ifdef USE_DIFFUSE_TEX
uniform sampler2D diffuseMap;
@@ -81,560 +53,254 @@ VARYING vec2 vary_texcoord0;
VARYING vec3 vary_norm;
#ifdef USE_VERTEX_COLOR
-VARYING vec4 vertex_color;
+VARYING vec4 vertex_color; //vertex color should be treated as sRGB
#endif
-vec3 vary_PositionEye;
-vec3 vary_SunlitColor;
-vec3 vary_AmblitColor;
-vec3 vary_AdditiveColor;
-vec3 vary_AtmosAttenuation;
-
+uniform mat4 proj_mat;
uniform mat4 inv_proj;
uniform vec2 screen_res;
-
+uniform int sun_up_factor;
uniform vec4 light_position[8];
uniform vec3 light_direction[8];
-uniform vec3 light_attenuation[8];
+uniform vec4 light_attenuation[8];
uniform vec3 light_diffuse[8];
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
+#ifdef WATER_FOG
+vec4 applyWaterFogView(vec3 pos, vec4 color);
#endif
-}
+vec3 srgb_to_linear(vec3 c);
+vec3 linear_to_srgb(vec3 c);
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
+vec2 encode_normal (vec3 n);
+vec3 scaleSoftClipFrag(vec3 l);
+vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten);
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
+void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive, bool use_ao);
+
+#ifdef HAS_SHADOW
+float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
#endif
-}
+float getAmbientClamp();
-vec2 encode_normal(vec3 n)
+vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, float ambiance)
{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+ vec3 col = vec3(0);
-vec3 decode_normal (vec2 enc)
-{
- vec2 fenc = enc*4-2;
- float f = dot(fenc,fenc);
- float g = sqrt(1-f/4);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1-f/2;
- return n;
-}
-
-vec3 calcDirectionalLight(vec3 n, vec3 l)
-{
- float a = max(dot(n,l),0.0);
- a = pow(a, 1.0/1.3);
- return vec3(a,a,a);
-}
-
-vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
-{
//get light vector
vec3 lv = lp.xyz-v;
-
+
//get distance
- float d = length(lv);
-
+ float dist = length(lv);
float da = 1.0;
- vec3 col = vec3(0);
+ /*if (dist > la)
+ {
+ return col;
+ }
- if (d > 0.0 && la > 0.0 && fa > 0.0)
+ clip to projector bounds
+ vec4 proj_tc = proj_mat * lp;
+
+ if (proj_tc.z < 0
+ || proj_tc.z > 1
+ || proj_tc.x < 0
+ || proj_tc.x > 1
+ || proj_tc.y < 0
+ || proj_tc.y > 1)
+ {
+ return col;
+ }*/
+
+ if (dist > 0.0 && la > 0.0)
{
+ dist /= la;
+
//normalize light vector
lv = normalize(lv);
//distance attenuation
- float dist = d/la;
float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
dist_atten *= dist_atten;
- dist_atten *= 2.0;
+ 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 *= max(dot(n, lv), 0.0);
+ da *= dot(n, lv);
+ da = max(0.0, da);
- float lit = max(da * dist_atten,0.0);
+ float lit = 0.0f;
- col = light_col * lit * diffuse;
+ float amb_da = 0.0;//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);
- // no spec for alpha shader...
- }
+ // SL-10969 ... need to work out why this blows out in many setups...
+ //col.rgb += amb_da * light_col * diffuse;
- return max(col, vec3(0.0,0.0,0.0));
-}
-
-#if HAS_SHADOW
-float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
-{
- stc.xyz /= stc.w;
- stc.z += shadow_bias;
-
- stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
-
- float cs = shadow2D(shadowMap, stc.xyz).x;
- float shadow = cs;
-
- shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
-
- return shadow*0.2;
-}
-#endif
-
-#ifdef WATER_FOG
-uniform vec4 waterPlane;
-uniform vec4 waterFogColor;
-uniform float waterFogDensity;
-uniform float waterFogKS;
-
-vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
-{
- //normalize view vector
- vec3 view = normalize(pos);
- float es = -(dot(view, waterPlane.xyz));
-
- //find intersection point with water plane and eye vector
-
- //get eye depth
- float e0 = max(-waterPlane.w, 0.0);
-
- vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
-
- //get object depth
- float depth = length(pos - int_v);
-
- //get "thickness" of water
- float l = max(depth, 0.1);
-
- float kd = waterFogDensity;
- float ks = waterFogKS;
- vec4 kc = waterFogColor;
-
- float F = 0.98;
-
- float t1 = -kd * pow(F, ks * e0);
- float t2 = kd + ks * es;
- float t3 = pow(F, t2*l) - 1.0;
-
- float L = min(t1/t2*t3, 1.0);
-
- float D = pow(0.98, l*kd);
-
- color.rgb = color.rgb * D + kc.rgb * L;
- color.a = kc.a + color.a;
-
- return color;
-}
-#endif
-
-vec3 getSunlitColor()
-{
- return vary_SunlitColor;
-}
-vec3 getAmblitColor()
-{
- return vary_AmblitColor;
-}
-vec3 getAdditiveColor()
-{
- return vary_AdditiveColor;
-}
-vec3 getAtmosAttenuation()
-{
- return vary_AtmosAttenuation;
-}
-
-void setPositionEye(vec3 v)
-{
- vary_PositionEye = v;
-}
-
-void setSunlitColor(vec3 v)
-{
- vary_SunlitColor = v;
-}
-
-void setAmblitColor(vec3 v)
-{
- vary_AmblitColor = v;
-}
-
-void setAdditiveColor(vec3 v)
-{
- vary_AdditiveColor = v;
-}
-
-void setAtmosAttenuation(vec3 v)
-{
- vary_AtmosAttenuation = v;
-}
-
-void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
-
- vec3 P = inPositionEye;
- setPositionEye(P);
-
- vec3 tmpLightnorm = lightnorm.xyz;
-
- vec3 Pn = normalize(P);
- float Plen = length(P);
-
- vec4 temp1 = vec4(0);
- vec3 temp2 = vec3(0);
- vec4 blue_weight;
- vec4 haze_weight;
- vec4 sunlight = sunlight_color;
- vec4 light_atten;
-
- //sunlight attenuation effect (hue and brightness) due to atmosphere
- //this is used later for sunlight modulation at various altitudes
- light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
- //I had thought blue_density and haze_density should have equal weighting,
- //but attenuation due to haze_density tends to seem too strong
-
- temp1 = blue_density + vec4(haze_density);
- blue_weight = blue_density / temp1;
- haze_weight = vec4(haze_density) / temp1;
-
- //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
- temp2.y = max(0.0, tmpLightnorm.y);
- temp2.y = 1. / temp2.y;
- sunlight *= exp( - light_atten * temp2.y);
-
- // main atmospheric scattering line integral
- temp2.z = Plen * density_multiplier;
-
- // Transparency (-> temp1)
- // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
- // compiler gets confused.
- temp1 = exp(-temp1 * temp2.z * distance_multiplier);
-
- //final atmosphere attenuation factor
- setAtmosAttenuation(temp1.rgb);
-
- //compute haze glow
- //(can use temp2.x as temp because we haven't used it yet)
- temp2.x = dot(Pn, tmpLightnorm.xyz);
- temp2.x = 1. - temp2.x;
- //temp2.x is 0 at the sun and increases away from sun
- temp2.x = max(temp2.x, .03); //was glow.y
- //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- temp2.x *= glow.x;
- //higher glow.x gives dimmer glow (because next step is 1 / "angle")
- temp2.x = pow(temp2.x, glow.z);
- //glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- //add "minimum anti-solar illumination"
- temp2.x += .25;
-
- //increase ambient when there are more clouds
- vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
-
- /* decrease value and saturation (that in HSV, not HSL) for occluded areas
- * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
- * // The following line of code performs the equivalent of:
- * float ambAlpha = tmpAmbient.a;
- * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
- * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
- * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
- */
- tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
-
- //haze color
- setAdditiveColor(
- vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
- + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
- + tmpAmbient)));
-
- //brightness of surface both sunlight and ambient
- setSunlitColor(vec3(sunlight * .5));
- setAmblitColor(vec3(tmpAmbient * .25));
- setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
-}
-
-vec3 atmosLighting(vec3 light)
-{
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor();
- return (2.0 * light);
-}
-
-vec3 atmosTransport(vec3 light) {
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor() * 2.0;
- return light;
-}
-vec3 atmosGetDiffuseSunlightColor()
-{
- return getSunlitColor();
-}
-
-vec3 scaleDownLight(vec3 light)
-{
- return (light / vec3(scene_light_strength, scene_light_strength, scene_light_strength));
-}
-
-vec3 scaleUpLight(vec3 light)
-{
- return (light * vec3(scene_light_strength, scene_light_strength, scene_light_strength));
-}
-
-vec3 atmosAmbient(vec3 light)
-{
- return getAmblitColor() + (light * vec3(0.5f, 0.5f, 0.5f));
-}
-
-vec3 atmosAffectDirectionalLight(float lightIntensity)
-{
- return getSunlitColor() * vec3(lightIntensity, lightIntensity, lightIntensity);
-}
-
-vec3 scaleSoftClip(vec3 light)
-{
- //soft clip effect:
- vec3 zeroes = vec3(0.0f, 0.0f, 0.0f);
- vec3 ones = vec3(1.0f, 1.0f, 1.0f);
-
- light = ones - clamp(light, zeroes, ones);
- light = ones - pow(light, gamma.xxx);
-
- return light;
-}
-
-vec3 fullbrightAtmosTransport(vec3 light) {
- float brightness = dot(light.rgb, vec3(0.33333));
-
- return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
-}
-
-vec3 fullbrightScaleSoftClip(vec3 light)
-{
- //soft clip effect:
- return light;
+ // no spec for alpha shader...
+ }
+ col = max(col, vec3(0));
+ return col;
}
void main()
{
- // Fix impostors failing to render with alpha correctly
- //vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
- //frag *= screen_res;
- //
+ vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
+ frag *= screen_res;
+
+ vec4 pos = vec4(vary_position, 1.0);
+ vec3 norm = vary_norm;
- vec4 pos = vec4(vary_position, 1.0);
-
- float shadow = 1.0;
+ float shadow = 1.0f;
-#if HAS_SHADOW
- vec4 spos = pos;
-
- if (spos.z > -shadow_clip.w)
- {
- shadow = 0.0;
+#ifdef HAS_SHADOW
+ shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, frag);
+#endif
- vec4 lpos;
-
- vec4 near_split = shadow_clip*-0.75;
- vec4 far_split = shadow_clip*-1.25;
- vec4 transition_domain = near_split-far_split;
- float weight = 0.0;
-
- if (spos.z < near_split.z)
- {
- lpos = shadow_matrix[3]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap3, lpos)*w;
- weight += w;
- shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
- }
-
- if (spos.z < near_split.y && spos.z > far_split.z)
- {
- lpos = shadow_matrix[2]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
- w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap2, lpos)*w;
- weight += w;
- }
-
- if (spos.z < near_split.x && spos.z > far_split.y)
- {
- lpos = shadow_matrix[1]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
- w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
- shadow += pcfShadow(shadowMap1, lpos)*w;
- weight += w;
- }
-
- if (spos.z > far_split.x)
- {
- lpos = shadow_matrix[0]*spos;
-
- float w = 1.0;
- w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
-
- shadow += pcfShadow(shadowMap0, lpos)*w;
- weight += w;
- }
-
-
- shadow /= weight;
- }
- else
- {
- shadow = 1.0;
- }
+#ifdef USE_DIFFUSE_TEX
+ vec4 diffuse_tap = texture2D(diffuseMap,vary_texcoord0.xy);
#endif
#ifdef USE_INDEXED_TEX
- vec4 diff = diffuseLookup(vary_texcoord0.xy);
-#else
- vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
+ vec4 diffuse_tap = diffuseLookup(vary_texcoord0.xy);
#endif
-// Fix impostors failing to render with alpha correctly
-//#ifdef FOR_IMPOSTOR
-// vec4 color;
-// color.rgb = diff.rgb;
-// color.a = 1.0;
-//
+ vec4 diffuse_srgb = diffuse_tap;
+ vec4 diffuse_linear = vec4(srgb_to_linear(diffuse_srgb.rgb), diffuse_srgb.a);
+
+#ifdef FOR_IMPOSTOR
+ vec4 color;
+ color.rgb = diffuse_srgb.rgb;
+ color.a = 1.0;
+
+ float final_alpha = diffuse_srgb.a * vertex_color.a;
+ diffuse_srgb.rgb *= vertex_color.rgb;
+ diffuse_linear.rgb = srgb_to_linear(diffuse_srgb.rgb);
+
+ // Insure we don't pollute depth with invis pixels in impostor rendering
+ //
+ if (final_alpha < 0.01)
+ {
+ discard;
+ }
+#else
+
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir: moon_dir;
+
+ float final_alpha = diffuse_linear.a;
#ifdef USE_VERTEX_COLOR
- float final_alpha = diff.a * vertex_color.a;
- diff.rgb *= vertex_color.rgb;
-#else
- float final_alpha = diff.a;
+ final_alpha *= vertex_color.a;
+ diffuse_srgb.rgb *= vertex_color.rgb;
+ diffuse_linear.rgb = srgb_to_linear(diffuse_srgb.rgb);
#endif
-// Fix impostors failing to render with alpha correctly
-#ifdef FOR_IMPOSTOR
- vec4 color = vec4(diff.rgb,final_alpha);
-//
-
- // Insure we don't pollute depth with invis pixels in impostor rendering
- //
- if (final_alpha < 0.01)
- {
- discard;
- }
-#else
-// Fix impostors failing to render with alpha correctly
-//#ifdef USE_VERTEX_COLOR
-// float final_alpha = diff.a * vertex_color.a;
-// diff.rgb *= vertex_color.rgb;
-//#else
-// float final_alpha = diff.a;
-//#endif
-//
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
- vec4 gamma_diff = diff;
- diff.rgb = srgb_to_linear(diff.rgb);
+ calcAtmosphericVars(pos.xyz, light_dir, 1.0, sunlit, amblit, additive, atten, false);
- vec3 norm = vary_norm;
-
- calcAtmospherics(pos.xyz, 1.0);
-
- vec2 abnormal = encode_normal(norm.xyz);
- norm.xyz = decode_normal(abnormal.xy);
-
- float da = dot(norm.xyz, sun_dir.xyz);
+ vec2 abnormal = encode_normal(norm.xyz);
+ float da = dot(norm.xyz, light_dir.xyz);
+ da = clamp(da, -1.0, 1.0);
+ da = pow(da, 1.0/1.3);
+
float final_da = da;
- final_da = min(final_da, shadow);
- final_da = max(final_da, 0.0f);
- final_da = min(final_da, 1.0f);
- final_da = pow(final_da, 1.0/1.3);
+ final_da = clamp(final_da, 0.0f, 1.0f);
- vec4 color = vec4(0,0,0,0);
+ vec4 color = vec4(0.0);
- color.rgb = atmosAmbient(color.rgb);
- color.a = final_alpha;
+ color.a = final_alpha;
- float ambient = abs(da);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0-ambient);
+ float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
+ ambient *= 0.5;
+ ambient *= ambient;
+ ambient = (1.0 - ambient);
- color.rgb *= ambient;
- color.rgb += atmosAffectDirectionalLight(final_da);
- color.rgb *= gamma_diff.rgb;
+ vec3 sun_contrib = min(final_da, shadow) * sunlit;
- //color.rgb = mix(diff.rgb, color.rgb, final_alpha);
-
- color.rgb = atmosLighting(color.rgb);
- color.rgb = scaleSoftClip(color.rgb);
+#if !defined(AMBIENT_KILL)
+ color.rgb = amblit;
+ color.rgb *= ambient;
+#endif
- vec4 light = vec4(0,0,0,0);
+vec3 post_ambient = color.rgb;
- color.rgb = srgb_to_linear(color.rgb);
-
- #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diff.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z);
+#if !defined(SUNLIGHT_KILL)
+ color.rgb += sun_contrib;
+#endif
- LIGHT_LOOP(1)
- LIGHT_LOOP(2)
- LIGHT_LOOP(3)
- LIGHT_LOOP(4)
- LIGHT_LOOP(5)
- LIGHT_LOOP(6)
- LIGHT_LOOP(7)
+vec3 post_sunlight = color.rgb;
- // keep it linear
- //
- color.rgb += light.rgb;
+ color.rgb *= diffuse_srgb.rgb;
- // straight to display gamma, we're post-deferred
- //
- color.rgb = linear_to_srgb(color.rgb);
+vec3 post_diffuse = color.rgb;
+
+ color.rgb = atmosFragLighting(color.rgb, additive, atten);
+
+vec3 post_atmo = color.rgb;
+
+ vec4 light = vec4(0,0,0,0);
+
+ color.rgb = scaleSoftClipFrag(color.rgb);
+
+ //convert to linear before applying local lights
+ color.rgb = srgb_to_linear(color.rgb);
+
+ #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diffuse_linear.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, 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)
+
+ // sum local light contrib in linear colorspace
+#if !defined(LOCAL_LIGHT_KILL)
+ color.rgb += light.rgb;
+#endif
+ // back to sRGB as we're going directly to the final RT post-deferred gamma correction
+ color.rgb = linear_to_srgb(color.rgb);
+
+//color.rgb = amblit;
+//color.rgb = vec3(ambient);
+//color.rgb = sunlit;
+//color.rgb = vec3(final_da);
+//color.rgb = post_ambient;
+//color.rgb = post_sunlight;
+//color.rgb = sun_contrib;
+//color.rgb = diffuse_srgb.rgb;
+//color.rgb = post_diffuse;
+//color.rgb = post_atmo;
#ifdef WATER_FOG
- color = applyWaterFogDeferred(pos.xyz, color);
-#endif
+ color = applyWaterFogView(pos.xyz, color);
+#endif // WATER_FOG
#endif
-
- frag_color = color;
+
+ frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl
new file mode 100644
index 0000000000..23adbded5e
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl
@@ -0,0 +1,123 @@
+/**
+ * @file class1/deferred/aoUtil.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform sampler2D noiseMap;
+uniform sampler2DRect normalMap;
+uniform sampler2DRect depthMap;
+
+uniform float ssao_radius;
+uniform float ssao_max_radius;
+uniform float ssao_factor;
+uniform float ssao_factor_inv;
+
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+
+vec2 getScreenCoordinateAo(vec2 screenpos)
+{
+ vec2 sc = screenpos.xy * 2.0;
+ if (screen_res.x > 0 && screen_res.y > 0)
+ {
+ sc /= screen_res;
+ }
+ return sc - vec2(1.0, 1.0);
+}
+
+float getDepthAo(vec2 pos_screen)
+{
+ float depth = texture2DRect(depthMap, pos_screen).r;
+ return depth;
+}
+
+vec4 getPositionAo(vec2 pos_screen)
+{
+ float depth = getDepthAo(pos_screen);
+ vec2 sc = getScreenCoordinateAo(pos_screen);
+ vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
+ vec4 pos = inv_proj * ndc;
+ pos /= pos.w;
+ pos.w = 1.0;
+ return pos;
+}
+
+vec2 getKern(int i)
+{
+ vec2 kern[8];
+ // exponentially (^2) distant occlusion samples spread around origin
+ kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
+ kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
+ kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
+ kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
+ kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
+ kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
+ kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
+ kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
+
+ return kern[i];
+}
+
+//calculate decreases in ambient lighting when crowded out (SSAO)
+float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen)
+{
+ float ret = 1.0;
+ vec3 pos_world = pos.xyz;
+ vec2 noise_reflect = texture2D(noiseMap, pos_screen.xy/128.0).xy;
+
+ float angle_hidden = 0.0;
+ float points = 0;
+
+ float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
+
+ // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?)
+ for (int i = 0; i < 8; i++)
+ {
+ vec2 samppos_screen = pos_screen + scale * reflect(getKern(i), noise_reflect);
+ vec3 samppos_world = getPositionAo(samppos_screen).xyz;
+
+ vec3 diff = pos_world - samppos_world;
+ float dist2 = dot(diff, diff);
+
+ // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
+ // --> solid angle shrinking by the square of distance
+ //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
+ //(k should vary inversely with # of samples, but this is taken care of later)
+
+ float funky_val = (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) ? 1.0 : 0.0;
+ angle_hidden = angle_hidden + funky_val * min(1.0/dist2, ssao_factor_inv);
+
+ // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
+ float diffz_val = (diff.z > -1.0) ? 1.0 : 0.0;
+ points = points + diffz_val;
+ }
+
+ angle_hidden = min(ssao_factor*angle_hidden/points, 1.0);
+
+ float points_val = (points > 0.0) ? 1.0 : 0.0;
+ ret = (1.0 - (points_val * angle_hidden));
+
+ ret = max(ret, 0.0);
+ return min(ret, 1.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl
index 22c9a4d14e..8e9a5fcd41 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl
@@ -22,6 +22,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
index 3f90600ace..0fa0edfd67 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
@@ -41,7 +41,7 @@ void main()
vec4 p = projection_matrix * vec4(pos, 1.0);
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
p.z = max(p.z, -p.w+0.01);
gl_Position = p;
#else
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl
index c8ddefac26..bbdc8fdd1c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl
@@ -29,17 +29,13 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
mat4 getSkinnedTransform();
void calcAtmospherics(vec3 inPositionEye);
float calcDirectionalLight(vec3 n, vec3 l);
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
-vec3 atmosAmbient(vec3 light);
+vec3 atmosAmbient();
vec3 atmosAffectDirectionalLight(float lightIntensity);
-vec3 scaleDownLight(vec3 light);
-vec3 scaleUpLight(vec3 light);
VARYING vec3 vary_position;
VARYING vec3 vary_ambient;
@@ -59,41 +55,7 @@ uniform vec3 light_direction[8];
uniform vec3 light_attenuation[8];
uniform vec3 light_diffuse[8];
-float calcDirectionalLight(vec3 n, vec3 l)
-{
- float a = max(dot(n,l),0.0);
- return a;
-}
-
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
-{
- //get light vector
- vec3 lv = lp.xyz-v;
-
- //get distance
- float d = dot(lv,lv);
-
- float da = 0.0;
-
- if (d > 0.0 && la > 0.0 && fa > 0.0)
- {
- //normalize light vector
- lv = normalize(lv);
-
- //distance attenuation
- float dist2 = d/la;
- da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
-
- // spotlight coefficient.
- float spot = max(dot(-ln, lv), is_pointlight);
- da *= spot*spot; // GL_SPOT_EXPONENT=2
-
- //angular attenuation
- da *= max(dot(n, lv), 0.0);
- }
-
- return da;
-}
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight);
void main()
{
@@ -137,7 +99,7 @@ void main()
col.rgb = vec3(0,0,0);
// Add windlight lights
- col.rgb = atmosAmbient(vec3(0.));
+ col.rgb = atmosAmbient();
vary_ambient = col.rgb*color.rgb;
vary_directional = color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), 0.0));
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
index 662c762bca..60d83cc623 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -36,11 +38,7 @@ uniform float minimum_alpha;
VARYING vec3 vary_normal;
VARYING vec2 vary_texcoord0;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec2 encode_normal(vec3 n);
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
index b809b73973..50020a50d8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
@@ -22,7 +22,9 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
@@ -31,7 +33,7 @@ out vec4 frag_color;
uniform sampler2D diffuseMap;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
@@ -39,7 +41,7 @@ void main()
{
frag_color = vec4(1,1,1,1);
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
index bde1ad4e9f..91b25613e0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
@@ -31,7 +31,7 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
@@ -53,7 +53,7 @@ void main()
norm = normalize(norm);
pos = projection_matrix * pos;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
post_pos = pos;
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl
index d3b1c87084..61c69f16b9 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl
@@ -68,7 +68,7 @@ void main()
norm = normalize(norm);
// Fix avatar cloth failing to work in deferred
-#if AVATAR_CLOTH
+#ifdef AVATAR_CLOTH
//wind
vec4 windEffect;
windEffect = vec4(dot(norm, gWindDir.xyz));
diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
index cbd8d2ebfc..596d0274af 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
@@ -33,7 +33,6 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
-uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
uniform sampler2DRect lightMap;
@@ -45,100 +44,68 @@ uniform float kern_scale;
VARYING vec2 vary_fragcoord;
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec2 fenc = enc*4-2;
- float f = dot(fenc,fenc);
- float g = sqrt(1-f/4);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1-f/2;
- return n;
-}
+vec4 getPosition(vec2 pos_screen);
+vec3 getNorm(vec2 pos_screen);
void main()
{
vec2 tc = vary_fragcoord.xy;
- vec3 norm = texture2DRect(normalMap, tc).xyz;
- norm = decode_normal(norm.xy); // unpack norm
+ vec3 norm = getNorm(tc);
+ vec3 pos = getPosition(tc).xyz;
+ vec4 ccol = texture2DRect(lightMap, tc).rgba;
+
+ vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy);
+ dlt /= max(-pos.z*dist_factor, 1.0);
+
+ vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
+ vec4 col = defined_weight.xyxx * ccol;
- vec3 pos = getPosition(tc).xyz;
- vec4 ccol = texture2DRect(lightMap, tc).rgba;
-
- vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy);
- dlt /= max(-pos.z*dist_factor, 1.0);
-
- vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
- vec4 col = defined_weight.xyxx * ccol;
+ // relax tolerance according to distance to avoid speckling artifacts, as angles and distances are a lot more abrupt within a small screen area at larger distances
+ float pointplanedist_tolerance_pow2 = pos.z*pos.z*0.00005;
- // relax tolerance according to distance to avoid speckling artifacts, as angles and distances are a lot more abrupt within a small screen area at larger distances
- float pointplanedist_tolerance_pow2 = pos.z*pos.z*0.00005;
+ // perturb sampling origin slightly in screen-space to hide edge-ghosting artifacts where smoothing radius is quite large
+ float tc_mod = 0.5*(tc.x + tc.y); // mod(tc.x+tc.y,2)
+ tc_mod -= floor(tc_mod);
+ tc_mod *= 2.0;
+ tc += ( (tc_mod - 0.5) * kern[1].z * dlt * 0.5 );
- // perturb sampling origin slightly in screen-space to hide edge-ghosting artifacts where smoothing radius is quite large
- float tc_mod = 0.5*(tc.x + tc.y); // mod(tc.x+tc.y,2)
- tc_mod -= floor(tc_mod);
- tc_mod *= 2.0;
- tc += ( (tc_mod - 0.5) * kern[1].z * dlt * 0.5 );
+ for (int i = 1; i < 4; i++)
+ {
+ vec2 samptc = tc + kern[i].z*dlt;
+ vec3 samppos = getPosition(samptc).xyz;
- for (int i = 1; i < 4; i++)
- {
- vec2 samptc = tc + kern[i].z*dlt;
- vec3 samppos = getPosition(samptc).xyz;
+ float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
+
+ if (d*d <= pointplanedist_tolerance_pow2)
+ {
+ col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
+ defined_weight += kern[i].xy;
+ }
+ }
- float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
-
- if (d*d <= pointplanedist_tolerance_pow2)
- {
- col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
- defined_weight += kern[i].xy;
- }
- }
+ for (int i = 1; i < 4; i++)
+ {
+ vec2 samptc = tc - kern[i].z*dlt;
+ vec3 samppos = getPosition(samptc).xyz;
- for (int i = 1; i < 4; i++)
- {
- vec2 samptc = tc - kern[i].z*dlt;
- vec3 samppos = getPosition(samptc).xyz;
+ float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
+
+ if (d*d <= pointplanedist_tolerance_pow2)
+ {
+ col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
+ defined_weight += kern[i].xy;
+ }
+ }
- float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
-
- if (d*d <= pointplanedist_tolerance_pow2)
- {
- col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
- defined_weight += kern[i].xy;
- }
- }
-
- col /= defined_weight.xyxx;
- col.y *= col.y;
-
- frag_color = col;
+ col /= defined_weight.xyxx;
+ col.y *= col.y;
+
+ frag_color = col;
#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.
- vec3 dummy1 = kern[0];
- vec3 dummy2 = kern[3];
+ // 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.
+ vec3 dummy1 = kern[0];
+ vec3 dummy2 = kern[3];
#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
index 58fb01d200..b5677a07ee 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
@@ -22,6 +22,8 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
+
+/*[EXTRA_CODE_HERE]*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
@@ -40,11 +42,7 @@ VARYING vec3 vary_mat2;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec2 encode_normal(vec3 n);
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl
new file mode 100644
index 0000000000..0157d166e0
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl
@@ -0,0 +1,127 @@
+/**
+ * @file class3/deferred/cloudsF.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$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2D diffuseMap;
+
+VARYING vec4 pos;
+VARYING float target_pos_x;
+VARYING float vary_CloudDensity;
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
+VARYING vec2 vary_texcoord3;
+
+uniform sampler2D cloud_noise_texture;
+uniform sampler2D cloud_noise_texture_next;
+uniform float blend_factor;
+uniform vec4 cloud_pos_density1;
+uniform vec4 cloud_pos_density2;
+uniform vec4 sunlight_color;
+uniform vec4 cloud_color;
+uniform float cloud_shadow;
+uniform float cloud_scale;
+uniform float cloud_variance;
+uniform vec3 camPosLocal;
+uniform vec3 sun_dir;
+uniform float sun_size;
+uniform float far_z;
+
+#if !defined(DEPTH_CLAMP)
+VARYING vec4 post_pos;
+#endif
+
+vec4 cloudNoise(vec2 uv)
+{
+ vec4 a = texture2D(cloud_noise_texture, uv);
+ vec4 b = texture2D(cloud_noise_texture_next, uv);
+ vec4 cloud_noise_sample = mix(a, b, blend_factor);
+ return normalize(cloud_noise_sample);
+}
+
+void main()
+{
+ // Set variables
+ vec2 uv1 = vary_texcoord0.xy;
+ vec2 uv2 = vary_texcoord1.xy;
+ vec2 uv3 = vary_texcoord2.xy;
+ float cloudDensity = 2.0 * (cloud_shadow - 0.25);
+
+ if (cloud_scale >= 0.0001)
+ {
+ vec2 uv4 = vary_texcoord3.xy;
+
+ vec2 disturbance = vec2(cloudNoise(uv1 / 8.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
+ vec2 disturbance2 = vec2(cloudNoise((uv1 + uv3) / 4.0f).x, cloudNoise((uv4 + uv2) / 8.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
+
+ // Offset texture coords
+ uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density
+ uv2 += cloud_pos_density1.xy; //large texture, self shadow
+ uv3 += cloud_pos_density2.xy; //small texture, visible density
+ uv4 += cloud_pos_density2.xy; //small texture, self shadow
+
+ float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0 + disturbance2.x + disturbance2.y) * 4.0);
+
+ cloudDensity *= 1.0 - (density_variance * density_variance);
+
+ // Compute alpha1, the main cloud opacity
+ float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
+ alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
+
+ // And smooth
+ alpha1 = 1. - alpha1 * alpha1;
+ alpha1 = 1. - alpha1 * alpha1;
+
+ if (alpha1 < 0.001f)
+ {
+ discard;
+ }
+
+ // Compute alpha2, for self shadowing effect
+ // (1 - alpha2) will later be used as percentage of incoming sunlight
+ float alpha2 = (cloudNoise(uv2).x - 0.5);
+ alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
+
+ // And smooth
+ alpha2 = 1. - alpha2;
+ alpha2 = 1. - alpha2 * alpha2;
+
+ frag_color = vec4(alpha1, alpha1, alpha1, 1);
+ }
+ else
+ {
+ frag_color = vec4(1);
+ }
+
+#if !defined(DEPTH_CLAMP)
+ gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
+#endif
+
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudShadowV.glsl
new file mode 100644
index 0000000000..effb070f93
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudShadowV.glsl
@@ -0,0 +1,63 @@
+/**
+ * @file cloudShadowV.glsl
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
+uniform float shadow_target_width;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+#if !defined(DEPTH_CLAMP)
+VARYING float pos_zd2;
+#endif
+
+VARYING vec4 pos;
+VARYING float target_pos_x;
+VARYING vec2 vary_texcoord0;
+VARYING vec4 vertex_color;
+
+void passTextureIndex();
+
+void main()
+{
+ //transform vertex
+ vec4 pre_pos = vec4(position.xyz, 1.0);
+ pos = modelview_projection_matrix * pre_pos;
+ target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
+
+#if !defined(DEPTH_CLAMP)
+ pos_zd2 = pos.z * 0.5;
+ gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+#else
+ gl_Position = pos;
+#endif
+
+ passTextureIndex();
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+ vertex_color = diffuse_color;
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
index 1d8ca04ccd..ae1ac5de7f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
@@ -1,5 +1,5 @@
/**
- * @file WLCloudsF.glsl
+ * @file class1\deferred\cloudsF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -22,7 +22,7 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+/*[EXTRA_CODE_HERE]*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
@@ -39,69 +39,93 @@ VARYING vec4 vary_CloudColorAmbient;
VARYING float vary_CloudDensity;
uniform sampler2D cloud_noise_texture;
+uniform sampler2D cloud_noise_texture_next;
+uniform float blend_factor;
uniform vec4 cloud_pos_density1;
uniform vec4 cloud_pos_density2;
-uniform vec4 gamma;
+uniform float cloud_scale;
+uniform float cloud_variance;
VARYING vec2 vary_texcoord0;
VARYING vec2 vary_texcoord1;
VARYING vec2 vary_texcoord2;
VARYING vec2 vary_texcoord3;
+VARYING float altitude_blend_factor;
/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light) {
- //soft clip effect:
- light = 1. - clamp(light, vec3(0.), vec3(1.));
- light = 1. - pow(light, gamma.xxx);
+vec3 scaleSoftClip(vec3 light);
- return light;
+vec4 cloudNoise(vec2 uv)
+{
+ vec4 a = texture2D(cloud_noise_texture, uv);
+ vec4 b = texture2D(cloud_noise_texture_next, uv);
+ vec4 cloud_noise_sample = mix(a, b, blend_factor);
+ return cloud_noise_sample;
}
void main()
{
- // Set variables
- vec2 uv1 = vary_texcoord0.xy;
- vec2 uv2 = vary_texcoord1.xy;
+ // Set variables
+ vec2 uv1 = vary_texcoord0.xy;
+ vec2 uv2 = vary_texcoord1.xy;
- vec4 cloudColorSun = vary_CloudColorSun;
- vec4 cloudColorAmbient = vary_CloudColorAmbient;
- float cloudDensity = vary_CloudDensity;
- vec2 uv3 = vary_texcoord2.xy;
- vec2 uv4 = vary_texcoord3.xy;
+ vec4 cloudColorSun = vary_CloudColorSun;
+ vec4 cloudColorAmbient = vary_CloudColorAmbient;
+ float cloudDensity = vary_CloudDensity;
+ vec2 uv3 = vary_texcoord2.xy;
+ vec2 uv4 = vary_texcoord3.xy;
- // Offset texture coords
- uv1 += cloud_pos_density1.xy; //large texture, visible density
- uv2 += cloud_pos_density1.xy; //large texture, self shadow
- uv3 += cloud_pos_density2.xy; //small texture, visible density
- uv4 += cloud_pos_density2.xy; //small texture, self shadow
+ if (cloud_scale < 0.001)
+ {
+ discard;
+ }
+ vec2 disturbance = vec2(cloudNoise(uv1 / 8.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
+ vec2 disturbance2 = vec2(cloudNoise((uv1 + uv3) / 4.0f).x, cloudNoise((uv4 + uv2) / 8.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
- // Compute alpha1, the main cloud opacity
- float alpha1 = (texture2D(cloud_noise_texture, uv1).x - 0.5) + (texture2D(cloud_noise_texture, uv3).x - 0.5) * cloud_pos_density2.z;
- alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10. * cloud_pos_density1.z, 1.);
+ // Offset texture coords
+ uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density
+ uv2 += cloud_pos_density1.xy; //large texture, self shadow
+ uv3 += cloud_pos_density2.xy; //small texture, visible density
+ uv4 += cloud_pos_density2.xy; //small texture, self shadow
- // And smooth
- alpha1 = 1. - alpha1 * alpha1;
- alpha1 = 1. - alpha1 * alpha1;
+ float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0 + disturbance2.x + disturbance2.y) * 4.0);
+ cloudDensity *= 1.0 - (density_variance * density_variance);
- // Compute alpha2, for self shadowing effect
- // (1 - alpha2) will later be used as percentage of incoming sunlight
- float alpha2 = (texture2D(cloud_noise_texture, uv2).x - 0.5);
- alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
+ // Compute alpha1, the main cloud opacity
- // And smooth
- alpha2 = 1. - alpha2;
- alpha2 = 1. - alpha2 * alpha2;
+ float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
+ alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
- // Combine
- vec4 color;
- color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
- color *= 2.;
+ // And smooth
+ alpha1 = 1. - alpha1 * alpha1;
+ alpha1 = 1. - alpha1 * alpha1;
- /// Gamma correct for WL (soft clip effect).
- frag_data[0] = vec4(scaleSoftClip(color.rgb), alpha1);
- frag_data[1] = vec4(0.0,0.0,0.0,0.0);
- frag_data[2] = vec4(0,0,1,0);
+ alpha1 *= altitude_blend_factor;
+ alpha1 = clamp(alpha1, 0.0, 1.0);
+
+ // Compute alpha2, for self shadowing effect
+ // (1 - alpha2) will later be used as percentage of incoming sunlight
+ float alpha2 = (cloudNoise(uv2).x - 0.5);
+ alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
+
+ // And smooth
+ alpha2 = 1. - alpha2;
+ alpha2 = 1. - alpha2 * alpha2;
+
+ // Combine
+ vec4 color;
+ color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
+ color.rgb= max(vec3(0), color.rgb);
+ color.rgb *= 2.0;
+ color.rgb = scaleSoftClip(color.rgb);
+
+ /// Gamma correct for WL (soft clip effect).
+ frag_data[0] = vec4(color.rgb, alpha1);
+ frag_data[1] = vec4(0.0,0.0,0.0,0.0);
+ frag_data[2] = vec4(0,0,0,1);
+
+ gl_FragDepth = 0.99995f;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
index 17f425475c..caa4fe1f65 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
@@ -41,13 +41,16 @@ 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 ambient;
+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;
@@ -58,22 +61,40 @@ uniform float density_multiplier;
uniform float max_y;
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\lllegacyatmospherics.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.)
{
@@ -81,6 +102,7 @@ void main()
}
else
{
+ altitude_blend_factor = 0; // SL-11589 Fix clouds drooping below horizon
P *= (-32000. / P.y);
}
@@ -93,16 +115,18 @@ void main()
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)) * (density_multiplier * max_y);
+ light_atten = (blue_density + vec4(haze_density * 0.25)) * (dens_mul * max_y);
// Calculate relative weights
- temp1 = blue_density + haze_density;
+ temp1 = abs(blue_density) + vec4(abs(haze_density));
blue_weight = blue_density / temp1;
haze_weight = haze_density / temp1;
@@ -112,7 +136,7 @@ void main()
sunlight *= exp( - light_atten * temp2.y);
// Distance
- temp2.z = Plen * density_multiplier;
+ temp2.z = Plen * dens_mul;
// Transparency (-> temp1)
// ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati
@@ -131,11 +155,13 @@ void main()
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;
+ vec4 tmpAmbient = ambient_color;
tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
@@ -147,8 +173,6 @@ void main()
);
// CLOUDS
-
- sunlight = sunlight_color;
temp2.y = max(0., lightnorm.y * 2.);
temp2.y = 1. / temp2.y;
sunlight *= exp( - light_atten * temp2.y);
@@ -167,19 +191,6 @@ void main()
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;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
index fef1c5a584..079d8458c9 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
@@ -50,15 +50,6 @@ uniform vec2 screen_res;
VARYING vec2 vary_fragcoord;
-float getDepth(vec2 pos_screen)
-{
- float z = texture2DRect(depthMap, pos_screen.xy).r;
- z = z*2.0-1.0;
- vec4 ndc = vec4(0.0, 0.0, z, 1.0);
- vec4 p = inv_proj*ndc;
- return p.z/p.w;
-}
-
float calc_cof(float depth)
{
float sc = (depth-focal_distance)/-depth*blur_constant;
@@ -77,8 +68,12 @@ float calc_cof(float depth)
void main()
{
vec2 tc = vary_fragcoord.xy;
-
- float depth = getDepth(tc);
+
+ float z = texture2DRect(depthMap, tc).r;
+ z = z*2.0-1.0;
+ vec4 ndc = vec4(0.0, 0.0, z, 1.0);
+ vec4 p = inv_proj*ndc;
+ float depth = p.z/p.w;
vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
new file mode 100644
index 0000000000..e27bbce094
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
@@ -0,0 +1,79 @@
+/**
+ * @file class1/deferred/deferredUtil.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform sampler2DRect normalMap;
+uniform sampler2DRect depthMap;
+
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+
+vec2 getScreenCoordinate(vec2 screenpos)
+{
+ vec2 sc = screenpos.xy * 2.0;
+ if (screen_res.x > 0 && screen_res.y > 0)
+ {
+ sc /= screen_res;
+ }
+ return sc - vec2(1.0, 1.0);
+}
+
+vec3 getNorm(vec2 screenpos)
+{
+ vec2 enc = texture2DRect(normalMap, screenpos.xy).xy;
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+
+float getDepth(vec2 pos_screen)
+{
+ float depth = texture2DRect(depthMap, pos_screen).r;
+ return depth;
+}
+
+vec4 getPosition(vec2 pos_screen)
+{
+ float depth = getDepth(pos_screen);
+ vec2 sc = getScreenCoordinate(pos_screen);
+ vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
+ vec4 pos = inv_proj * ndc;
+ pos /= pos.w;
+ pos.w = 1.0;
+ return pos;
+}
+
+vec4 getPositionWithDepth(vec2 pos_screen, float depth)
+{
+ vec2 sc = getScreenCoordinate(pos_screen);
+ vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
+ vec4 pos = inv_proj * ndc;
+ pos /= pos.w;
+ pos.w = 1.0;
+ return pos;
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
index 7930b5d18b..b328ee9483 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -37,11 +39,7 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec2 encode_normal(vec3 n);
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
index 8525e13333..fc5c86b4d6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -36,11 +38,7 @@ uniform float minimum_alpha;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec2 encode_normal(vec3 n);
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
index 37d70a2412..1bb8eb8bd0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
@@ -23,6 +23,7 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
@@ -37,11 +38,7 @@ uniform sampler2D diffuseMap;
VARYING vec3 vary_normal;
VARYING vec2 vary_texcoord0;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec2 encode_normal(vec3 n);
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
index 6befb1bd8b..8319e61242 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
@@ -22,6 +22,8 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
+
+/*[EXTRA_CODE_HERE]*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
@@ -35,11 +37,7 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec2 encode_normal(vec3 n);
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
index adc361d7a2..ccd1df84f9 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -33,17 +35,13 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
+vec2 encode_normal(vec3 n);
+vec3 linear_to_srgb(vec3 c);
void main()
{
vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
-
+
vec3 spec;
spec.rgb = vec3(vertex_color.a);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
index 0ffca8515c..f0522850de 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
@@ -44,7 +44,6 @@ void main()
float shadow = 1.0;
vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
- color.rgb = pow(color.rgb, vec3(2.2));
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl
index 115b04797f..5e4f08b017 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl
@@ -34,11 +34,8 @@ ATTRIBUTE vec2 texcoord0;
void calcAtmospherics(vec3 inPositionEye);
-vec3 atmosAmbient(vec3 light);
+vec3 atmosAmbient();
vec3 atmosAffectDirectionalLight(float lightIntensity);
-vec3 scaleDownLight(vec3 light);
-vec3 scaleUpLight(vec3 light);
-
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
index 6c43704ba1..57420158ca 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
@@ -1,5 +1,5 @@
/**
- * @file fullbrightF.glsl
+ * @file deferred/fullbrightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -33,7 +33,7 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
-#if !HAS_DIFFUSE_LOOKUP
+#if !defined(HAS_DIFFUSE_LOOKUP)
uniform sampler2D diffuseMap;
#endif
@@ -41,114 +41,22 @@ VARYING vec3 vary_position;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-// Fix fullbright fog failing
+#ifdef WATER_FOG
+vec4 applyWaterFogView(vec3 pos, vec4 color);
+#endif
+
+vec3 srgb_to_linear(vec3 cs);
+vec3 linear_to_srgb(vec3 cl);
vec3 fullbrightAtmosTransport(vec3 light);
vec3 fullbrightScaleSoftClip(vec3 light);
-//
-
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
-#endif
-
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
-
-// Fix fullbright fog failing
-//vec3 fullbrightAtmosTransportDeferred(vec3 light)
-//{
-// return light;
-//}
-
-//vec3 fullbrightScaleSoftClipDeferred(vec3 light)
-//{
-// //soft clip effect:
-// return light;
-//}
-//
#ifdef HAS_ALPHA_MASK
uniform float minimum_alpha;
#endif
-#ifdef WATER_FOG
-uniform vec4 waterPlane;
-uniform vec4 waterFogColor;
-uniform float waterFogDensity;
-uniform float waterFogKS;
-
-vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
-{
- //normalize view vector
- vec3 view = normalize(pos);
- float es = -(dot(view, waterPlane.xyz));
-
- //find intersection point with water plane and eye vector
-
- //get eye depth
- float e0 = max(-waterPlane.w, 0.0);
-
- vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
-
- //get object depth
- float depth = length(pos - int_v);
-
- //get "thickness" of water
- float l = max(depth, 0.1);
-
- float kd = waterFogDensity;
- float ks = waterFogKS;
- vec4 kc = waterFogColor;
-
- float F = 0.98;
-
- float t1 = -kd * pow(F, ks * e0);
- float t2 = kd + ks * es;
- float t3 = pow(F, t2*l) - 1.0;
-
- float L = min(t1/t2*t3, 1.0);
-
- float D = pow(0.98, l*kd);
-
- color.rgb = color.rgb * D + kc.rgb * L;
- color.a = kc.a + color.a;
-
- return color;
-}
-#endif
-
void main()
{
-#if HAS_DIFFUSE_LOOKUP
+#ifdef HAS_DIFFUSE_LOOKUP
vec4 color = diffuseLookup(vary_texcoord0.xy);
#else
vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
@@ -164,32 +72,17 @@ void main()
#endif
color.rgb *= vertex_color.rgb;
- // Fix fullbright fog failing
- //color.rgb = srgb_to_linear(color.rgb);
- //color.rgb = fullbrightAtmosTransportDeferred(color.rgb);
- //color.rgb = fullbrightScaleSoftClipDeferred(color.rgb);
-
- //color.rgb = linear_to_srgb(color.rgb);
- color.rgb = fullbrightAtmosTransport(color.rgb);
- color.rgb = fullbrightScaleSoftClip(color.rgb);
- //
#ifdef WATER_FOG
vec3 pos = vary_position;
- // Fix fullbright fog failing
- //vec4 fogged = applyWaterFogDeferred(pos, vec4(color.rgb, final_alpha));
- //color.rgb = fogged.rgb;
- //color.a = fogged.a;
- color = applyWaterFogDeferred(pos, vec4(color.rgb, final_alpha));
- //
+ vec4 fogged = applyWaterFogView(pos, vec4(color.rgb, final_alpha));
+ color.rgb = fogged.rgb;
+ color.a = fogged.a;
#else
- color.a = final_alpha;
+ color.a = final_alpha;
#endif
- // Fix fullbright fog failing
- //frag_color.rgb = color.rgb;
- //frag_color.a = color.a;
- frag_color = color;
- //
+ frag_color.rgb = color.rgb;
+ frag_color.a = color.a;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
index b0db9876d3..bd0ad3bce8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
@@ -23,7 +23,7 @@
* $/LicenseInfo$
*/
-
+/*[EXTRA_CODE_HERE]*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
@@ -31,41 +31,57 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
-#ifndef diffuseLookup
+#ifndef HAS_DIFFUSE_LOOKUP
uniform sampler2D diffuseMap;
#endif
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_texcoord1;
+VARYING vec4 vary_position;
uniform samplerCube environmentMap;
vec3 fullbrightShinyAtmosTransport(vec3 light);
+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 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
+
+
void main()
{
-#if HAS_DIFFUSE_LOOKUP
+#ifdef HAS_DIFFUSE_LOOKUP
vec4 color = diffuseLookup(vary_texcoord0.xy);
#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;
+
+ calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten, false);
vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
- color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
+ float env_intensity = vertex_color.a;
+ color.rgb = mix(color.rgb, envColor.rgb, env_intensity);
- color.rgb = pow(color.rgb,vec3(2.2f,2.2f,2.2f));
+ //color.rgb = srgb_to_linear(color.rgb);
- color.rgb = fullbrightShinyAtmosTransport(color.rgb);
+ color.rgb = fullbrightAtmosTransportFrag(color.rgb, additive, atten);
color.rgb = fullbrightScaleSoftClip(color.rgb);
color.a = 1.0;
- color.rgb = pow(color.rgb, vec3(1.0/2.2));
+ //color.rgb = linear_to_srgb(color.rgb);
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
index 34bd8d445a..8f6eb79668 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
@@ -45,7 +45,7 @@ ATTRIBUTE vec2 texcoord0;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_texcoord1;
-
+VARYING vec4 vary_position;
void main()
{
@@ -53,7 +53,7 @@ void main()
vec4 vert = vec4(position.xyz,1.0);
passTextureIndex();
vec4 pos = (modelview_matrix * vert);
- gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+ vary_position = gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
vec3 norm = normalize(normal_matrix * normal);
vec3 ref = reflect(pos.xyz, -norm);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
index 8e899e3e0f..bdf3546aa5 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
@@ -35,10 +35,8 @@ ATTRIBUTE vec2 texcoord0;
void calcAtmospherics(vec3 inPositionEye);
-vec3 atmosAmbient(vec3 light);
+vec3 atmosAmbient();
vec3 atmosAffectDirectionalLight(float lightIntensity);
-vec3 scaleDownLight(vec3 light);
-vec3 scaleUpLight(vec3 light);
#ifdef WATER_FOG
VARYING vec3 vary_position;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
index f8fdde43f9..d29e8a9423 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -38,42 +40,6 @@ uniform sampler2D specularMap;
VARYING vec2 vary_texcoord0;
-vec3 decode_normal (vec2 enc)
-{
- vec2 fenc = enc*4-2;
- float f = dot(fenc,fenc);
- float g = sqrt(1-f/4);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1-f/2;
- return n;
-}
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
-
void main()
{
vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
@@ -86,8 +52,6 @@ void main()
vec4 norm = texture2D(normalMap, vary_texcoord0.xy);
vec4 spec = texture2D(specularMap, vary_texcoord0.xy);
- col.rgb = linear_to_srgb(col.rgb);
-
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = spec;
frag_data[2] = vec4(norm.xy,0,0);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/indirect.glsl b/indra/newview/app_settings/shaders/class1/deferred/indirect.glsl
new file mode 100644
index 0000000000..49bfa660f8
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/indirect.glsl
@@ -0,0 +1,30 @@
+/**
+ * @file class1/deferred/indirect.glsl
+ *
+ * $LicenseInfo:firstyear=2018&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$
+ */
+
+vec3 getIndirect(vec3 ambient, vec3 norm, vec3 pos, vec2 pos_screen)
+{
+ return ambient;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
index dcf474824d..be1003a7e0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
@@ -22,8 +22,8 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-uniform sampler2DRect diffuseMap;
+
+/*[EXTRA_CODE_HERE]*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
@@ -31,6 +31,7 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
+uniform sampler2DRect diffuseMap;
VARYING vec2 vary_fragcoord;
void main()
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
index 07d28ed4cd..0afd1a9672 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -1,788 +1,439 @@
-/**
- * @file materialF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#define DIFFUSE_ALPHA_MODE_IGNORE 0
-#define DIFFUSE_ALPHA_MODE_BLEND 1
-#define DIFFUSE_ALPHA_MODE_MASK 2
-#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
-
-uniform float emissive_brightness;
-uniform float display_gamma;
-
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
-#endif
-
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-#if HAS_SUN_SHADOW
-
-uniform sampler2DShadow shadowMap0;
-uniform sampler2DShadow shadowMap1;
-uniform sampler2DShadow shadowMap2;
-uniform sampler2DShadow shadowMap3;
-
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-uniform vec2 shadow_res;
-uniform float shadow_bias;
-
-float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
-{
- stc.xyz /= stc.w;
- stc.z += shadow_bias;
-
- stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
-
- float cs = shadow2D(shadowMap, stc.xyz).x;
- float shadow = cs;
-
- shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
-
- return shadow*0.2;
-}
-
-#endif
-
-uniform samplerCube environmentMap;
-uniform sampler2D lightFunc;
-
-// Inputs
-uniform vec4 morphFactor;
-uniform vec3 camPosLocal;
-//uniform vec4 camPosWorld;
-uniform vec4 gamma;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 ambient;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
-uniform float haze_horizon;
-uniform float haze_density;
-uniform float cloud_shadow;
-uniform float density_multiplier;
-uniform float distance_multiplier;
-uniform float max_y;
-uniform vec4 glow;
-uniform float scene_light_strength;
-uniform mat3 env_mat;
-uniform mat3 ssao_effect_mat;
-
-uniform vec3 sun_dir;
-VARYING vec2 vary_fragcoord;
-
-VARYING vec3 vary_position;
-
-vec3 vary_PositionEye;
-
-vec3 vary_SunlitColor;
-vec3 vary_AmblitColor;
-vec3 vary_AdditiveColor;
-vec3 vary_AtmosAttenuation;
-
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-uniform vec4 light_position[8];
-uniform vec3 light_direction[8];
-uniform vec3 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-
-#ifdef WATER_FOG
-uniform vec4 waterPlane;
-uniform vec4 waterFogColor;
-uniform float waterFogDensity;
-uniform float waterFogKS;
-
-vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
-{
- //normalize view vector
- vec3 view = normalize(pos);
- float es = -(dot(view, waterPlane.xyz));
-
- //find intersection point with water plane and eye vector
-
- //get eye depth
- float e0 = max(-waterPlane.w, 0.0);
-
- vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
-
- //get object depth
- float depth = length(pos - int_v);
-
- //get "thickness" of water
- float l = max(depth, 0.1);
-
- float kd = waterFogDensity;
- float ks = waterFogKS;
- vec4 kc = waterFogColor;
-
- float F = 0.98;
-
- float t1 = -kd * pow(F, ks * e0);
- float t2 = kd + ks * es;
- float t3 = pow(F, t2*l) - 1.0;
-
- float L = min(t1/t2*t3, 1.0);
-
- float D = pow(0.98, l*kd);
-
- color.rgb = color.rgb * D + kc.rgb * L;
- color.a = kc.a + color.a;
-
- return color;
-}
-#endif
-
-vec3 calcDirectionalLight(vec3 n, vec3 l)
-{
- float a = max(dot(n,l),0.0);
- return vec3(a,a,a);
-}
-
-
-vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare)
-{
- //get light vector
- vec3 lv = lp.xyz-v;
-
- //get distance
- float d = length(lv);
-
- float da = 1.0;
-
- vec3 col = vec3(0,0,0);
-
- if (d > 0.0 && la > 0.0 && fa > 0.0)
- {
- //normalize light vector
- lv = normalize(lv);
-
- //distance attenuation
- float dist = d/la;
- float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0;
-
- // spotlight coefficient.
- float spot = max(dot(-ln, lv), is_pointlight);
- da *= spot*spot; // GL_SPOT_EXPONENT=2
-
- //angular attenuation
- da *= max(dot(n, lv), 0.0);
-
- float lit = max(da * dist_atten, 0.0);
-
- col = light_col*lit*diffuse;
-
- if (spec.a > 0.0)
- {
- //vec3 ref = dot(pos+lv, norm);
- vec3 h = normalize(lv+npos);
- float nh = dot(n, h);
- float nv = dot(n, npos);
- float vh = dot(npos, h);
- float sa = nh;
- float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
-
- float gtdenom = 2 * nh;
- float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-
- if (nh > 0.0)
- {
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
- vec3 speccol = lit*scol*light_col.rgb*spec.rgb;
- col += speccol;
-
- float cur_glare = max(speccol.r, speccol.g);
- cur_glare = max(cur_glare, speccol.b);
- glare = max(glare, speccol.r);
- glare += max(cur_glare, 0.0);
- //col += spec.rgb;
- }
- }
- }
-
- return max(col, vec3(0.0,0.0,0.0));
-
-}
-
-vec4 getPosition_d(vec2 pos_screen, float depth)
-{
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
-
-#ifndef WATER_FOG
-vec3 getPositionEye()
-{
- return vary_PositionEye;
-}
-#endif
-
-vec3 getSunlitColor()
-{
- return vary_SunlitColor;
-}
-vec3 getAmblitColor()
-{
- return vary_AmblitColor;
-}
-vec3 getAdditiveColor()
-{
- return vary_AdditiveColor;
-}
-vec3 getAtmosAttenuation()
-{
- return vary_AtmosAttenuation;
-}
-
-void setPositionEye(vec3 v)
-{
- vary_PositionEye = v;
-}
-
-void setSunlitColor(vec3 v)
-{
- vary_SunlitColor = v;
-}
-
-void setAmblitColor(vec3 v)
-{
- vary_AmblitColor = v;
-}
-
-void setAdditiveColor(vec3 v)
-{
- vary_AdditiveColor = v;
-}
-
-void setAtmosAttenuation(vec3 v)
-{
- vary_AtmosAttenuation = v;
-}
-
-void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
-
- vec3 P = inPositionEye;
- setPositionEye(P);
-
- vec3 tmpLightnorm = lightnorm.xyz;
-
- vec3 Pn = normalize(P);
- float Plen = length(P);
-
- vec4 temp1 = vec4(0);
- vec3 temp2 = vec3(0);
- vec4 blue_weight;
- vec4 haze_weight;
- vec4 sunlight = sunlight_color;
- vec4 light_atten;
-
- //sunlight attenuation effect (hue and brightness) due to atmosphere
- //this is used later for sunlight modulation at various altitudes
- light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
- //I had thought blue_density and haze_density should have equal weighting,
- //but attenuation due to haze_density tends to seem too strong
-
- temp1 = blue_density + vec4(haze_density);
- blue_weight = blue_density / temp1;
- haze_weight = vec4(haze_density) / temp1;
-
- //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
- temp2.y = max(0.0, tmpLightnorm.y);
- temp2.y = 1. / temp2.y;
- sunlight *= exp( - light_atten * temp2.y);
-
- // main atmospheric scattering line integral
- temp2.z = Plen * density_multiplier;
-
- // Transparency (-> temp1)
- // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
- // compiler gets confused.
- temp1 = exp(-temp1 * temp2.z * distance_multiplier);
-
- //final atmosphere attenuation factor
- setAtmosAttenuation(temp1.rgb);
-
- //compute haze glow
- //(can use temp2.x as temp because we haven't used it yet)
- temp2.x = dot(Pn, tmpLightnorm.xyz);
- temp2.x = 1. - temp2.x;
- //temp2.x is 0 at the sun and increases away from sun
- temp2.x = max(temp2.x, .03); //was glow.y
- //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- temp2.x *= glow.x;
- //higher glow.x gives dimmer glow (because next step is 1 / "angle")
- temp2.x = pow(temp2.x, glow.z);
- //glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- //add "minimum anti-solar illumination"
- temp2.x += .25;
-
- //increase ambient when there are more clouds
- vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
-
- /* decrease value and saturation (that in HSV, not HSL) for occluded areas
- * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
- * // The following line of code performs the equivalent of:
- * float ambAlpha = tmpAmbient.a;
- * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
- * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
- * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
- */
- tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
-
- //haze color
- setAdditiveColor(
- vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
- + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
- + tmpAmbient)));
-
- //brightness of surface both sunlight and ambient
- setSunlitColor(vec3(sunlight * .5));
- setAmblitColor(vec3(tmpAmbient * .25));
- setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
-}
-
-vec3 atmosLighting(vec3 light)
-{
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor();
- return (2.0 * light);
-}
-
-vec3 atmosTransport(vec3 light) {
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor() * 2.0;
- return light;
-}
-vec3 atmosGetDiffuseSunlightColor()
-{
- return getSunlitColor();
-}
-
-vec3 scaleDownLight(vec3 light)
-{
- return (light / vec3(scene_light_strength, scene_light_strength, scene_light_strength));
-}
-
-vec3 scaleUpLight(vec3 light)
-{
- return (light * vec3(scene_light_strength, scene_light_strength, scene_light_strength));
-}
-
-vec3 atmosAmbient(vec3 light)
-{
- return getAmblitColor() + (light * vec3(0.5f, 0.5f, 0.5f));
-}
-
-vec3 atmosAffectDirectionalLight(float lightIntensity)
-{
- return getSunlitColor() * vec3(lightIntensity, lightIntensity, lightIntensity);
-}
-
-vec3 scaleSoftClip(vec3 light)
-{
- //soft clip effect:
- vec3 zeroes = vec3(0.0f, 0.0f, 0.0f);
- vec3 ones = vec3(1.0f, 1.0f, 1.0f);
-
- light = ones - clamp(light, zeroes, ones);
- light = ones - pow(light, gamma.xxx);
-
- return light;
-}
-
-vec3 fullbrightAtmosTransport(vec3 light) {
- float brightness = dot(light.rgb, vec3(0.33333));
-
- return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
-}
-
-vec3 fullbrightScaleSoftClip(vec3 light)
-{
- //soft clip effect:
- return light;
-}
-
-#else
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-#endif
-
-uniform sampler2D diffuseMap;
-
-#if HAS_NORMAL_MAP
-uniform sampler2D bumpMap;
-#endif
-
-#if HAS_SPECULAR_MAP
-uniform sampler2D specularMap;
-
-VARYING vec2 vary_texcoord2;
-#endif
-
-uniform float env_intensity;
-uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
-uniform float minimum_alpha;
-#endif
-
-#if HAS_NORMAL_MAP
-VARYING vec3 vary_mat0;
-VARYING vec3 vary_mat1;
-VARYING vec3 vary_mat2;
-VARYING vec2 vary_texcoord1;
-#else
-VARYING vec3 vary_normal;
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec2 fenc = enc*4-2;
- float f = dot(fenc,fenc);
- float g = sqrt(1-f/4);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1-f/2;
- return n;
-}
-
-void main()
-{
- vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
- diffcol.rgb *= vertex_color.rgb;
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
- if (diffcol.a < minimum_alpha)
- {
- discard;
- }
-#endif
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
- vec3 gamma_diff = diffcol.rgb;
- diffcol.rgb = srgb_to_linear(diffcol.rgb);
-#endif
-
-#if HAS_SPECULAR_MAP
- vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
- spec.rgb *= specular_color.rgb;
-#else
- vec4 spec = vec4(specular_color.rgb, 1.0);
-#endif
-
-#if HAS_NORMAL_MAP
- vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
-
- norm.xyz = norm.xyz * 2 - 1;
-
- vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
- dot(norm.xyz,vary_mat1),
- dot(norm.xyz,vary_mat2));
-#else
- vec4 norm = vec4(0,0,0,1.0);
- vec3 tnorm = vary_normal;
-#endif
-
- norm.xyz = tnorm;
- norm.xyz = normalize(norm.xyz);
-
- vec2 abnormal = encode_normal(norm.xyz);
- norm.xyz = decode_normal(abnormal.xy);
-
- vec4 final_color = diffcol;
-
-#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
- final_color.a = emissive_brightness;
-#else
- final_color.a = max(final_color.a, emissive_brightness);
-#endif
-
- vec4 final_specular = spec;
-#if HAS_SPECULAR_MAP
- vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0);
- final_specular.a = specular_color.a * norm.a;
-#else
- vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0);
- final_specular.a = specular_color.a;
-#endif
-
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
- //forward rendering, output just lit RGBA
- vec3 pos = vary_position;
-
-#if HAS_SUN_SHADOW
- float shadow = 0.0;
-
- vec4 spos = vec4(pos,1.0);
-
- if (spos.z > -shadow_clip.w)
- {
- vec4 lpos;
-
- vec4 near_split = shadow_clip*-0.75;
- vec4 far_split = shadow_clip*-1.25;
- vec4 transition_domain = near_split-far_split;
- float weight = 0.0;
-
- if (spos.z < near_split.z)
- {
- lpos = shadow_matrix[3]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap3, lpos)*w;
- weight += w;
- shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
- }
-
- if (spos.z < near_split.y && spos.z > far_split.z)
- {
- lpos = shadow_matrix[2]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
- w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap2, lpos)*w;
- weight += w;
- }
-
- if (spos.z < near_split.x && spos.z > far_split.y)
- {
- lpos = shadow_matrix[1]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
- w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
- shadow += pcfShadow(shadowMap1, lpos)*w;
- weight += w;
- }
-
- if (spos.z > far_split.x)
- {
- lpos = shadow_matrix[0]*spos;
-
- float w = 1.0;
- w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
-
- shadow += pcfShadow(shadowMap0, lpos)*w;
- weight += w;
- }
-
-
- shadow /= weight;
- }
- else
- {
- shadow = 1.0;
- }
-#else
- float shadow = 1.0;
-#endif
-
- spec = final_specular;
- vec4 diffuse = final_color;
- float envIntensity = final_normal.z;
-
- vec3 col = vec3(0.0f,0.0f,0.0f);
-
- float bloom = 0.0;
- calcAtmospherics(pos.xyz, 1.0);
-
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-
- float da =dot(norm.xyz, sun_dir.xyz);
-
- float final_da = da;
- final_da = min(final_da, shadow);
- //final_da = max(final_da, diffuse.a);
- final_da = max(final_da, 0.0f);
- final_da = min(final_da, 1.0f);
- final_da = pow(final_da, 1.0/1.3);
-
- col.rgb = atmosAmbient(col);
-
- float ambient = min(abs(da), 1.0);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0-ambient);
-
- col.rgb *= ambient;
-
- col.rgb = col.rgb + atmosAffectDirectionalLight(final_da);
-
- col.rgb *= gamma_diff.rgb;
-
-
- float glare = 0.0;
-
- if (spec.a > 0.0) // specular reflection
- {
- // the old infinite-sky shiny reflection
- //
-
- float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = vary_SunlitColor*shadow*(texture2D(lightFunc, vec2(sa, spec.a)).r);
-
- // add the two types of shiny together
- vec3 spec_contrib = dumbshiny * spec.rgb;
- bloom = dot(spec_contrib, spec_contrib) / 6;
-
- glare = max(spec_contrib.r, spec_contrib.g);
- glare = max(glare, spec_contrib.b);
-
- col += spec_contrib;
- }
-
-
- col = mix(col.rgb, diffcol.rgb, diffuse.a);
-
- if (envIntensity > 0.0)
- {
- //add environmentmap
- vec3 env_vec = env_mat * refnormpersp;
-
- vec3 refcol = textureCube(environmentMap, env_vec).rgb;
-
- col = mix(col.rgb, refcol,
- envIntensity);
-
- float cur_glare = max(refcol.r, refcol.g);
- cur_glare = max(cur_glare, refcol.b);
- cur_glare *= envIntensity*4.0;
- glare += cur_glare;
- }
-
- //col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
- //col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
-
- col = atmosLighting(col);
- col = scaleSoftClip(col);
-
- //convert to linear space before adding local lights
- col = srgb_to_linear(col);
-
- 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_LOOP(1)
- LIGHT_LOOP(2)
- LIGHT_LOOP(3)
- LIGHT_LOOP(4)
- LIGHT_LOOP(5)
- LIGHT_LOOP(6)
- LIGHT_LOOP(7)
-
- col.rgb += light.rgb;
-
- glare = min(glare, 1.0);
- float al = max(diffcol.a,glare)*vertex_color.a;
-
- //convert to gamma space for display on screen
- col.rgb = linear_to_srgb(col.rgb);
-
-#ifdef WATER_FOG
- vec4 temp = applyWaterFogDeferred(pos, vec4(col.rgb, al));
- col.rgb = temp.rgb;
- al = temp.a;
-#endif
-
- frag_color.rgb = col.rgb;
- frag_color.a = al;
-
-#else
- frag_data[0] = final_color;
- frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
- frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity.
-#endif
-}
-
+/**
+* @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
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
index 393d1e69da..7e29ada205 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
@@ -28,7 +28,7 @@
#define DIFFUSE_ALPHA_MODE_MASK 2
#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
-#if HAS_SKIN
+#ifdef HAS_SKIN
uniform mat4 modelview_matrix;
uniform mat4 projection_matrix;
mat4 getObjectSkinnedTransform();
@@ -39,7 +39,7 @@ uniform mat4 modelview_projection_matrix;
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
-#if !HAS_SKIN
+#if !defined(HAS_SKIN)
uniform mat4 modelview_matrix;
#endif
@@ -55,7 +55,7 @@ ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
-#if HAS_NORMAL_MAP
+#ifdef HAS_NORMAL_MAP
ATTRIBUTE vec4 tangent;
ATTRIBUTE vec2 texcoord1;
@@ -68,7 +68,7 @@ VARYING vec2 vary_texcoord1;
VARYING vec3 vary_normal;
#endif
-#if HAS_SPECULAR_MAP
+#ifdef HAS_SPECULAR_MAP
ATTRIBUTE vec2 texcoord2;
VARYING vec2 vary_texcoord2;
#endif
@@ -78,7 +78,7 @@ VARYING vec2 vary_texcoord0;
void main()
{
-#if HAS_SKIN
+#ifdef HAS_SKIN
mat4 mat = getObjectSkinnedTransform();
mat = modelview_matrix * mat;
@@ -99,17 +99,17 @@ void main()
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-#if HAS_NORMAL_MAP
+#ifdef HAS_NORMAL_MAP
vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
#endif
-#if HAS_SPECULAR_MAP
+#ifdef HAS_SPECULAR_MAP
vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy;
#endif
-#if HAS_SKIN
+#ifdef HAS_SKIN
vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
-#if HAS_NORMAL_MAP
+#ifdef HAS_NORMAL_MAP
vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz);
vec3 b = cross(n, t)*tangent.w;
@@ -121,7 +121,7 @@ vary_normal = n;
#endif //HAS_NORMAL_MAP
#else //HAS_SKIN
vec3 n = normalize(normal_matrix * normal);
-#if HAS_NORMAL_MAP
+#ifdef HAS_NORMAL_MAP
vec3 t = normalize(normal_matrix * tangent.xyz);
vec3 b = cross(n,t)*tangent.w;
//vec3 t = cross(b,n) * binormal.w;
@@ -137,7 +137,7 @@ vary_normal = n;
vertex_color = diffuse_color;
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
-#if !HAS_SKIN
+#if !defined(HAS_SKIN)
vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
#endif
#endif
diff --git a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
new file mode 100644
index 0000000000..80f232948a
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
@@ -0,0 +1,74 @@
+/**
+ * @file moonF.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$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+
+uniform vec4 color;
+uniform vec4 sunlight_color;
+uniform vec4 moonlight_color;
+uniform vec3 lumWeights;
+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);
+
+ // 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);
+
+ vec4 light_color = max(sunlight_color, moonlight_color);
+ float mix = 1.0 - dot(normalize(light_color.rgb), luma_weights);
+
+ vec3 exp = vec3(1.0 - mix * moon_brightness) * 2.0 - 1.0;
+ c.rgb = pow(c.rgb, exp);
+
+ //c.rgb *= moonlight_color.rgb;
+
+ frag_data[0] = vec4(c.rgb, c.a);
+ frag_data[1] = vec4(0.0);
+ frag_data[2] = vec4(0.0f);
+
+ gl_FragDepth = 0.999985f;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl b/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl
new file mode 100644
index 0000000000..e1bac4f248
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl
@@ -0,0 +1,49 @@
+/**
+ * @file moonV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+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 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 9974f8f31b..0d1cc81786 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
@@ -36,7 +36,6 @@ out vec4 frag_color;
uniform sampler2DRect depthMap;
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
-uniform sampler2DRect normalMap;
uniform samplerCube environmentMap;
uniform sampler2D noiseMap;
uniform sampler2D lightFunc;
@@ -57,38 +56,17 @@ uniform float far_z;
uniform mat4 inv_proj;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec2 fenc = enc*4-2;
- float f = dot(fenc,fenc);
- float g = sqrt(1-f/4);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1-f/2;
- return n;
-}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
+vec4 getPosition(vec2 pos_screen);
+vec3 getNorm(vec2 pos_screen);
+vec3 srgb_to_linear(vec3 c);
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)
@@ -96,14 +74,13 @@ void main()
discard;
}
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = decode_normal(norm.xy); // unpack norm
- norm = normalize(norm);
+ 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 out_col = vec3(0,0,0);
vec3 npos = normalize(-pos);
// As of OSX 10.6.7 ATI Apple's crash when using a variable size loop
@@ -123,6 +100,9 @@ void main()
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;
@@ -159,7 +139,7 @@ void main()
}
}
}
-
+#endif
frag_color.rgb = out_col;
frag_color.a = 0.0;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
index 3a3e871ade..9bba45bc4e 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
@@ -30,14 +30,14 @@
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_shader_texture_lod : enable
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
-/*[EXTRA_CODE_HERE]*/
-
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect depthMap;
@@ -71,60 +71,8 @@ VARYING vec4 vary_fragcoord;
uniform vec2 screen_res;
uniform mat4 inv_proj;
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec2 fenc = enc*4-2;
- float f = dot(fenc,fenc);
- float g = sqrt(1-f/4);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1-f/2;
- return n;
-}
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
-#endif
-
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
-
+vec3 getNorm(vec2 pos_screen);
+vec3 srgb_to_linear(vec3 c);
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
@@ -178,22 +126,15 @@ vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
return ret;
}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
+vec4 getPosition(vec2 pos_screen);
void main()
{
+ vec3 col = vec3(0,0,0);
+
+#if defined(LOCAL_LIGHT_KILL)
+ discard;
+#else
vec4 frag = vary_fragcoord;
frag.xyz /= frag.w;
frag.xyz = frag.xyz*0.5+0.5;
@@ -208,12 +149,9 @@ void main()
discard;
}
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- float envIntensity = norm.z;
+ float envIntensity = texture2DRect(normalMap, frag.xy).z;
+ vec3 norm = getNorm(frag.xy);
- norm = decode_normal(norm.xy);
-
- norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
@@ -225,25 +163,33 @@ void main()
proj_tc.xyz /= proj_tc.w;
float fa = falloff+1.0;
- float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
+ float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
dist_atten *= dist_atten;
dist_atten *= 2.0;
+
if (dist_atten <= 0.0)
{
discard;
}
+ float noise = texture2D(noiseMap, frag.xy/128.0).b;
+ dist_atten *= noise;
+
lv = proj_origin-pos.xyz;
lv = normalize(lv);
float da = dot(norm, lv);
- vec3 col = vec3(0,0,0);
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
+ // SL-12005 Projector light pops as we get closer, more objectionable than being in wrong color space.
+ // We can't switch to linear here unless we do it everywhere*
+ // *gbuffer is sRGB, convert to linear whenever sampling from it
+ diff_tex.rgb = srgb_to_linear(diff_tex.rgb);
+
vec3 dlit = vec3(0, 0, 0);
- float noise = texture2D(noiseMap, frag.xy/128.0).b;
+
if (proj_tc.z > 0.0 &&
proj_tc.x < 1.0 &&
proj_tc.y < 1.0 &&
@@ -262,7 +208,7 @@ void main()
dlit = color.rgb * plcol.rgb * plcol.a;
- lit = da * dist_atten * noise;
+ lit = da * dist_atten;
col = dlit*lit*diff_tex;
amb_da += (da*0.5)*proj_ambiance;
@@ -304,7 +250,7 @@ void main()
col += dlit*scol*spec.rgb;
//col += spec.rgb;
}
- }
+ }
if (envIntensity > 0.0)
{
@@ -334,7 +280,9 @@ void main()
}
}
}
-
+#endif
+
+ //output linear, sum of lights will be gamma corrected later
frag_color.rgb = col;
frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
index aba4a01754..d805c9ea48 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
@@ -56,103 +56,78 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
uniform vec4 viewport;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec2 fenc = enc*4-2;
- float f = dot(fenc,fenc);
- float g = sqrt(1-f/4);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1-f/2;
- return n;
-}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = (pos_screen.xy-viewport.xy)*2.0;
- sc /= viewport.zw;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
+vec3 getNorm(vec2 pos_screen);
+vec4 getPosition(vec2 pos_screen);
+vec3 srgb_to_linear(vec3 c);
void main()
{
- vec4 frag = vary_fragcoord;
- frag.xyz /= frag.w;
- frag.xyz = frag.xyz*0.5+0.5;
- frag.xy *= screen_res;
-
- vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = trans_center.xyz-pos;
- float dist = length(lv);
- dist /= size;
- if (dist > 1.0)
- {
- discard;
- }
-
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = decode_normal(norm.xy); // unpack norm
- float da = dot(norm, lv);
- if (da < 0.0)
- {
- discard;
- }
-
- norm = normalize(norm);
- lv = normalize(lv);
- da = dot(norm, lv);
-
- float noise = texture2D(noiseMap, frag.xy/128.0).b;
-
- vec3 col = texture2DRect(diffuseRect, frag.xy).rgb;
- float fa = falloff+1.0;
- float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0;
-
- float lit = da * dist_atten * noise;
+ vec4 frag = vary_fragcoord;
+ frag.xyz /= frag.w;
+ frag.xyz = frag.xyz*0.5+0.5;
+ frag.xy *= screen_res;
+
+ vec3 pos = getPosition(frag.xy).xyz;
+ vec3 lv = trans_center.xyz-pos;
+ float dist = length(lv);
+ dist /= size;
+ if (dist > 1.0)
+ {
+ discard;
+ }
+
+ vec3 norm = getNorm(frag.xy);
- col = color.rgb*lit*col;
+ float da = dot(norm, lv);
+ if (da < 0.0)
+ {
+ discard;
+ }
+
+ lv = normalize(lv);
+ da = dot(norm, lv);
+
+ float noise = texture2D(noiseMap, frag.xy/128.0).b;
+
+ vec3 col = texture2DRect(diffuseRect, frag.xy).rgb;
+ col.rgb = srgb_to_linear(col.rgb);
- vec4 spec = texture2DRect(specularRect, frag.xy);
- if (spec.a > 0.0)
- {
- lit = min(da*6.0, 1.0) * dist_atten;
+ float fa = falloff+1.0;
+ float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0;
+
+ float lit = da * dist_atten * noise;
- vec3 npos = -normalize(pos);
- vec3 h = normalize(lv+npos);
- float nh = dot(norm, h);
- float nv = dot(norm, npos);
- float vh = dot(npos, h);
- float sa = nh;
- float fres = pow(1 - dot(h, npos), 5) * 0.4+0.5;
- float gtdenom = 2 * nh;
- float gt = max(0,(min(gtdenom * nv / vh, gtdenom * da / vh)));
+ col = color.rgb*lit*col;
- if (nh > 0.0)
- {
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
- col += lit*scol*color.rgb*spec.rgb;
- }
- }
-
- if (dot(col, col) <= 0.0)
- {
- discard;
- }
-
- frag_color.rgb = col;
- frag_color.a = 0.0;
+ vec4 spec = texture2DRect(specularRect, frag.xy);
+ if (spec.a > 0.0)
+ {
+ lit = min(da*6.0, 1.0) * dist_atten;
+
+ vec3 npos = -normalize(pos);
+ vec3 h = normalize(lv+npos);
+ float nh = dot(norm, h);
+ float nv = dot(norm, npos);
+ float vh = dot(npos, h);
+ float sa = nh;
+ float fres = pow(1 - dot(h, npos), 5) * 0.4+0.5;
+ float gtdenom = 2 * nh;
+ float gt = max(0,(min(gtdenom * nv / vh, gtdenom * da / vh)));
+
+ if (nh > 0.0)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ col += lit*scol*color.rgb*spec.rgb;
+ }
+ }
+
+ if (dot(col, col) <= 0.0)
+ {
+ discard;
+ }
+//col.rgb = vec3(0);
+ frag_color.rgb = col;
+ frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
index a5625fbc16..3da8531442 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
@@ -1,5 +1,5 @@
/**
- * @file pointLightF.glsl
+ * @file pointLightV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
index 6669947d1b..cd37a34e0d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
@@ -37,33 +37,16 @@ uniform sampler2DRect diffuseRect;
uniform vec2 screen_res;
VARYING vec2 vary_fragcoord;
-
uniform float display_gamma;
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
-
+vec3 linear_to_srgb(vec3 cl);
void main()
{
- vec4 diff = texture2DRect(diffuseRect, vary_fragcoord);
- diff.rgb = linear_to_srgb(diff.rgb);
- frag_color = diff;
+ //this is the one of the rare spots where diffuseRect contains linear color values (not sRGB)
+ vec4 diff = texture2DRect(diffuseRect, vary_fragcoord);
+ //diff.rgb = pow(diff.rgb, vec3(display_gamma));
+ diff.rgb = linear_to_srgb(diff.rgb);
+ frag_color = diff;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl
index 018ced4cad..cf994d3547 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
@@ -47,18 +49,7 @@ VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 screen_res;
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).a;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
+vec4 getPosition(vec2 pos_screen);
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendF.glsl
new file mode 100644
index 0000000000..44f2a73e1f
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendF.glsl
@@ -0,0 +1,55 @@
+/**
+ * @file shadowAlphaMaskF.glsl
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2D diffuseMap;
+
+#if !defined(DEPTH_CLAMP)
+VARYING float pos_zd2;
+#endif
+
+VARYING float pos_w;
+
+VARYING float target_pos_x;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+void main()
+{
+ float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a;
+
+ frag_color = vec4(alpha, alpha, alpha, 1);
+
+#if !defined(DEPTH_CLAMP)
+ gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0);
+#endif
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendV.glsl
new file mode 100644
index 0000000000..f45c343066
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendV.glsl
@@ -0,0 +1,67 @@
+/**
+ * @file shadowAlphaMaskV.glsl
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
+uniform float shadow_target_width;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+#if !defined(DEPTH_CLAMP)
+VARYING float pos_zd2;
+#endif
+
+VARYING float pos_w;
+
+VARYING float target_pos_x;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+void passTextureIndex();
+
+void main()
+{
+ //transform vertex
+ vec4 pre_pos = vec4(position.xyz, 1.0);
+ vec4 pos = modelview_projection_matrix * pre_pos;
+ target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
+
+ pos_w = pos.w;
+
+#if !defined(DEPTH_CLAMP)
+ pos_zd2 = pos.z * 0.5;
+
+ gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+#else
+ gl_Position = pos;
+#endif
+
+ passTextureIndex();
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+ vertex_color = diffuse_color;
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
index 91a96977f0..9b8df0a5a4 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
@@ -31,19 +33,25 @@ out vec4 frag_color;
uniform sampler2D diffuseMap;
-#if !DEPTH_CLAMP
-VARYING float pos_zd2;
-#endif
-
-VARYING float pos_w;
-
+VARYING vec4 post_pos;
VARYING float target_pos_x;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+uniform float minimum_alpha;
void main()
{
- float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a;
+ float alpha = diffuseLookup(vary_texcoord0.xy).a;
+
+ // mask cutoff 0 -> no shadow SL-11051
+ if (minimum_alpha == 0)
+ {
+ discard;
+ }
+
+#if !defined(IS_FULLBRIGHT)
+ alpha *= vertex_color.a;
+#endif
if (alpha < 0.05) // treat as totally transparent
{
@@ -52,7 +60,7 @@ void main()
if (alpha < 0.88) // treat as semi-transparent
{
- if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25)
+ if (fract(0.5*floor(target_pos_x / post_pos.w )) < 0.25)
{
discard;
}
@@ -60,7 +68,7 @@ void main()
frag_color = vec4(1,1,1,1);
-#if !DEPTH_CLAMP
- gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0);
+#if !defined(DEPTH_CLAMP)
+ gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
index 11411a605c..b6a0f0b165 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
@@ -31,12 +31,7 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec2 texcoord0;
-#if !DEPTH_CLAMP
-VARYING float pos_zd2;
-#endif
-
-VARYING float pos_w;
-
+VARYING vec4 post_pos;
VARYING float target_pos_x;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
@@ -50,11 +45,9 @@ void main()
vec4 pos = modelview_projection_matrix * pre_pos;
target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
- pos_w = pos.w;
+ post_pos = pos;
-#if !DEPTH_CLAMP
- pos_zd2 = pos.z * 0.5;
-
+#if !defined(DEPTH_CLAMP)
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
#else
gl_Position = pos;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
index ef153dfc5b..0e74d2eb8a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
@@ -27,7 +27,7 @@ uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
@@ -40,7 +40,7 @@ void main()
vec3 p = position*box_size+box_center;
vec4 pos = modelview_projection_matrix*vec4(p.xyz, 1.0);
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
post_pos = pos;
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
index 3d1b182875..1ea96918bb 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
@@ -23,21 +23,21 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
-#if !DEPTH_CLAMP
VARYING vec4 post_pos;
-#endif
void main()
{
frag_color = vec4(1,1,1,1);
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl
new file mode 100644
index 0000000000..4134220306
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl
@@ -0,0 +1,221 @@
+/**
+ * @file class1/deferred/shadowUtil.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform sampler2DRect normalMap;
+uniform sampler2DRect depthMap;
+uniform sampler2DShadow shadowMap0;
+uniform sampler2DShadow shadowMap1;
+uniform sampler2DShadow shadowMap2;
+uniform sampler2DShadow shadowMap3;
+uniform sampler2DShadow shadowMap4;
+uniform sampler2DShadow shadowMap5;
+
+uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+uniform vec2 shadow_res;
+uniform vec2 proj_shadow_res;
+uniform mat4 shadow_matrix[6];
+uniform vec4 shadow_clip;
+uniform float shadow_bias;
+uniform float shadow_offset;
+uniform float spot_shadow_bias;
+uniform float spot_shadow_offset;
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+uniform int sun_up_factor;
+
+float pcfShadow(sampler2DShadow shadowMap, vec3 norm, vec4 stc, float bias_mul, vec2 pos_screen, vec3 light_dir)
+{
+ float offset = shadow_bias * bias_mul;
+ stc.xyz /= stc.w;
+ stc.z += offset * 2.0;
+ stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*shadow_res.y))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
+ float cs = shadow2D(shadowMap, stc.xyz).x;
+ float shadow = cs * 4.0;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3( 1.5/shadow_res.x, 0.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3( 0.5/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.5/shadow_res.x, -0.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-0.5/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
+ return clamp(shadow * 0.125, 0.0, 1.0);
+}
+
+float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float bias_scale, vec2 pos_screen)
+{
+ stc.xyz /= stc.w;
+ stc.z += spot_shadow_bias * bias_scale;
+ stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap
+
+ float cs = shadow2D(shadowMap, stc.xyz).x;
+ float shadow = cs;
+
+ vec2 off = 1.0/proj_shadow_res;
+ off.y *= 1.5;
+
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x;
+ return shadow*0.2;
+}
+
+float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen)
+{
+ float shadow = 0.0f;
+ vec3 light_dir = normalize((sun_up_factor == 1) ? sun_dir : moon_dir);
+
+ float dp_directional_light = max(0.0, dot(norm.xyz, light_dir));
+ dp_directional_light = clamp(dp_directional_light, 0.0, 1.0);
+
+ vec3 shadow_pos = pos.xyz;
+
+ vec3 offset = light_dir.xyz * (1.0 - dp_directional_light);
+
+ shadow_pos += offset * shadow_offset * 2.0;
+
+ vec4 spos = vec4(shadow_pos.xyz, 1.0);
+
+ if (spos.z > -shadow_clip.w)
+ {
+ vec4 lpos;
+ vec4 near_split = shadow_clip*-0.75;
+ vec4 far_split = shadow_clip*-1.25;
+ vec4 transition_domain = near_split-far_split;
+ float weight = 0.0;
+
+ if (spos.z < near_split.z)
+ {
+ lpos = shadow_matrix[3]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
+ //w = clamp(w, 0.0, 1.0);
+ float contrib = pcfShadow(shadowMap3, norm, lpos, 1.0, pos_screen, light_dir)*w;
+ //if (contrib > 0)
+ {
+ shadow += contrib;
+ weight += w;
+ }
+ shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
+ }
+
+ if (spos.z < near_split.y && spos.z > far_split.z)
+ {
+ lpos = shadow_matrix[2]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
+ w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
+ //w = clamp(w, 0.0, 1.0);
+ float contrib = pcfShadow(shadowMap2, norm, lpos, 1.0, pos_screen, light_dir)*w;
+ //if (contrib > 0)
+ {
+ shadow += contrib;
+ weight += w;
+ }
+ }
+
+ if (spos.z < near_split.x && spos.z > far_split.y)
+ {
+ lpos = shadow_matrix[1]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
+ w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
+ //w = clamp(w, 0.0, 1.0);
+ float contrib = pcfShadow(shadowMap1, norm, lpos, 1.0, pos_screen, light_dir)*w;
+ //if (contrib > 0)
+ {
+ shadow += contrib;
+ weight += w;
+ }
+ }
+
+ if (spos.z > far_split.x)
+ {
+ lpos = shadow_matrix[0]*spos;
+
+ float w = 1.0;
+ w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
+ //w = clamp(w, 0.0, 1.0);
+ float contrib = pcfShadow(shadowMap0, norm, lpos, 1.0, pos_screen, light_dir)*w;
+ //if (contrib > 0)
+ {
+ shadow += contrib;
+ weight += w;
+ }
+ }
+
+ shadow /= weight;
+ }
+ else
+ {
+ return 1.0f; // lit beyond the far split...
+ }
+ //shadow = min(dp_directional_light,shadow);
+ return shadow;
+}
+
+float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen)
+{
+ float shadow = 0.0f;
+ pos += norm * spot_shadow_offset;
+
+ vec4 spos = vec4(pos,1.0);
+ if (spos.z > -shadow_clip.w)
+ {
+ vec4 lpos;
+
+ vec4 near_split = shadow_clip*-0.75;
+ vec4 far_split = shadow_clip*-1.25;
+ vec4 transition_domain = near_split-far_split;
+ float weight = 0.0;
+
+ {
+ float w = 1.0;
+ w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
+
+ if (index == 0)
+ {
+ lpos = shadow_matrix[4]*spos;
+ shadow += pcfSpotShadow(shadowMap4, lpos, 0.8, spos.xy)*w;
+ }
+ else
+ {
+ lpos = shadow_matrix[5]*spos;
+ shadow += pcfSpotShadow(shadowMap5, lpos, 0.8, spos.xy)*w;
+ }
+ weight += w;
+ shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
+ }
+
+ shadow /= weight;
+ }
+ else
+ {
+ shadow = 1.0f;
+ }
+ return shadow;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
index cc77a4cea0..72bd0f0f34 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
@@ -27,20 +27,19 @@ uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
-#if !DEPTH_CLAMP
VARYING vec4 post_pos;
-#endif
void main()
{
//transform vertex
vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
-#if !DEPTH_CLAMP
post_pos = pos;
+#if !defined(DEPTH_CLAMP)
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
#else
gl_Position = pos;
#endif
+
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
index 22f4729e2e..331249dc33 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
@@ -1,5 +1,5 @@
/**
- * @file WLSkyF.glsl
+ * @file class1/deferred/skyF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -35,32 +37,28 @@ out vec4 frag_data[3];
VARYING vec4 vary_HazeColor;
-uniform sampler2D cloud_noise_texture;
-uniform vec4 gamma;
-
/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light) {
- //soft clip effect:
- light = 1. - clamp(light, vec3(0.), vec3(1.));
- light = 1. - pow(light, gamma.xxx);
-
- return light;
-}
+vec3 scaleSoftClip(vec3 light);
+vec3 srgb_to_linear(vec3 c);
void main()
{
- // Potential Fill-rate optimization. Add cloud calculation
- // back in and output alpha of 0 (so that alpha culling kills
- // the fragment) if the sky wouldn't show up because the clouds
- // are fully opaque.
+ // Potential Fill-rate optimization. Add cloud calculation
+ // back in and output alpha of 0 (so that alpha culling kills
+ // the fragment) if the sky wouldn't show up because the clouds
+ // are fully opaque.
- vec4 color;
- color = vary_HazeColor;
- color *= 2.;
+ vec4 color;
+ color = vary_HazeColor;
- /// Gamma correct for WL (soft clip effect).
- frag_data[0] = vec4(scaleSoftClip(color.rgb), 1.0);
- frag_data[1] = vec4(0.0,0.0,0.0,0.0);
- frag_data[2] = vec4(0.5,0.5,0.0,1.0); //1.0 in norm.w masks off fog
+ color.rgb *= 2.;
+ color.rgb = scaleSoftClip(color.rgb);
+
+ /// Gamma correct for WL (soft clip effect).
+ frag_data[0] = vec4(color.rgb, 0.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
+
+ gl_FragDepth = 0.99999f;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
index 7c02d31d43..ead754ec76 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
@@ -39,7 +39,9 @@ uniform vec3 camPosLocal;
uniform vec4 lightnorm;
uniform vec4 sunlight_color;
-uniform vec4 ambient;
+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;
@@ -47,21 +49,28 @@ uniform float haze_density;
uniform float cloud_shadow;
uniform float density_multiplier;
+uniform float distance_multiplier;
uniform float max_y;
uniform vec4 glow;
+uniform float sun_moon_glow_factor;
uniform vec4 cloud_color;
+// 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\lllegacyatmospherics.cpp
void main()
{
// World / view / projection
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ 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);
- //vec3 P = position.xyz + vec3(0,50,0);
// Set altitude
if (P.y > 0.)
@@ -75,39 +84,40 @@ void main()
// Can normalize then
vec3 Pn = normalize(P);
- float Plen = length(P);
+
+ float Plen = length(P);
// Initialize temp variables
vec4 temp1 = vec4(0.);
vec4 temp2 = vec4(0.);
vec4 blue_weight;
vec4 haze_weight;
- vec4 sunlight = sunlight_color;
+ 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)) * (density_multiplier * max_y);
+ light_atten = (blue_density + vec4(haze_density * 0.25)) * (dens_mul * max_y);
// Calculate relative weights
- temp1 = blue_density + haze_density;
+ 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);
+ 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 * density_multiplier;
+ 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);
-
+ // 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);
@@ -123,35 +133,33 @@ void main()
// Add "minimum anti-solar illumination"
temp2.x += .25;
+ vec4 color = ( blue_horizon * blue_weight * (sunlight + ambient_color)
+ + (haze_horizon * haze_weight) * (sunlight * temp2.x + ambient_color)
+ );
- // Haze color above cloud
- vary_HazeColor = ( blue_horizon * blue_weight * (sunlight + ambient)
- + (haze_horizon * haze_weight) * (sunlight * temp2.x + ambient)
- );
+ // Final atmosphere additive
+ color *= (1. - temp1);
// Increase ambient when there are more clouds
- vec4 tmpAmbient = ambient;
- tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;
+ vec4 tmpAmbient = ambient_color;
+ tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
- sunlight *= (1. - cloud_shadow);
+ 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)
);
- // Final atmosphere additive
- vary_HazeColor *= (1. - temp1);
-
// Attenuate cloud color by atmosphere
temp1 = sqrt(temp1); //less atmos opacity (more transparency) below clouds
// At horizon, blend high altitude sky color towards the darker color below the clouds
- vary_HazeColor += (additiveColorBelowCloud - vary_HazeColor) * (1. - sqrt(temp1));
-
- // won't compile on mac without this being set
- //vary_AtmosAttenuation = vec3(0.0,0.0,0.0);
+ color += (additiveColorBelowCloud - color) * (1. - sqrt(temp1));
+
+ // Haze color above cloud
+ 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 03bdb754b5..a5804220bc 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -1,5 +1,5 @@
/**
- * @file softenLightF.glsl
+ * @file class1/deferred/softenLightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -36,442 +36,161 @@ out vec4 frag_color;
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
-uniform sampler2DRect positionMap;
uniform sampler2DRect normalMap;
uniform sampler2DRect lightMap;
uniform sampler2DRect depthMap;
uniform samplerCube environmentMap;
-uniform sampler2D lightFunc;
+uniform sampler2D lightFunc;
uniform float blur_size;
uniform float blur_fidelity;
// Inputs
-uniform vec4 morphFactor;
-uniform vec3 camPosLocal;
-//uniform vec4 camPosWorld;
-uniform vec4 gamma;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 ambient;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
-uniform float haze_horizon;
-uniform float haze_density;
-uniform float cloud_shadow;
-uniform float density_multiplier;
-uniform float distance_multiplier;
-uniform float max_y;
-uniform vec4 glow;
-uniform float global_gamma;
-uniform float scene_light_strength;
uniform mat3 env_mat;
-uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+uniform int sun_up_factor;
VARYING vec2 vary_fragcoord;
-vec3 vary_PositionEye;
-
-vec3 vary_SunlitColor;
-vec3 vary_AmblitColor;
-vec3 vary_AdditiveColor;
-vec3 vary_AtmosAttenuation;
-
uniform mat4 inv_proj;
uniform vec2 screen_res;
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+vec3 getNorm(vec2 pos_screen);
+vec4 getPositionWithDepth(vec2 pos_screen, float depth);
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
-#endif
-
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
-
-
-vec3 decode_normal (vec2 enc)
-{
- vec2 fenc = enc*4-2;
- float f = dot(fenc,fenc);
- float g = sqrt(1-f/4);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1-f/2;
- return n;
-}
-
-vec4 getPosition_d(vec2 pos_screen, float depth)
-{
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
-
-vec4 getPosition(vec2 pos_screen)
-{ //get position in screen space (world units) given window coordinate and depth map
- float depth = texture2DRect(depthMap, pos_screen.xy).a;
- return getPosition_d(pos_screen, depth);
-}
-
-vec3 getPositionEye()
-{
- return vary_PositionEye;
-}
-vec3 getSunlitColor()
-{
- return vary_SunlitColor;
-}
-vec3 getAmblitColor()
-{
- return vary_AmblitColor;
-}
-vec3 getAdditiveColor()
-{
- return vary_AdditiveColor;
-}
-vec3 getAtmosAttenuation()
-{
- return vary_AtmosAttenuation;
-}
-
-void setPositionEye(vec3 v)
-{
- vary_PositionEye = v;
-}
-
-void setSunlitColor(vec3 v)
-{
- vary_SunlitColor = v;
-}
-
-void setAmblitColor(vec3 v)
-{
- vary_AmblitColor = v;
-}
-
-void setAdditiveColor(vec3 v)
-{
- vary_AdditiveColor = v;
-}
-
-void setAtmosAttenuation(vec3 v)
-{
- vary_AtmosAttenuation = v;
-}
+void 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 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
#ifdef WATER_FOG
-uniform vec4 waterPlane;
-uniform vec4 waterFogColor;
-uniform float waterFogDensity;
-uniform float waterFogKS;
-
-vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
-{
- //normalize view vector
- vec3 view = normalize(pos);
- float es = -(dot(view, waterPlane.xyz));
-
- //find intersection point with water plane and eye vector
-
- //get eye depth
- float e0 = max(-waterPlane.w, 0.0);
-
- vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
-
- //get object depth
- float depth = length(pos - int_v);
-
- //get "thickness" of water
- float l = max(depth, 0.1);
-
- float kd = waterFogDensity;
- float ks = waterFogKS;
- vec4 kc = waterFogColor;
-
- float F = 0.98;
-
- float t1 = -kd * pow(F, ks * e0);
- float t2 = kd + ks * es;
- float t3 = pow(F, t2*l) - 1.0;
-
- float L = min(t1/t2*t3, 1.0);
-
- float D = pow(0.98, l*kd);
-
- color.rgb = color.rgb * D + kc.rgb * L;
- color.a = kc.a + color.a;
-
- return color;
-}
+vec4 applyWaterFogView(vec3 pos, vec4 color);
#endif
-void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
-
- vec3 P = inPositionEye;
- setPositionEye(P);
-
- vec3 tmpLightnorm = lightnorm.xyz;
-
- vec3 Pn = normalize(P);
- float Plen = length(P);
-
- vec4 temp1 = vec4(0);
- vec3 temp2 = vec3(0);
- vec4 blue_weight;
- vec4 haze_weight;
- vec4 sunlight = sunlight_color;
- vec4 light_atten;
-
- //sunlight attenuation effect (hue and brightness) due to atmosphere
- //this is used later for sunlight modulation at various altitudes
- light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
- //I had thought blue_density and haze_density should have equal weighting,
- //but attenuation due to haze_density tends to seem too strong
-
- temp1 = blue_density + vec4(haze_density);
- blue_weight = blue_density / temp1;
- haze_weight = vec4(haze_density) / temp1;
-
- //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
- temp2.y = max(0.0, tmpLightnorm.y);
- temp2.y = 1. / temp2.y;
- sunlight *= exp( - light_atten * temp2.y);
-
- // main atmospheric scattering line integral
- temp2.z = Plen * density_multiplier;
-
- // Transparency (-> temp1)
- // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
- // compiler gets confused.
- temp1 = exp(-temp1 * temp2.z * distance_multiplier);
-
- //final atmosphere attenuation factor
- setAtmosAttenuation(temp1.rgb);
-
- //compute haze glow
- //(can use temp2.x as temp because we haven't used it yet)
- temp2.x = dot(Pn, tmpLightnorm.xyz);
- temp2.x = 1. - temp2.x;
- //temp2.x is 0 at the sun and increases away from sun
- temp2.x = max(temp2.x, .03); //was glow.y
- //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- temp2.x *= glow.x;
- //higher glow.x gives dimmer glow (because next step is 1 / "angle")
- temp2.x = pow(temp2.x, glow.z);
- //glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- //add "minimum anti-solar illumination"
- temp2.x += .25;
-
- //increase ambient when there are more clouds
- vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
-
- /* decrease value and saturation (that in HSV, not HSL) for occluded areas
- * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
- * // The following line of code performs the equivalent of:
- * float ambAlpha = tmpAmbient.a;
- * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
- * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
- * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
- */
- tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
-
- //haze color
- setAdditiveColor(
- vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
- + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
- + tmpAmbient)));
-
- //brightness of surface both sunlight and ambient
- setSunlitColor(vec3(sunlight * .5));
- setAmblitColor(vec3(tmpAmbient * .25));
- setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
-}
-
-vec3 atmosLighting(vec3 light)
-{
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor();
- return (2.0 * light);
-}
-
-vec3 atmosTransport(vec3 light) {
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor() * 2.0;
- return light;
-}
-
-vec3 fullbrightAtmosTransport(vec3 light) {
- float brightness = dot(light.rgb, vec3(0.33333));
-
- return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
-}
-
-
-
-vec3 atmosGetDiffuseSunlightColor()
-{
- return getSunlitColor();
-}
-
-vec3 scaleDownLight(vec3 light)
-{
- return (light / scene_light_strength );
-}
-
-vec3 scaleUpLight(vec3 light)
-{
- return (light * scene_light_strength);
-}
-
-vec3 atmosAmbient(vec3 light)
-{
- return getAmblitColor() + light / 2.0;
-}
-
-vec3 atmosAffectDirectionalLight(float lightIntensity)
-{
- return getSunlitColor() * lightIntensity;
-}
-
-vec3 scaleSoftClip(vec3 light)
-{
- //soft clip effect:
- light = 1. - clamp(light, vec3(0.), vec3(1.));
- light = 1. - pow(light, gamma.xxx);
-
- return light;
-}
-
-
-vec3 fullbrightScaleSoftClip(vec3 light)
-{
- //soft clip effect:
- return light;
-}
-
void main()
{
- vec2 tc = vary_fragcoord.xy;
- float depth = texture2DRect(depthMap, tc.xy).r;
- vec3 pos = getPosition_d(tc, depth).xyz;
- vec4 norm = texture2DRect(normalMap, tc);
- float envIntensity = norm.z;
- norm.xyz = decode_normal(norm.xy); // unpack norm
-
- float da = dot(norm.xyz, sun_dir.xyz);
+ 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);
+
+ vec4 diffuse = texture2DRect(diffuseRect, tc);
- float final_da = max(0.0,da);
- final_da = min(final_da, 1.0f);
- final_da = pow(final_da, 1.0/1.3);
+ //convert to gamma space
+ //diffuse.rgb = linear_to_srgb(diffuse.rgb);
- vec4 diffuse = texture2DRect(diffuseRect, tc);
+ vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
+ vec3 color = vec3(0);
+ float bloom = 0.0;
+ {
+ float ambocc = 1.0; // no AO...
- //convert to gamma space
- diffuse.rgb = linear_to_srgb(diffuse.rgb);
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+
+ calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, false);
- vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
- vec3 col;
- float bloom = 0.0;
- {
- calcAtmospherics(pos.xyz, 1.0);
-
- col = atmosAmbient(vec3(0));
- float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0-ambient);
+ color.rgb = amblit;
- col.rgb *= ambient;
+ float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
+ ambient *= 0.5;
+ ambient *= ambient;
+ ambient = (1.0 - ambient);
- col += atmosAffectDirectionalLight(final_da);
-
- col *= diffuse.rgb;
-
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+ color.rgb *= ambient;
- if (spec.a > 0.0) // specular reflection
- {
- // the old infinite-sky shiny reflection
- //
-
- float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = vary_SunlitColor*(texture2D(lightFunc, vec2(sa, spec.a)).r);
-
- // add the two types of shiny together
- vec3 spec_contrib = dumbshiny * spec.rgb;
- bloom = dot(spec_contrib, spec_contrib) / 6;
- col += spec_contrib;
- }
-
-
- col = mix(col.rgb, diffuse.rgb, diffuse.a);
-
- if (envIntensity > 0.0)
- { //add environmentmap
- vec3 env_vec = env_mat * refnormpersp;
-
-
- vec3 refcol = textureCube(environmentMap, env_vec).rgb;
+ vec3 sun_contrib = da * sunlit;
- col = mix(col.rgb, refcol,
- envIntensity);
- }
-
- if (norm.w < 0.5)
- {
- col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
- col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
- }
+ color.rgb += sun_contrib;
- #ifdef WATER_FOG
- vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom));
- col = fogged.rgb;
- bloom = fogged.a;
- #endif
+ color.rgb *= diffuse.rgb;
- col = srgb_to_linear(col);
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
- //col = vec3(1,0,1);
- //col.g = envIntensity;
- }
+ if (spec.a > 0.0) // specular reflection
+ {
- frag_color.rgb = col.rgb;
- frag_color.a = bloom;
+#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
+
+ }
+
+ 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
+
+ }
+
+// linear debuggables
+//color.rgb = vec3(final_da);
+//color.rgb = vec3(ambient);
+//color.rgb = vec3(scol);
+//color.rgb = diffuse_srgb.rgb;
+
+ // 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;
}
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl
index b59fcbe017..8891315e15 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl
@@ -1,5 +1,5 @@
/**
- * @file softenLightF.glsl
+ * @file softenLightV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -29,12 +29,17 @@ ATTRIBUTE vec3 position;
uniform vec2 screen_res;
+void setAtmosAttenuation(vec3 c);
+void setAdditiveColor(vec3 c);
+
VARYING vec2 vary_fragcoord;
void main()
{
- //transform vertex
- vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
- gl_Position = pos;
-
- vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
+ //transform vertex
+ vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ gl_Position = pos;
+ // appease OSX GLSL compiler/linker by touching all the varyings we said we would
+ setAtmosAttenuation(vec3(1));
+ setAdditiveColor(vec3(0));
+ vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
index f1aec315cc..694b19cdfb 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
@@ -70,64 +70,8 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec2 fenc = enc*4-2;
- float f = dot(fenc,fenc);
- float g = sqrt(1-f/4);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1-f/2;
- return n;
-}
-
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
-#endif
-
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
-
-vec4 correctWithGamma(vec4 col)
-{
- return vec4(srgb_to_linear(col.rgb), col.a);
-}
+vec3 getNorm(vec2 pos_screen);
+vec3 srgb_to_linear(vec3 c);
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
@@ -152,7 +96,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret = correctWithGamma(ret);
+ ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
@@ -170,7 +114,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret = correctWithGamma(ret);
+ ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = tc-vec2(0.5);
@@ -181,22 +125,15 @@ vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
return ret;
}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
+vec4 getPosition(vec2 pos_screen);
void main()
{
+ vec3 col = vec3(0,0,0);
+
+#if defined(LOCAL_LIGHT_KILL)
+ discard;
+#else
vec4 frag = vary_fragcoord;
frag.xyz /= frag.w;
frag.xyz = frag.xyz*0.5+0.5;
@@ -210,12 +147,10 @@ void main()
{
discard;
}
-
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
float envIntensity = norm.z;
- norm = decode_normal(norm.xy);
-
+ norm = getNorm(frag.xy);
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
@@ -241,13 +176,11 @@ void main()
lv = normalize(lv);
float da = dot(norm, lv);
- vec3 col = vec3(0,0,0);
-
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
+ //light shaders output linear and are gamma corrected later in postDeferredGammaCorrectF.glsl
+ diff_tex.rgb = srgb_to_linear(diff_tex.rgb);
-
+ vec4 spec = texture2DRect(specularRect, frag.xy);
float noise = texture2D(noiseMap, frag.xy/128.0).b;
vec3 dlit = vec3(0, 0, 0);
@@ -284,7 +217,6 @@ void main()
amb_da = min(amb_da, 1.0-lit);
col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a*diff_tex.rgb;
}
-
if (spec.a > 0.0)
{
@@ -311,7 +243,6 @@ void main()
}
}
-
if (envIntensity > 0.0)
{
vec3 ref = reflect(normalize(pos), norm);
@@ -340,7 +271,9 @@ void main()
}
}
}
-
+#endif
+
+ //col.r = 1.0;
frag_color.rgb = col;
frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
index 821058804c..bac79a9fdc 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -31,14 +33,35 @@ out vec4 frag_data[3];
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+VARYING vec2 screenpos;
uniform sampler2D diffuseMap;
+uniform sampler2D altDiffuseMap;
+uniform float blend_factor;
+uniform float custom_alpha;
+uniform float time;
+
+float twinkle(){
+ float d = fract(screenpos.x + screenpos.y);
+ return abs(d);
+}
void main()
{
- vec4 col = vertex_color * texture2D(diffuseMap, vary_texcoord0.xy);
-
- frag_data[0] = col;
- frag_data[1] = vec4(0,0,0,0);
- frag_data[2] = vec4(0,0,1,0);
+ vec4 col_a = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 col_b = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 col = mix(col_b, col_a, blend_factor);
+ col.rgb *= vertex_color.rgb;
+
+ float factor = smoothstep(0.0f, 0.9f, custom_alpha);
+
+ col.a = (col.a * factor) * 32.0f;
+ col.a *= twinkle();
+
+ frag_data[0] = col;
+ frag_data[1] = vec4(0.0f);
+ frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
+
+ gl_FragDepth = 0.99995f;
}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl
index 8bc5b06379..bb2a2ee72b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl
@@ -25,6 +25,7 @@
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
+uniform float time;
ATTRIBUTE vec3 position;
ATTRIBUTE vec4 diffuse_color;
@@ -32,11 +33,20 @@ ATTRIBUTE vec2 texcoord0;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+VARYING vec2 screenpos;
void main()
{
//transform vertex
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vec4 pos = modelview_projection_matrix * vec4(position, 1.0);
+
+// bias z to fix SL-9806 and get stars to depth test against clouds
+ pos.z += 0.001f;
+
+ gl_Position = pos;
+
+ float t = mod(time, 1.25f);
+ screenpos = position.xy * vec2(t, t);
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
vertex_color = diffuse_color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
new file mode 100644
index 0000000000..454af2a9bc
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
@@ -0,0 +1,68 @@
+/**
+ * @file sunDiscF.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$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+
+vec3 srgb_to_linear(vec3 c);
+vec3 fullbrightAtmosTransport(vec3 light);
+vec3 fullbrightScaleSoftClip(vec3 light);
+
+uniform sampler2D diffuseMap;
+uniform sampler2D altDiffuseMap;
+uniform float blend_factor; // interp factor between sunDisc A/B
+VARYING vec2 vary_texcoord0;
+VARYING float sun_fade;
+
+void main()
+{
+ vec4 sunDiscA = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 sunDiscB = texture2D(altDiffuseMap, vary_texcoord0.xy);
+ vec4 c = mix(sunDiscA, sunDiscB, blend_factor);
+
+ c.rgb = srgb_to_linear(c.rgb);
+ c.rgb = clamp(c.rgb, vec3(0), vec3(1));
+ c.rgb = pow(c.rgb, vec3(0.7f));
+
+ //c.rgb = fullbrightAtmosTransport(c.rgb);
+ c.rgb = fullbrightScaleSoftClip(c.rgb);
+
+ // SL-9806 stars poke through
+ //c.a *= sun_fade;
+
+ frag_data[0] = c;
+ frag_data[1] = vec4(0.0f);
+ frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
+
+ gl_FragDepth = 0.999988f;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunDiscV.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunDiscV.glsl
new file mode 100644
index 0000000000..0d117c6bc7
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunDiscV.glsl
@@ -0,0 +1,52 @@
+/**
+ * @file sunDiscV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec2 vary_texcoord0;
+VARYING float sun_fade;
+
+void calcAtmospherics(vec3 eye_pos);
+
+void main()
+{
+ //transform vertex
+ vec3 offset = vec3(0, 0, 50);
+ vec4 vert = vec4(position.xyz - offset, 1.0);
+ vec4 pos = modelview_projection_matrix*vert;
+
+ sun_fade = smoothstep(0.3, 1.0, (position.z + 50) / 512.0f);
+
+ gl_Position = pos;
+
+ calcAtmospherics(pos.xyz);
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
index 930255729b..15f141cbe5 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
@@ -35,103 +35,16 @@ out vec4 frag_color;
//class 1 -- no shadow, SSAO only
-uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
-uniform sampler2D noiseMap;
-
// Inputs
-uniform float ssao_radius;
-uniform float ssao_max_radius;
-uniform float ssao_factor;
-uniform float ssao_factor_inv;
-
VARYING vec2 vary_fragcoord;
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec2 fenc = enc*4-2;
- float f = dot(fenc,fenc);
- float g = sqrt(1-f/4);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1-f/2;
- return n;
-}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
+vec3 getNorm(vec2 pos_screen);
+vec4 getPosition(vec2 pos_screen);
//calculate decreases in ambient lighting when crowded out (SSAO)
-float calcAmbientOcclusion(vec4 pos, vec3 norm)
-{
- float ret = 1.0;
-
- vec2 kern[8];
- // exponentially (^2) distant occlusion samples spread around origin
- kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
- kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
- kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
- kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
- kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
- kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
- kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
- kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
-
- vec2 pos_screen = vary_fragcoord.xy;
- vec3 pos_world = pos.xyz;
- vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy;
-
- float angle_hidden = 0.0;
- int points = 0;
-
- float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
-
- // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations unrolling?)
- for (int i = 0; i < 8; i++)
- {
- vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect);
- vec3 samppos_world = getPosition(samppos_screen).xyz;
-
- vec3 diff = pos_world - samppos_world;
- float dist2 = dot(diff, diff);
-
- // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
- // --> solid angle shrinking by the square of distance
- //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
- //(k should vary inversely with # of samples, but this is taken care of later)
-
- angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv);
-
- // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
- points = points + int(diff.z > -1.0);
- }
-
- angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0);
-
- ret = (1.0 - (float(points != 0) * angle_hidden));
-
- return min(ret, 1.0);
-}
+float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen);
void main()
{
@@ -139,13 +52,11 @@ void main()
//try doing an unproject here
- vec4 pos = getPosition(pos_screen);
-
- vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
- norm = decode_normal(norm.xy);
-
+ vec4 pos = getPosition(pos_screen);
+ vec3 norm = getNorm(pos_screen);
+
frag_color[0] = 1.0;
- frag_color[1] = calcAmbientOcclusion(pos, norm);
+ frag_color[1] = calcAmbientOcclusion(pos, norm, pos_screen);
frag_color[2] = 1.0;
frag_color[3] = 1.0;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
index 52a429465f..6b6eed9db8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
@@ -1,5 +1,5 @@
/**
- * @file terrainF.glsl
+ * @file class1\deferred\terrainF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -35,33 +37,32 @@ uniform sampler2D detail_2;
uniform sampler2D detail_3;
uniform sampler2D alpha_ramp;
+VARYING vec3 pos;
VARYING vec3 vary_normal;
VARYING vec4 vary_texcoord0;
VARYING vec4 vary_texcoord1;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec2 encode_normal(vec3 n);
void main()
{
- /// Note: This should duplicate the blending functionality currently used for the terrain rendering.
-
- vec4 color0 = texture2D(detail_0, vary_texcoord0.xy);
- vec4 color1 = texture2D(detail_1, vary_texcoord0.xy);
- vec4 color2 = texture2D(detail_2, vary_texcoord0.xy);
- vec4 color3 = texture2D(detail_3, vary_texcoord0.xy);
+ /// Note: This should duplicate the blending functionality currently used for the terrain rendering.
+
+ vec4 color0 = texture2D(detail_0, vary_texcoord0.xy);
+ vec4 color1 = texture2D(detail_1, vary_texcoord0.xy);
+ vec4 color2 = texture2D(detail_2, vary_texcoord0.xy);
+ vec4 color3 = texture2D(detail_3, vary_texcoord0.xy);
- float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a;
- float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a;
- float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a;
- vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal );
-
- frag_data[0] = vec4(outColor.rgb, 0.0);
- frag_data[1] = vec4(0,0,0,0);
- vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
+ float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a;
+ float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a;
+ float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a;
+ vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal );
+
+ outColor.a = 0.0; // yes, downstream atmospherics
+
+ frag_data[0] = outColor;
+ frag_data[1] = vec4(0.0,0.0,0.0,-1.0);
+ vec3 nvn = normalize(vary_normal);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl
index 5effee4e4e..f42cb6ff6d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl
@@ -1,5 +1,5 @@
/**
- * @file terrainV.glsl
+ * @file class1\environment\terrainV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -33,8 +33,8 @@ ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec2 texcoord0;
ATTRIBUTE vec2 texcoord1;
+VARYING vec3 pos;
VARYING vec3 vary_normal;
-
VARYING vec4 vary_texcoord0;
VARYING vec4 vary_texcoord1;
@@ -43,31 +43,35 @@ uniform vec4 object_plane_t;
vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1)
{
- vec4 tcoord;
-
- tcoord.x = dot(vpos, tp0);
- tcoord.y = dot(vpos, tp1);
- tcoord.z = tc.z;
- tcoord.w = tc.w;
-
- tcoord = mat * tcoord;
-
- return tcoord;
+ vec4 tcoord;
+
+ tcoord.x = dot(vpos, tp0);
+ tcoord.y = dot(vpos, tp1);
+ tcoord.z = tc.z;
+ tcoord.w = tc.w;
+
+ tcoord = mat * tcoord;
+
+ return tcoord;
}
void main()
{
- //transform vertex
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
-
- vary_normal = normalize(normal_matrix * normal);
-
- // Transform and pass tex coords
- vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy;
-
- vec4 t = vec4(texcoord1,0,1);
-
- vary_texcoord0.zw = t.xy;
- vary_texcoord1.xy = t.xy-vec2(2.0, 0.0);
- vary_texcoord1.zw = t.xy-vec2(1.0, 0.0);
+ //transform vertex
+ vec4 pre_pos = vec4(position.xyz, 1.0);
+ vec4 t_pos = modelview_projection_matrix * pre_pos;
+
+ gl_Position = t_pos;
+ pos = t_pos.xyz;
+
+ vary_normal = normalize(normal_matrix * normal);
+
+ // Transform and pass tex coords
+ vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy;
+
+ vec4 t = vec4(texcoord1,0,1);
+
+ vary_texcoord0.zw = t.xy;
+ vary_texcoord1.xy = t.xy-vec2(2.0, 0.0);
+ vary_texcoord1.zw = t.xy-vec2(1.0, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
index 808750496f..89e354558a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -37,11 +39,7 @@ VARYING vec2 vary_texcoord0;
uniform float minimum_alpha;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec2 encode_normal(vec3 n);
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl
index d4d2f5f571..e34d75ba1d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
diff --git a/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl
index 4362414e14..9a5debb3c1 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -56,84 +58,7 @@ VARYING vec4 refCoord;
VARYING vec4 littleWave;
VARYING vec4 view;
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
-#endif
-
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec4 applyWaterFog(vec4 color, vec3 viewVec)
-{
- //normalize view vector
- vec3 view = normalize(viewVec);
- float es = -view.z;
-
- //find intersection point with water plane and eye vector
-
- //get eye depth
- float e0 = max(-waterPlane.w, 0.0);
-
- //get object depth
- float depth = length(viewVec);
-
- //get "thickness" of water
- float l = max(depth, 0.1);
-
- float kd = waterFogDensity;
- float ks = waterFogKS;
- vec4 kc = waterFogColor;
-
- float F = 0.98;
-
- float t1 = -kd * pow(F, ks * e0);
- float t2 = kd + ks * es;
- float t3 = pow(F, t2*l) - 1.0;
-
- float L = min(t1/t2*t3, 1.0);
-
- float D = pow(0.98, l*kd);
- //return vec4(1.0, 0.0, 1.0, 1.0);
- return color * D + kc * L;
- //depth /= 10.0;
- //return vec4(depth,depth,depth,0.0);
-}
+vec2 encode_normal(vec3 n);
void main()
{
@@ -151,10 +76,7 @@ void main()
vec4 fb = texture2D(screenTex, distort);
- // Fix gamma in underwater
- //frag_data[0] = vec4(linear_to_srgb(fb.rgb), 1.0); // diffuse
frag_data[0] = vec4(fb.rgb, 1.0); // diffuse
- //
frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
- frag_data[2] = vec4(encode_normal(wavef), 0.0, 0.0); // normalxyz, displace
+ frag_data[2] = vec4(encode_normal(wavef), 0.0, 0.0); // normalxyz, env intens, atmo kill
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
index 45124a5099..ceb4b8033d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file waterF.glsl
+ * @file class1/deferred/waterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -37,17 +37,10 @@ vec3 scaleSoftClip(vec3 inColor);
vec3 atmosTransport(vec3 inColor);
uniform sampler2D bumpMap;
+uniform sampler2D bumpMap2;
+uniform float blend_factor;
uniform sampler2D screenTex;
uniform sampler2D refTex;
-uniform sampler2DRectShadow shadowMap0;
-uniform sampler2DRectShadow shadowMap1;
-uniform sampler2DRectShadow shadowMap2;
-uniform sampler2DRectShadow shadowMap3;
-uniform sampler2D noiseMap;
-
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-
uniform float sunAngle;
uniform float sunAngle2;
uniform vec3 lightDir;
@@ -62,6 +55,7 @@ uniform float fresnelOffset;
uniform float blurMultiplier;
uniform vec2 screen_res;
uniform mat4 norm_mat; //region space to screen space
+uniform int water_edge;
//bigWave is (refCoord.w, view.w);
VARYING vec4 refCoord;
@@ -69,141 +63,116 @@ VARYING vec4 littleWave;
VARYING vec4 view;
VARYING vec4 vary_position;
-vec3 srgb_to_linear(vec3 cs)
+vec2 encode_normal(vec3 n);
+vec3 scaleSoftClip(vec3 l);
+vec3 srgb_to_linear(vec3 c);
+vec3 linear_to_srgb(vec3 c);
+
+vec3 BlendNormal(vec3 bump1, vec3 bump2)
{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
-#endif
-
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
+ vec3 n = mix(bump1, bump2, blend_factor);
+ return n;
}
void main()
{
- vec4 color;
- float dist = length(view.xy);
-
- //normalize view vector
- vec3 viewVec = normalize(view.xyz);
-
- //get wave normals
- vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
- vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
- //get base fresnel components
-
- vec3 df = vec3(
- dot(viewVec, wave1),
- dot(viewVec, (wave2 + wave3) * 0.5),
- dot(viewVec, wave3)
- ) * fresnelScale + fresnelOffset;
- df *= df;
-
- vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
-
- float dist2 = dist;
- dist = max(dist, 5.0);
-
- float dmod = sqrt(dist);
-
- vec2 dmod_scale = vec2(dmod*dmod, dmod);
-
- //get reflected color
- vec2 refdistort1 = wave1.xy*normScale.x;
- vec2 refvec1 = distort+refdistort1/dmod_scale;
- vec4 refcol1 = texture2D(refTex, refvec1);
-
- vec2 refdistort2 = wave2.xy*normScale.y;
- vec2 refvec2 = distort+refdistort2/dmod_scale;
- vec4 refcol2 = texture2D(refTex, refvec2);
-
- vec2 refdistort3 = wave3.xy*normScale.z;
- vec2 refvec3 = distort+refdistort3/dmod_scale;
- vec4 refcol3 = texture2D(refTex, refvec3);
+ vec4 color;
+ float dist = length(view.xyz);
+
+ //normalize view vector
+ vec3 viewVec = normalize(view.xyz);
+
+ //get wave normals
+ vec3 wave1_a = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
+ vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
- vec4 refcol = refcol1 + refcol2 + refcol3;
- float df1 = df.x + df.y + df.z;
+
+ vec3 wave1_b = texture2D(bumpMap2, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
+ vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
+
+ vec3 wave1 = BlendNormal(wave1_a, wave1_b);
+ vec3 wave2 = BlendNormal(wave2_a, wave2_b);
+ vec3 wave3 = BlendNormal(wave3_a, wave3_b);
+
+ //get base fresnel components
+
+ vec3 df = vec3(
+ dot(viewVec, wave1),
+ dot(viewVec, (wave2 + wave3) * 0.5),
+ dot(viewVec, wave3)
+ ) * fresnelScale + fresnelOffset;
+ df *= df;
+
+ vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
+
+ float dist2 = dist;
+ dist = max(dist, 5.0);
+
+ float dmod = sqrt(dist);
+
+ vec2 dmod_scale = vec2(dmod*dmod, dmod);
+
+ //get reflected color
+ vec2 refdistort1 = wave1.xy*normScale.x;
+ vec2 refvec1 = distort+refdistort1/dmod_scale;
+ vec4 refcol1 = texture2D(refTex, refvec1);
+
+ vec2 refdistort2 = wave2.xy*normScale.y;
+ vec2 refvec2 = distort+refdistort2/dmod_scale;
+ vec4 refcol2 = texture2D(refTex, refvec2);
+
+ vec2 refdistort3 = wave3.xy*normScale.z;
+ vec2 refvec3 = distort+refdistort3/dmod_scale;
+ vec4 refcol3 = texture2D(refTex, refvec3);
+
+ vec4 refcol = refcol1 + refcol2 + refcol3;
+ float df1 = df.x + df.y + df.z;
refcol *= df1 * 0.333;
-
- vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
- wavef.z *= max(-viewVec.z, 0.1);
- wavef = normalize(wavef);
-
- float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
-
- vec2 refdistort4 = wavef.xy*0.125;
- refdistort4.y -= abs(refdistort4.y);
- vec2 refvec4 = distort+refdistort4/dmod;
- float dweight = min(dist2*blurMultiplier, 1.0);
- vec4 baseCol = texture2D(refTex, refvec4);
+
+ vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
+ wavef.z *= max(-viewVec.z, 0.1);
+ wavef = normalize(wavef);
+
+ float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
+
+ vec2 refdistort4 = wavef.xy*0.125;
+ refdistort4.y -= abs(refdistort4.y);
+ vec2 refvec4 = distort+refdistort4/dmod;
+ float dweight = min(dist2*blurMultiplier, 1.0);
+ vec4 baseCol = texture2D(refTex, refvec4);
- refcol = mix(baseCol*df2, refcol, dweight);
+ refcol = mix(baseCol*df2, refcol, dweight);
- //get specular component
+ //get specular component
float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
//harden specular
spec = pow(spec, 128.0);
//figure out distortion vector (ripply)
- vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
+ vec2 distort2 = distort+wavef.xy*refScale*0.16/max(dmod*df1, 1.0);
vec4 fb = texture2D(screenTex, distort2);
//mix with reflection
// Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug
- color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
+ color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999f);
vec4 pos = vary_position;
color.rgb += spec * specular;
-
+
color.rgb = atmosTransport(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
+
color.a = spec * sunAngle2;
-
+
vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz);
-
- // Fix weird water glow on edge of land due to broken alpha value
- //frag_data[0] = vec4(color.rgb, color); // diffuse
- //frag_data[1] = vec4(0); // speccolor, spec
- //frag_data[2] = vec4(encode_normal(screenspacewavef.xyz*0.5+0.5), 0.05, 0);// normalxy, 0, 0
- frag_data[0] = vec4(color.rgb, color.a); // diffuse
- frag_data[1] = vec4(0.5, 0.5, 0.5, 0.75); // speccolor, spec
+
+ //frag_data[0] = color;
+ frag_data[0] = color;
+ frag_data[1] = vec4(0); // speccolor, spec
frag_data[2] = vec4(encode_normal(screenspacewavef.xyz), 0.05, 0);// normalxy, 0, 0
- //
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
index 9734acf005..8863869e44 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
@@ -31,8 +31,8 @@ ATTRIBUTE vec3 position;
void calcAtmospherics(vec3 inPositionEye);
-uniform vec2 d1;
-uniform vec2 d2;
+uniform vec2 waveDir1;
+uniform vec2 waveDir2;
uniform float time;
uniform vec3 eyeVec;
uniform float waterHeight;
@@ -88,10 +88,10 @@ void main()
calcAtmospherics(pos.xyz);
//pass wave parameters to pixel shader
- vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055;
+ vec2 bigWave = (v.xy) * vec2(0.04,0.04) + waveDir1 * time * 0.055;
//get two normal map (detail map) texture coordinates
- littleWave.xy = (v.xy) * vec2(0.45, 0.9) + d2 * time * 0.13;
- littleWave.zw = (v.xy) * vec2(0.1, 0.2) + d1 * time * 0.1;
+ littleWave.xy = (v.xy) * vec2(0.45, 0.9) + waveDir2 * time * 0.13;
+ littleWave.zw = (v.xy) * vec2(0.1, 0.2) + waveDir1 * time * 0.1;
view.w = bigWave.y;
refCoord.w = bigWave.x;
diff --git a/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl b/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl
new file mode 100644
index 0000000000..50e781fa78
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl
@@ -0,0 +1,31 @@
+/**
+ * @file encodeNormF.glsl
+ *
+ * $LicenseInfo:firstyear=2018&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2018, 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$
+ */
+
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl
similarity index 67%
rename from indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl
rename to indra/newview/app_settings/shaders/class1/environment/srgbF.glsl
index 6cc1e6e798..4a8b892c3a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl
@@ -1,5 +1,5 @@
/**
- * @file srgb.glsl
+ * @file srgbF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -27,14 +27,18 @@ vec3 srgb_to_linear(vec3 cs)
{
vec3 low_range = cs / vec3(12.92);
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
-
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+#ifdef OLD_SELECT
vec3 result;
result.r = lte.r ? low_range.r : high_range.r;
result.g = lte.g ? low_range.g : high_range.g;
result.b = lte.b ? low_range.b : high_range.b;
return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
}
vec3 linear_to_srgb(vec3 cl)
@@ -42,13 +46,39 @@ vec3 linear_to_srgb(vec3 cl)
cl = clamp(cl, vec3(0), vec3(1));
vec3 low_range = cl * 12.92;
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
-
bvec3 lt = lessThan(cl,vec3(0.0031308));
+#ifdef OLD_SELECT
vec3 result;
result.r = lt.r ? low_range.r : high_range.r;
result.g = lt.g ? low_range.g : high_range.g;
result.b = lt.b ? low_range.b : high_range.b;
- return result;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
}
+vec3 ColorFromRadiance(vec3 radiance)
+{
+ return vec3(1.0) - exp(-radiance * 0.0001);
+}
+
+vec3 rgb2hsv(vec3 c)
+{
+ vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
+ vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
+ vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
+
+ float d = q.x - min(q.w, q.y);
+ float e = 1.0e-10;
+ return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
+}
+
+vec3 hsv2rgb(vec3 c)
+{
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+}
diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl
index 668a710c04..6b68ed4169 100644
--- a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl
@@ -1,5 +1,5 @@
/**
- * @file terrainF.glsl
+ * @file class1\environment\terrainF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl
index d09c5f9247..ef27848d37 100644
--- a/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl
@@ -1,5 +1,5 @@
/**
- * @file terrainV.glsl
+ * @file class1\environment\terrainV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -35,6 +35,7 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
ATTRIBUTE vec2 texcoord1;
+ATTRIBUTE vec4 diffuse_color;
VARYING vec4 vertex_color;
VARYING vec4 vary_texcoord0;
@@ -42,7 +43,7 @@ VARYING vec4 vary_texcoord1;
void calcAtmospherics(vec3 inPositionEye);
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1)
{
@@ -71,7 +72,7 @@ void main()
/// Potentially better without it for water.
pos /= pos.w;
- vec4 color = calcLighting(pos.xyz, norm, vec4(1,1,1,1), vec4(0));
+ vec4 color = calcLighting(pos.xyz, norm, /*diffuse_color*/vec4(1));
vertex_color = color;
diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl
index a956562396..e53bb46177 100644
--- a/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file terrainWaterF.glsl
+ * @file class1\environment\terrainWaterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -64,4 +64,3 @@ void main()
outColor = applyWaterFog(outColor);
frag_color = outColor;
}
-
diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainWaterV.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainWaterV.glsl
new file mode 100644
index 0000000000..a075cfeef2
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/environment/terrainWaterV.glsl
@@ -0,0 +1,84 @@
+/**
+ * @file class1\environment\terrainV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+uniform vec4 object_plane_t;
+uniform vec4 object_plane_s;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec2 texcoord1;
+ATTRIBUTE vec4 diffuse_color;
+
+VARYING vec4 vertex_color;
+VARYING vec4 vary_texcoord0;
+VARYING vec4 vary_texcoord1;
+
+void calcAtmospherics(vec3 inPositionEye);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
+
+vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1)
+{
+ vec4 tcoord;
+
+ tcoord.x = dot(vpos, tp0);
+ tcoord.y = dot(vpos, tp1);
+ tcoord.z = tc.z;
+ tcoord.w = tc.w;
+
+ tcoord = mat * tcoord;
+
+ return tcoord;
+}
+
+void main()
+{
+ //transform vertex
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+
+ vec4 pos = modelview_matrix * vec4(position.xyz, 1.0);
+ vec3 norm = normalize(normal_matrix * normal);
+
+ calcAtmospherics(pos.xyz);
+
+ vec4 color = calcLighting(pos.xyz, norm, vec4(1.0));
+
+ vertex_color.rgb = color.rgb;
+
+ // Transform and pass tex coords
+ vary_texcoord0.xy = texgen_object(vec4(position.xyz, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy;
+
+ vec4 t = vec4(texcoord1,0,1);
+
+ vary_texcoord0.zw = t.xy;
+ vary_texcoord1.xy = t.xy-vec2(2.0, 0.0);
+ vary_texcoord1.zw = t.xy-vec2(1.0, 0.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
index 0d8dab0a41..8c8bd6d0d5 100644
--- a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file underWaterF.glsl
+ * @file class1\environment\underWaterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -47,7 +47,6 @@ uniform float kd;
uniform vec4 waterPlane;
uniform vec3 eyeVec;
uniform vec4 waterFogColor;
-uniform float waterFogDensity;
uniform float waterFogKS;
uniform vec2 screenRes;
@@ -56,41 +55,7 @@ VARYING vec4 refCoord;
VARYING vec4 littleWave;
VARYING vec4 view;
-vec4 applyWaterFog(vec4 color, vec3 viewVec)
-{
- //normalize view vector
- vec3 view = normalize(viewVec);
- float es = -view.z;
-
- //find intersection point with water plane and eye vector
-
- //get eye depth
- float e0 = max(-waterPlane.w, 0.0);
-
- //get object depth
- float depth = length(viewVec);
-
- //get "thickness" of water
- float l = max(depth, 0.1);
-
- float kd = waterFogDensity;
- float ks = waterFogKS;
- vec4 kc = waterFogColor;
-
- float F = 0.98;
-
- float t1 = -kd * pow(F, ks * e0);
- float t2 = kd + ks * es;
- float t3 = pow(F, t2*l) - 1.0;
-
- float L = min(t1/t2*t3, 1.0);
-
- float D = pow(0.98, l*kd);
- //return vec4(1.0, 0.0, 1.0, 1.0);
- return color * D + kc * L;
- //depth /= 10.0;
- //return vec4(depth,depth,depth,0.0);
-}
+vec4 applyWaterFogView(vec3 pos, vec4 color);
void main()
{
@@ -108,5 +73,5 @@ void main()
vec4 fb = texture2D(screenTex, distort);
- frag_color = applyWaterFog(fb,view.xyz);
+ frag_color = applyWaterFogView(view.xyz, fb);
}
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
index 79bffab745..d370997123 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
@@ -32,7 +32,9 @@ out vec4 frag_color;
vec3 scaleSoftClip(vec3 inColor);
vec3 atmosTransport(vec3 inColor);
-uniform sampler2D bumpMap;
+uniform sampler2D bumpMap;
+uniform sampler2D bumpMap2;
+uniform float blend_factor;
uniform sampler2D screenTex;
uniform sampler2D refTex;
@@ -55,6 +57,13 @@ VARYING vec4 refCoord;
VARYING vec4 littleWave;
VARYING vec4 view;
+vec3 BlendNormal(vec3 bump1, vec3 bump2)
+{
+ vec3 n = mix(bump1, bump2, blend_factor);
+ return n;
+}
+
+
void main()
{
vec4 color;
@@ -65,9 +74,21 @@ void main()
vec3 viewVec = normalize(view.xyz);
//get wave normals
- vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
- vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
+ vec2 bigwave = vec2(refCoord.w, view.w);
+ vec3 wave1_a = texture2D(bumpMap, bigwave ).xyz*2.0-1.0;
+ vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
+
+
+ vec3 wave1_b = texture2D(bumpMap2, bigwave ).xyz*2.0-1.0;
+ vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
+
+ vec3 wave1 = BlendNormal(wave1_a, wave1_b);
+ vec3 wave2 = BlendNormal(wave2_a, wave2_b);
+ vec3 wave3 = BlendNormal(wave3_a, wave3_b);
+
+
//get base fresnel components
vec3 df = vec3(
@@ -136,6 +157,12 @@ void main()
color.rgb = atmosTransport(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
color.a = spec * sunAngle2;
-
+
frag_color = color;
+
+#if defined(WATER_EDGE)
+ gl_FragDepth = 0.9999847f;
+#endif
+
}
+
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
index 4bdfce9260..df640cba05 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
@@ -1,5 +1,5 @@
/**
- * @file waterFogF.glsl
+ * @file class1\environment\waterFogF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -25,7 +25,6 @@
-uniform vec4 lightnorm;
uniform vec4 waterPlane;
uniform vec4 waterFogColor;
uniform float waterFogDensity;
@@ -33,42 +32,48 @@ uniform float waterFogKS;
vec3 getPositionEye();
-vec4 applyWaterFog(vec4 color)
+vec4 applyWaterFogView(vec3 pos, vec4 color)
{
- //normalize view vector
- vec3 view = normalize(getPositionEye());
- float es = -(dot(view, waterPlane.xyz));
+ vec3 view = normalize(pos);
+ //normalize view vector
+ float es = -(dot(view, waterPlane.xyz));
- //find intersection point with water plane and eye vector
-
- //get eye depth
- float e0 = max(-waterPlane.w, 0.0);
-
- vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
-
- //get object depth
- float depth = length(getPositionEye() - int_v);
-
- //get "thickness" of water
- float l = max(depth, 0.1);
+ //find intersection point with water plane and eye vector
+
+ //get eye depth
+ float e0 = max(-waterPlane.w, 0.0);
+
+ vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
+
+ //get object depth
+ float depth = length(pos - int_v);
+
+ //get "thickness" of water
+ float l = max(depth, 0.1);
- float kd = waterFogDensity;
- float ks = waterFogKS;
- vec4 kc = waterFogColor;
-
- float F = 0.98;
-
- float t1 = -kd * pow(F, ks * e0);
- float t2 = kd + ks * es;
- float t3 = pow(F, t2*l) - 1.0;
-
- float L = min(t1/t2*t3, 1.0);
-
- float D = pow(0.98, l*kd);
-
- color.rgb = color.rgb * D + kc.rgb * L;
- color.a = kc.a + color.a;
-
- return color;
+ float kd = waterFogDensity;
+ float ks = waterFogKS;
+ vec4 kc = waterFogColor;
+
+ float F = 0.98;
+
+ float t1 = -kd * pow(F, ks * e0);
+ float t2 = kd + ks * es;
+ float t3 = pow(F, t2*l) - 1.0;
+
+ float L = min(t1/t2*t3, 1.0);
+
+ float D = pow(0.98, l*kd);
+
+ color.rgb = color.rgb * D + kc.rgb * L;
+ color.a = kc.a + color.a;
+
+ return color;
+}
+
+vec4 applyWaterFog(vec4 color)
+{
+ //normalize view vector
+ return applyWaterFogView(getPositionEye(), color);
}
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
index 352cea7aaa..cc41e3f740 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
@@ -1,5 +1,5 @@
/**
- * @file waterV.glsl
+ * @file class1\environment\waterV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -31,8 +31,8 @@ ATTRIBUTE vec3 position;
void calcAtmospherics(vec3 inPositionEye);
-uniform vec2 d1;
-uniform vec2 d2;
+uniform vec2 waveDir1;
+uniform vec2 waveDir2;
uniform float time;
uniform vec3 eyeVec;
uniform float waterHeight;
@@ -86,10 +86,10 @@ void main()
//pass wave parameters to pixel shader
- vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055;
+ vec2 bigWave = (v.xy) * vec2(0.04,0.04) + waveDir1 * time * 0.055;
//get two normal map (detail map) texture coordinates
- littleWave.xy = (v.xy) * vec2(0.45, 0.9) + d2 * time * 0.13;
- littleWave.zw = (v.xy) * vec2(0.1, 0.2) + d1 * time * 0.1;
+ littleWave.xy = (v.xy) * vec2(0.45, 0.9) + waveDir2 * time * 0.13;
+ littleWave.zw = (v.xy) * vec2(0.1, 0.2) + waveDir1 * time * 0.1;
view.w = bigWave.y;
refCoord.w = bigWave.x;
diff --git a/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl b/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl
index a96d04cc39..f6b31a5956 100644
--- a/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl
@@ -38,7 +38,9 @@ VARYING vec2 vary_texcoord0;
void main()
{
- vec4 color = vertex_color*texture2D(diffuseMap, vary_texcoord0.xy);
- color.a *= custom_alpha;
+ vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
+ color.rgb = pow(color.rgb, vec3(0.45));
+ color.rgb *= vertex_color.rgb;
+ color.a *= max(custom_alpha, vertex_color.a);
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl
index 0d9af3e780..d92e4b2258 100644
--- a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl
@@ -25,14 +25,14 @@
#extension GL_ARB_texture_rectangle : enable
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
-/*[EXTRA_CODE_HERE]*/
-
uniform sampler2D glowMap;
uniform sampler2DRect screenMap;
uniform vec3 exo_vignette;
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
index cad5b9ff04..f665394b46 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightAlphaMaskF.glsl
+ * @file class1\lighting\lightAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl
index 8918182853..b768d609f4 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightAlphaMaskNonIndexedF.glsl
+ * @file class1\lighting\lightAlphaMaskNonIndexedF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl
index d6ebfcb825..9fd189358b 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightF.glsl
+ * @file class1\lighting\lightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
index 5740987ab1..46390e4a0e 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightAlphaMaskF.glsl
+ * @file class1\lighting\lightFullbrightAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
index c8771a3f1e..b967709c57 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightF.glsl
+ * @file class1\lighting\lightFullbrightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
index f72f20b03d..e8e71beb44 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightNonIndexedAlphaMaskF.glsl
+ * @file class1\lighting\lightFullbrightNonIndexedAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl
index 2738ff8947..11a0919086 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightF.glsl
+ * @file class1\lighting\lightFullbrightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
index c8282e9a51..567811cd75 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightShinyF.glsl
+ * @file class1\lighting\lightFullbrightShinyF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -44,7 +44,7 @@ void fullbright_shiny_lighting()
color.rgb *= vertex_color.rgb;
vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
- color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
+ color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a*0.75); // MAGIC NUMBER SL-12574; ALM: Off, Quality > Low
color.rgb = fullbrightShinyAtmosTransport(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl
index e7dbd4bbd2..3118453342 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightShinyF.glsl
+ * @file class1\lighting\lightFullbrightShinyF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl
index 5886fc65be..f78e5e0e8a 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightShinyWaterF.glsl
+ * @file class1\lighting\lightFullbrightShinyWaterF.glsl
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl
index cddc7d8df8..90668bd2b6 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightShinyWaterF.glsl
+ * @file class1\lighting\lightFullbrightShinyWaterF.glsl
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
index 6dd3bb937f..d04cd79f4b 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightWaterAlphaMaskF.glsl
+ * @file class1\lighting\lightFullbrightWaterAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
index d3dacf9bc4..27880b720c 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightWaterF.glsl
+ * @file class1\lighting\lightFullbrightWaterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl
index 63f92a8844..3b9c04b22b 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightWaterNonIndexedAlphaMaskF.glsl
+ * @file class1\lighting\lightFullbrightWaterNonIndexedAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl
index 0e68091e7c..e9fd8ac820 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightWaterF.glsl
+ * @file class1\lighting\lightFullbrightWaterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl
index 85cddc647d..13a6dde4aa 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFuncSpecularV.glsl
+ * @file class1/lighting\lightFuncSpecularV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,14 +23,6 @@
* $/LicenseInfo$
*/
-
-
-float calcDirectionalLight(vec3 n, vec3 l)
-{
- float a = max(dot(n,l),0.0);
- return a;
-}
-
float calcDirectionalSpecular(vec3 view, vec3 n, vec3 l)
{
return pow(max(dot(reflect(view, n),l), 0.0),8.0);
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl
index a9288b3df6..45701002b8 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFuncV.glsl
+ * @file class1\lighting\lightFuncV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -32,8 +32,7 @@ float calcDirectionalLight(vec3 n, vec3 l)
return a;
}
-
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight)
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
{
//get light vector
vec3 lv = lp.xyz-v;
@@ -54,6 +53,6 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
//angular attenuation
da *= calcDirectionalLight(n, lv);
- return da;
+ return da;
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl
index 0aca768021..f9c7ad2ab3 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightF.glsl
+ * @file class1\lighting\lightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl
index 9208c148ef..f621a00785 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightShinyF.glsl
+ * @file class1\lighting\lightShinyF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -45,7 +45,7 @@ void shiny_lighting()
color.rgb *= vertex_color.rgb;
vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
- color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
+ color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a*0.75); // MAGIC NUMBER SL-12574; ALM: Off, Quality > Low
color.rgb = atmosLighting(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl
index 92628faa68..2b6f414005 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightShinyF.glsl
+ * @file class1\lighting\lightShinyF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl
index 61841674e2..0f3371eba9 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightShinyWaterF.glsl
+ * @file class1\lighting\lightShinyWaterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl
index 0b6e835fd0..c607fa64cb 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightShinyWaterF.glsl
+ * @file class1\lighting\lightShinyWaterNonIndexedF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl
index 24bf9b3cee..06aed40e26 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightSpecularV.glsl
+ * @file class1\lighting\lightSpecularV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -27,10 +27,10 @@
// All lights, no specular highlights
-vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol);
+vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor);
-vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol)
+vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor)
{
- return sumLightsSpecular(pos, norm, color, specularColor, baseCol);
+ return sumLightsSpecular(pos, norm, color, specularColor);
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl
index 8045809b82..5e39d1629d 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightV.glsl
+ * @file class1\lighting\lightV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -26,11 +26,18 @@
// All lights, no specular highlights
+vec3 atmosAmbient();
+vec4 sumLights(vec3 pos, vec3 norm, vec4 color);
+float getAmbientClamp();
-vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight);
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseLight)
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color)
{
- return sumLights(pos, norm, color, baseLight);
+ vec4 c = sumLights(pos, norm, color);
+
+#if !defined(AMBIENT_KILL)
+ c.rgb += atmosAmbient() * color.rgb * 0.5 * getAmbientClamp();
+#endif
+
+ return c;
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
index 3426fea52f..0916797259 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightWaterAlphaMaskF.glsl
+ * @file class1\lighting\lightWaterAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
index d9faa9b314..f2a84f1d42 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightWaterAlphaMaskNonIndexedF.glsl
+ * @file class1\lighting\lightWaterAlphaMaskNonIndexedF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl
index 00609e93cd..57ed993a66 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightWaterF.glsl
+ * @file class1\lighting\lightWaterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl
index 13ecb7a636..af5da1411b 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightWaterF.glsl
+ * @file class1\lighting\lightWaterNonIndexedF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl
index 7059ff31ae..7c3697c333 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl
@@ -1,5 +1,5 @@
/**
- * @file sumLightsSpecularV.glsl
+ * @file class1\lighting\sumLightsSpecularV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -26,7 +26,7 @@
float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da);
-vec3 atmosAmbient(vec3 light);
+vec3 atmosAmbient();
vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 atmosGetDiffuseSunlightColor();
vec3 scaleDownLight(vec3 light);
@@ -34,7 +34,7 @@ vec3 scaleDownLight(vec3 light);
uniform vec4 light_position[8];
uniform vec3 light_diffuse[8];
-vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol)
+vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor)
{
vec4 col = vec4(0,0,0, color.a);
@@ -45,8 +45,8 @@ vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor
col.rgb += light_diffuse[1].rgb * calcDirectionalLightSpecular(specularColor, view, norm, light_position[1].xyz,light_diffuse[1].rgb, 1.0);
col.rgb = scaleDownLight(col.rgb);
- col.rgb += atmosAmbient(baseCol.rgb);
- col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, light_position[0].xyz,atmosGetDiffuseSunlightColor()*baseCol.a, 1.0));
+ col.rgb += atmosAmbient();
+ col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, light_position[0].xyz, atmosGetDiffuseSunlightColor(), 1.0));
col.rgb = min(col.rgb * color.rgb, 1.0);
specularColor.rgb = min(specularColor.rgb * specularSum.rgb, 1.0);
diff --git a/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl
index 41288c21c1..0c3ea4231e 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl
@@ -1,5 +1,5 @@
/**
- * @file sumLightsV.glsl
+ * @file class1\lighting\sumLightsV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -28,22 +28,27 @@ uniform vec3 light_diffuse[8];
float calcDirectionalLight(vec3 n, vec3 l);
-vec3 atmosAmbient(vec3 light);
+vec3 atmosAmbient();
vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 scaleDownLight(vec3 light);
-vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight)
+vec4 sumLights(vec3 pos, vec3 norm, vec4 color)
{
- vec4 col;
+ vec4 col = vec4(0);
col.a = color.a;
col.rgb = light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
col.rgb = scaleDownLight(col.rgb);
- col.rgb += atmosAmbient(baseLight.rgb);
+
+#if defined(LOCAL_LIGHT_KILL)
+ col.rgb = vec3(0);
+#endif
+
+#if !defined(SUNLIGHT_KILL)
col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, light_position[0].xyz));
-
+#endif
+
col.rgb = min(col.rgb*color.rgb, 1.0);
-
return col;
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl
index a54c0caf81..31a262f1db 100644
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl
@@ -1,5 +1,5 @@
/**
- * @file fullbrightF.glsl
+ * @file objects/fullbrightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl
index 79b552ee1a..1e244d9dfd 100644
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl
@@ -35,6 +35,7 @@ ATTRIBUTE vec2 texcoord0;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_texcoord1;
+VARYING vec4 vary_position;
void calcAtmospherics(vec3 inPositionEye);
@@ -46,6 +47,9 @@ void main()
mat = modelview_matrix * mat;
vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
+
+ mat4 mvp = modelview_matrix * projection_matrix;
+ vary_position = mvp * vec4(position, 1.0);
vec4 norm = vec4(position.xyz, 1.0);
norm.xyz += normal.xyz;
diff --git a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
index de2ea2a065..a4826f9b05 100644
--- a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
@@ -52,7 +52,7 @@ float calcDirectionalLight(vec3 n, vec3 l)
}
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight)
+float calcLocalLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight)
{
//get light vector
vec3 lv = lp.xyz-v;
diff --git a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl
index 591d6fc5c9..727bae19c0 100644
--- a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl
@@ -36,7 +36,7 @@ VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_texcoord1;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
void calcAtmospherics(vec3 inPositionEye);
mat4 getObjectSkinnedTransform();
@@ -59,7 +59,7 @@ void main()
calcAtmospherics(pos.xyz);
- vec4 color = calcLighting(pos.xyz, norm.xyz, diffuse_color, vec4(0.));
+ vec4 color = calcLighting(pos.xyz, norm.xyz, diffuse_color);
vertex_color = color;
gl_Position = projection_matrix*vec4(pos, 1.0);
diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl
index fdb3453cc5..4ba8194d03 100644
--- a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl
@@ -39,7 +39,7 @@ VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_texcoord1;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
void calcAtmospherics(vec3 inPositionEye);
@@ -61,5 +61,5 @@ void main()
calcAtmospherics(pos.xyz);
- vertex_color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.0));
+ vertex_color = calcLighting(pos.xyz, norm, diffuse_color);
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl
index 0be52a52af..22821a2f76 100644
--- a/indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl
@@ -38,7 +38,7 @@ VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
void calcAtmospherics(vec3 inPositionEye);
void main()
@@ -52,7 +52,7 @@ void main()
calcAtmospherics(pos.xyz);
- vec4 col = calcLighting(pos.xyz, norm, color, vec4(0.));
+ vec4 col = calcLighting(pos.xyz, norm, color);
vertex_color = col;
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl
index cb80697d15..e605676819 100644
--- a/indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl
@@ -37,7 +37,7 @@ VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
void calcAtmospherics(vec3 inPositionEye);
void main()
@@ -54,7 +54,7 @@ void main()
calcAtmospherics(pos.xyz);
- vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
+ vec4 color = calcLighting(pos.xyz, norm, diffuse_color);
vertex_color = color;
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl
index 1c6e53b187..df31b5a79f 100644
--- a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl
@@ -35,7 +35,7 @@ VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
void calcAtmospherics(vec3 inPositionEye);
mat4 getObjectSkinnedTransform();
@@ -56,7 +56,7 @@ void main()
calcAtmospherics(pos.xyz);
- vec4 color = calcLighting(pos.xyz, norm.xyz, diffuse_color, vec4(0.));
+ vec4 color = calcLighting(pos.xyz, norm.xyz, diffuse_color);
vertex_color = color;
gl_Position = projection_matrix*vec4(pos, 1.0);
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl
index d4dee78793..945f80f31e 100644
--- a/indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl
@@ -37,7 +37,7 @@ uniform vec4 color;
uniform vec4 object_plane_t;
uniform vec4 object_plane_s;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
void calcAtmospherics(vec3 inPositionEye);
VARYING vec4 vertex_color;
@@ -70,7 +70,7 @@ void main()
calcAtmospherics(pos.xyz);
- vec4 color = calcLighting(pos.xyz, norm, color, vec4(0.));
+ vec4 color = calcLighting(pos.xyz, norm, color);
vertex_color = color;
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
index 37a20383e2..a59bd9c0a6 100644
--- a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
@@ -34,7 +34,7 @@ ATTRIBUTE vec2 texcoord0;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec4 diffuse_color;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
void calcAtmospherics(vec3 inPositionEye);
@@ -57,7 +57,7 @@ void main()
calcAtmospherics(pos.xyz);
- vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
+ vec4 color = calcLighting(pos.xyz, norm, diffuse_color);
vertex_color = color;
diff --git a/indra/newview/app_settings/shaders/class1/objects/treeV.glsl b/indra/newview/app_settings/shaders/class1/objects/treeV.glsl
index fa01a27ec0..0227e6e3b8 100644
--- a/indra/newview/app_settings/shaders/class1/objects/treeV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/treeV.glsl
@@ -31,8 +31,9 @@ uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
ATTRIBUTE vec2 texcoord0;
ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 diffuse_color;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
void calcAtmospherics(vec3 inPositionEye);
VARYING vec4 vertex_color;
@@ -53,8 +54,6 @@ void main()
calcAtmospherics(pos.xyz);
- vec4 color = calcLighting(pos.xyz, norm, vec4(1,1,1,1), vec4(0.));
+ vec4 color = calcLighting(pos.xyz, norm, diffuse_color);
vertex_color = color;
-
-
}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
index aacc503e13..4e0618e276 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericsF.glsl
+ * @file class1\windlight\atmosphericsF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,11 +23,26 @@
* $/LicenseInfo$
*/
+vec3 atmosFragAmbient(vec3 light, vec3 sunlit)
+{
+ /* stub function for fallback compatibility on class1 hardware */
+ return light;
+}
+vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
+{
+ /* stub function for fallback compatibility on class1 hardware */
+ return light;
+}
+
+vec3 atmosFragAffectDirectionalLight(float light, vec3 sunlit)
+{
+ return light * sunlit;
+}
vec3 atmosLighting(vec3 light)
{
- /* stub function for fallback compatibility on class1 hardware */
- return light;
+ /* stub function for fallback compatibility on class1 hardware */
+ return light;
}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
new file mode 100644
index 0000000000..dcb02bd1c1
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
@@ -0,0 +1,154 @@
+/**
+ * @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 float haze_horizon;
+uniform float haze_density;
+uniform float cloud_shadow;
+uniform float density_multiplier;
+uniform float distance_multiplier;
+uniform float max_y;
+uniform vec4 glow;
+uniform float scene_light_strength;
+uniform mat3 ssao_effect_mat;
+uniform int no_atmo;
+uniform float sun_moon_glow_factor;
+
+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) {
+
+ 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);
+
+ vec3 tmpLightnorm = lightnorm.xyz;
+
+ vec3 Pn = normalize(P);
+ float Plen = length(P);
+
+ vec4 temp1 = vec4(0);
+ vec3 temp2 = vec3(0);
+ vec4 blue_weight;
+ vec4 haze_weight;
+ vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
+ vec4 light_atten;
+
+ float dens_mul = density_multiplier;
+ float dist_mul = distance_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);
+ //I had thought blue_density and haze_density should have equal weighting,
+ //but attenuation due to haze_density tends to seem too strong
+
+ temp1 = blue_density + vec4(haze_density);
+ blue_weight = blue_density / temp1;
+ haze_weight = vec4(haze_density) / temp1;
+
+ //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
+ temp2.y = max(0.0, tmpLightnorm.y);
+ 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);
+
+ // main atmospheric scattering line integral
+ temp2.z = Plen * dens_mul;
+
+ // 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);
+
+ //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);
+
+ // 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
+ 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);
+ */
+ 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));
+
+ //brightness of surface both sunlight and ambient
+ sunlit = sunlight.rgb * 0.5;
+ amblit = tmpAmbient.rgb * .25;
+ additive *= vec3(1.0 - temp1);
+}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersF.glsl
new file mode 100644
index 0000000000..206a51db27
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersF.glsl
@@ -0,0 +1,51 @@
+/**
+ * @file class1\windlight\atmosphericsHelpersF.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 vec4 sunlight_color;
+uniform vec4 light_ambient;
+uniform int no_atmo;
+
+vec3 atmosAmbient()
+{
+ if (no_atmo == 1) return vec3(0.16);
+ return light_ambient.rgb;
+}
+
+vec3 atmosAffectDirectionalLight(float lightIntensity)
+{
+ return sunlight_color.rgb * lightIntensity;
+}
+
+vec3 atmosGetDiffuseSunlightColor()
+{
+ return sunlight_color.rgb;
+}
+
+vec3 scaleDownLight(vec3 light)
+{
+ /* stub function for fallback compatibility on class1 hardware */
+ return light;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
index 6ff860362c..c266f9732f 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericsHelpersV.glsl
+ * @file class1\windlight\atmosphericsHelpersV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,33 +23,35 @@
* $/LicenseInfo$
*/
-uniform vec4 sunlight_color_copy;
+uniform vec4 sunlight_color;
uniform vec4 light_ambient;
+uniform int no_atmo;
-vec3 atmosAmbient(vec3 light)
+vec3 atmosAmbient()
{
- return light + light_ambient.rgb;
+ if (no_atmo == 1) return vec3(0.66);
+ return light_ambient.rgb;
}
vec3 atmosAffectDirectionalLight(float lightIntensity)
{
- return sunlight_color_copy.rgb * lightIntensity;
+ return sunlight_color.rgb * lightIntensity;
}
vec3 atmosGetDiffuseSunlightColor()
{
- return sunlight_color_copy.rgb;
+ return sunlight_color.rgb;
}
vec3 scaleDownLight(vec3 light)
{
- /* stub function for fallback compatibility on class1 hardware */
- return light;
+ /* stub function for fallback compatibility on class1 hardware */
+ return light;
}
vec3 scaleUpLight(vec3 light)
{
- /* stub function for fallback compatibility on class1 hardware */
- return light;
+ /* stub function for fallback compatibility on class1 hardware */
+ return light;
}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl
index 76d7d5059d..20457ad125 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericsV.glsl
+ * @file class1\windlight\atmosphericsV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -29,7 +29,7 @@ void setPositionEye(vec3 v);
void calcAtmospherics(vec3 inPositionEye)
{
- /* stub function for fallback compatibility on class1 hardware */
- setPositionEye(inPositionEye);
+ /* stub function for fallback compatibility on class1 hardware */
+ setPositionEye(inPositionEye);
}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
index 8bdae328bd..a0699affbf 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericVarsF.glsl
+ * @file class1\windlight\atmosphericVarsF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
index 8ec9ae617c..bd1d150fc8 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericVarsV.glsl
+ * @file class1\windlight\atmosphericVarsV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
index 636d4af006..5dc086ab1e 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericVarsWaterF.glsl
+ * @file class1\windlight\atmosphericVarsWaterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
index 8afcc20f6d..e59eca265a 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericVarsWaterV.glsl
+ * @file class1\windlight\atmosphericVarsWaterV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl b/indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl
new file mode 100644
index 0000000000..82fad4db5a
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl
@@ -0,0 +1,127 @@
+/**
+ * @file class1/windlight/cloudShadowF.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$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2D diffuseMap;
+
+VARYING vec4 pos;
+VARYING float target_pos_x;
+VARYING float vary_CloudDensity;
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
+VARYING vec2 vary_texcoord3;
+
+uniform sampler2D cloud_noise_texture;
+uniform sampler2D cloud_noise_texture_next;
+uniform float blend_factor;
+uniform vec4 cloud_pos_density1;
+uniform vec4 cloud_pos_density2;
+uniform vec4 sunlight_color;
+uniform vec4 cloud_color;
+uniform float cloud_shadow;
+uniform float cloud_scale;
+uniform float cloud_variance;
+uniform vec3 camPosLocal;
+uniform vec3 sun_dir;
+uniform float sun_size;
+uniform float far_z;
+
+#if !defined(DEPTH_CLAMP)
+VARYING vec4 post_pos;
+#endif
+
+vec4 cloudNoise(vec2 uv)
+{
+ vec4 a = texture2D(cloud_noise_texture, uv);
+ vec4 b = texture2D(cloud_noise_texture_next, uv);
+ vec4 cloud_noise_sample = mix(a, b, blend_factor);
+ return normalize(cloud_noise_sample);
+}
+
+void main()
+{
+ if (cloud_scale >= 0.0001)
+ {
+ // Set variables
+ vec2 uv1 = vary_texcoord0.xy;
+ vec2 uv2 = vary_texcoord1.xy;
+ vec2 uv3 = vary_texcoord2.xy;
+ float cloudDensity = 2.0 * (cloud_shadow - 0.25);
+
+ vec2 uv4 = vary_texcoord3.xy;
+
+ vec2 disturbance = vec2(cloudNoise(uv1 / 8.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
+ vec2 disturbance2 = vec2(cloudNoise((uv1 + uv3) / 4.0f).x, cloudNoise((uv4 + uv2) / 8.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
+
+ // Offset texture coords
+ uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density
+ uv2 += cloud_pos_density1.xy; //large texture, self shadow
+ uv3 += cloud_pos_density2.xy; //small texture, visible density
+ uv4 += cloud_pos_density2.xy; //small texture, self shadow
+
+ float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0 + disturbance2.x + disturbance2.y) * 4.0);
+
+ cloudDensity *= 1.0 - (density_variance * density_variance);
+
+ // Compute alpha1, the main cloud opacity
+ float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
+ alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
+
+ // And smooth
+ alpha1 = 1. - alpha1 * alpha1;
+ alpha1 = 1. - alpha1 * alpha1;
+
+ if (alpha1 < 0.001f)
+ {
+ discard;
+ }
+
+ // Compute alpha2, for self shadowing effect
+ // (1 - alpha2) will later be used as percentage of incoming sunlight
+ float alpha2 = (cloudNoise(uv2).x - 0.5);
+ alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
+
+ // And smooth
+ alpha2 = 1. - alpha2;
+ alpha2 = 1. - alpha2 * alpha2;
+
+ frag_color = vec4(alpha1, alpha1, alpha1, 1);
+ }
+ else
+ {
+ frag_color = vec4(1);
+ }
+
+#if !defined(DEPTH_CLAMP)
+ gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
+#endif
+
+}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/cloudShadowV.glsl b/indra/newview/app_settings/shaders/class1/windlight/cloudShadowV.glsl
new file mode 100644
index 0000000000..09b6004481
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/cloudShadowV.glsl
@@ -0,0 +1,61 @@
+/**
+ * @file class1\windlight\cloudShadowV.glsl
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
+uniform float shadow_target_width;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+#if !defined(DEPTH_CLAMP)
+VARYING float pos_zd2;
+#endif
+
+VARYING vec4 pos;
+VARYING float target_pos_x;
+VARYING vec2 vary_texcoord0;
+
+void passTextureIndex();
+
+void main()
+{
+ //transform vertex
+ vec4 pre_pos = vec4(position.xyz, 1.0);
+ pos = modelview_projection_matrix * pre_pos;
+ target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
+
+#if !defined(DEPTH_CLAMP)
+ pos_zd2 = pos.z * 0.5;
+ gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+#else
+ gl_Position = pos;
+#endif
+
+ passTextureIndex();
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl
index 62f4e51449..fc51e81177 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl
@@ -1,5 +1,5 @@
/**
- * @file gammaF.glsl
+ * @file class1\windlight\gammaF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,17 +23,30 @@
* $/LicenseInfo$
*/
+uniform int no_atmo;
-
-uniform vec4 gamma;
-
-/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light) {
+vec3 scaleSoftClipFrag(vec3 light)
+{
// For compatibility with lower cards. Do nothing.
return light;
}
-vec3 fullbrightScaleSoftClip(vec3 light) {
- return scaleSoftClip(light);
+/// Soft clips the light with a gamma correction
+vec3 scaleSoftClip(vec3 light)
+{
+ // For compatibility with lower cards. Do nothing
+ return light;
+}
+
+vec3 fullbrightScaleSoftClipFrag(vec3 light, vec3 additive, vec3 atten)
+{
+ // For compatibility with lower cards. Do nothing
+ return light;
+}
+
+vec3 fullbrightScaleSoftClip(vec3 light)
+{
+ // For compatibility with lower cards. Do nothing
+ return light;
}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl b/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
new file mode 100644
index 0000000000..24f3992e32
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
@@ -0,0 +1,64 @@
+/**
+ * @file class1\wl\moonF.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$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform vec4 color;
+uniform vec4 sunlight_color;
+uniform vec4 moonlight_color;
+uniform vec3 lumWeights;
+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;
+
+void main()
+{
+ vec4 moonA = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 moonB = texture2D(altDiffuseMap, vary_texcoord0.xy);
+ vec4 c = mix(moonA, moonB, blend_factor);
+
+ // 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);
+
+ vec3 exp = vec3(1.0 - mix * moon_brightness) * 2.0 - 1.0;
+ c.rgb = pow(c.rgb, exp);
+ //c.rgb *= moonlight_color.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
new file mode 100644
index 0000000000..8cd4b2ef47
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/moonV.glsl
@@ -0,0 +1,49 @@
+/**
+ * @file class1\wl\moonV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+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 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/class1/windlight/sunDiscF.glsl b/indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl
new file mode 100644
index 0000000000..b9ae7a0226
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl
@@ -0,0 +1,59 @@
+/**
+ * @file class1\wl\sunDiscF.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$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+vec3 fullbrightAtmosTransport(vec3 light);
+vec3 fullbrightScaleSoftClip(vec3 light);
+
+uniform sampler2D diffuseMap;
+uniform sampler2D altDiffuseMap;
+uniform float blend_factor; // interp factor between sun A/B
+VARYING vec2 vary_texcoord0;
+VARYING float sun_fade;
+
+void main()
+{
+ vec4 sunA = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 sunB = texture2D(altDiffuseMap, vary_texcoord0.xy);
+ vec4 c = mix(sunA, sunB, blend_factor);
+
+// SL-9806 stars poke through
+// c.a *= sun_fade;
+
+ c.rgb = pow(c.rgb, vec3(0.7f));
+ c.rgb = fullbrightAtmosTransport(c.rgb);
+ c.rgb = fullbrightScaleSoftClip(c.rgb);
+ frag_color = c;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/windlight/sunDiscV.glsl b/indra/newview/app_settings/shaders/class1/windlight/sunDiscV.glsl
new file mode 100644
index 0000000000..6c0e795f6b
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/sunDiscV.glsl
@@ -0,0 +1,51 @@
+/**
+ * @file class1\wl\sunDiscV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec2 vary_texcoord0;
+VARYING float sun_fade;
+
+void calcAtmospherics(vec3 eye_pos);
+
+void main()
+{
+ //transform vertex
+ vec3 offset = vec3(0, 0, 50);
+ vec4 vert = vec4(position.xyz - offset, 1.0);
+ vec4 pos = modelview_projection_matrix*vert;
+
+ sun_fade = smoothstep(0.3, 1.0, (position.z + 50) / 512.0f);
+ gl_Position = pos;
+
+ calcAtmospherics(pos.xyz);
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl
index 7c95ecdb14..a937d9fa99 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl
@@ -1,5 +1,5 @@
/**
- * @file transportF.glsl
+ * @file class1/windlight/transportF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -22,25 +22,35 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+uniform int no_atmo;
+
+vec3 atmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
+{
+ /* stub function for fallback compatibility on class1 hardware */
+ return light;
+}
vec3 atmosTransport(vec3 light)
{
/* stub function for fallback compatibility on class1 hardware */
- return light;
+ return light;
+}
+
+vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
+{
+ /* stub function for fallback compatibility on class1 hardware */
+ return light;
}
vec3 fullbrightAtmosTransport(vec3 light)
{
- /* stub function for fallback compatibility on class1 hardware */
- return light;
+ /* stub function for fallback compatibility on class1 hardware */
+ return light;
}
-
vec3 fullbrightShinyAtmosTransport(vec3 light)
{
- /* stub function for fallback compatibility on class1 hardware */
- return light;
+ /* stub function for fallback compatibility on class1 hardware */
+ return light;
}
-
diff --git a/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl b/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl
index 5af9f5c902..563c5f562b 100644
--- a/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl
+++ b/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl
@@ -37,7 +37,7 @@ VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol);
+vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor);
void calcAtmospherics(vec3 inPositionEye);
void main()
@@ -53,7 +53,7 @@ void main()
// vec4 specular = specularColor;
vec4 specular = vec4(1.0);
- vec4 color = calcLightingSpecular(pos, norm, diffuse_color, specular, vec4(0.0));
+ vec4 color = calcLightingSpecular(pos, norm, diffuse_color, specular);
vertex_color = color;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/indirect.glsl b/indra/newview/app_settings/shaders/class2/deferred/indirect.glsl
new file mode 100644
index 0000000000..67b98e0fb1
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/deferred/indirect.glsl
@@ -0,0 +1,32 @@
+/**
+ * @file class2/deferred/indirect.glsl
+ *
+ * $LicenseInfo:firstyear=2018&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$
+ */
+
+float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen);
+
+vec3 getIndirect(vec3 ambient, vec3 norm, vec4 pos, vec2 pos_screen)
+{
+ return ambient * calcAmbientOcclusion(pos, norm, pos_screen);
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
index b9bb522842..5d7a28c359 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
@@ -71,294 +71,233 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
-#endif
-
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec2 fenc = enc*4-2;
- float f = dot(fenc,fenc);
- float g = sqrt(1-f/4);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1-f/2;
- return n;
-}
-
-vec4 correctWithGamma(vec4 col)
-{
- return vec4(srgb_to_linear(col.rgb), col.a);
-}
+vec3 srgb_to_linear(vec3 cs);
+vec3 getNorm(vec2 pos_screen);
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret.rgb = srgb_to_linear(ret.rgb);
-
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret.rgb = srgb_to_linear(ret.rgb);
+ vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+
+ float det = min(lod/(proj_lod*0.5), 1.0);
+
+ float d = min(dist.x, dist.y);
d *= min(1, d * (proj_lod - lod));
-
- float edge = 0.25*det;
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
+ float edge = 0.25*det;
+
+ ret *= clamp(d/edge, 0.0, 1.0);
+
+ return ret;
}
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret = correctWithGamma(ret);
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret.rgb = srgb_to_linear(ret.rgb);
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
+ vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+
+ float det = min(lod/(proj_lod*0.5), 1.0);
+
+ float d = min(dist.x, dist.y);
+
+ float edge = 0.25*det;
+
+ ret *= clamp(d/edge, 0.0, 1.0);
+
+ return ret;
}
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret = correctWithGamma(ret);
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret.rgb = srgb_to_linear(ret.rgb);
- vec2 dist = tc-vec2(0.5);
-
- float d = dot(dist,dist);
-
- ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
-
- return ret;
+ vec2 dist = tc-vec2(0.5);
+
+ float d = dot(dist,dist);
+
+ ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
+
+ return ret;
}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
+vec4 getPosition(vec2 pos_screen);
void main()
{
- vec4 frag = vary_fragcoord;
- frag.xyz /= frag.w;
- frag.xyz = frag.xyz*0.5+0.5;
- frag.xy *= screen_res;
-
- vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = center.xyz-pos.xyz;
- float dist = length(lv);
- dist /= size;
- if (dist > 1.0)
- {
- discard;
- }
-
- float shadow = 1.0;
-
- if (proj_shadow_idx >= 0)
- {
- vec4 shd = texture2DRect(lightMap, frag.xy);
- float sh[2];
- sh[0] = shd.b;
- sh[1] = shd.a;
- shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
- }
-
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
-
- float envIntensity = norm.z;
- norm = decode_normal(norm.xy);
-
- norm = normalize(norm);
- float l_dist = -dot(lv, proj_n);
-
- vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
- if (proj_tc.z < 0.0)
- {
- discard;
- }
-
- proj_tc.xyz /= proj_tc.w;
-
- float fa = falloff+1.0;
- float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0;
- if (dist_atten <= 0.0)
- {
- discard;
- }
-
- lv = proj_origin-pos.xyz;
- lv = normalize(lv);
- float da = dot(norm, lv);
+ vec3 col = vec3(0,0,0);
- vec3 col = vec3(0,0,0);
-
- vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
+#if defined(LOCAL_LIGHT_KILL)
+ discard;
+#else
+ vec4 frag = vary_fragcoord;
+ frag.xyz /= frag.w;
+ frag.xyz = frag.xyz*0.5+0.5;
+ frag.xy *= screen_res;
+
+ vec3 pos = getPosition(frag.xy).xyz;
+ vec3 lv = center.xyz-pos.xyz;
+ float dist = length(lv);
- vec3 dlit = vec3(0, 0, 0);
+ if (dist >= size)
+ {
+ discard;
+ }
+ dist /= size;
- float noise = texture2D(noiseMap, frag.xy/128.0).b;
- if (proj_tc.z > 0.0 &&
- proj_tc.x < 1.0 &&
- proj_tc.y < 1.0 &&
- proj_tc.x > 0.0 &&
- proj_tc.y > 0.0)
- {
- float amb_da = proj_ambiance;
- float lit = 0.0;
+ float shadow = 1.0;
+
+ if (proj_shadow_idx >= 0)
+ {
+ vec4 shd = texture2DRect(lightMap, frag.xy);
+ shadow = (proj_shadow_idx==0)?shd.b:shd.a;
+ shadow += shadow_fade;
+ shadow = clamp(shadow, 0.0, 1.0);
+ }
+
+ vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
+
+ float envIntensity = norm.z;
- if (da > 0.0)
- {
- lit = da * dist_atten * noise;
+ norm = getNorm(frag.xy);
+
+ norm = normalize(norm);
+ float l_dist = -dot(lv, proj_n);
+
+ vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
+ if (proj_tc.z < 0.0)
+ {
+ discard;
+ }
+
+ proj_tc.xyz /= proj_tc.w;
+
+ float fa = falloff+1.0;
+ float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0;
+ if (dist_atten <= 0.0)
+ {
+ discard;
+ }
+
+ lv = proj_origin-pos.xyz;
+ lv = normalize(lv);
+ float da = dot(norm, lv);
+
+ vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
+ // SL-12005 Projector light pops as we get closer, more objectionable than being in wrong color space.
+ // We can't switch to linear here unless we do it everywhere*
+ // *gbuffer IS sRGB, convert to linear since this shader outputs linear
+ diff_tex.rgb = srgb_to_linear(diff_tex.rgb);
+
+ vec4 spec = texture2DRect(specularRect, frag.xy);
- float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
- float lod = diff * proj_lod;
-
- vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
-
- dlit = color.rgb * plcol.rgb * plcol.a;
-
- col = dlit*lit*diff_tex*shadow;
- amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
- }
-
- //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
- vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
-
- amb_da += (da*da*0.5+0.5)*proj_ambiance;
-
- amb_da *= dist_atten * noise;
-
- amb_da = min(amb_da, 1.0-lit);
-
- col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
- }
-
+ vec3 dlit = vec3(0, 0, 0);
- if (spec.a > 0.0)
- {
- vec3 npos = -normalize(pos);
- dlit *= min(da*6.0, 1.0) * dist_atten;
+ float noise = texture2D(noiseMap, frag.xy/128.0).b;
+ if (proj_tc.z > 0.0 &&
+ proj_tc.x < 1.0 &&
+ proj_tc.y < 1.0 &&
+ proj_tc.x > 0.0 &&
+ proj_tc.y > 0.0)
+ {
+ float amb_da = proj_ambiance;
+ float lit = 0.0;
- //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;
+ if (da > 0.0)
+ {
+ lit = da * dist_atten * noise;
- float gtdenom = 2 * nh;
- float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-
- if (nh > 0.0)
- {
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
- col += dlit*scol*spec.rgb*shadow;
- //col += spec.rgb;
- }
- }
-
-
-
-
+ float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
+ float lod = diff * proj_lod;
+
+ vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
+
+ dlit = color.rgb * plcol.rgb * plcol.a;
+
+ col = dlit*lit*diff_tex*shadow;
- if (envIntensity > 0.0)
- {
- vec3 ref = reflect(normalize(pos), norm);
-
- //project from point pos in direction ref to plane proj_p, proj_n
- vec3 pdelta = proj_p-pos;
- float ds = dot(ref, proj_n);
-
- if (ds < 0.0)
- {
- vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
-
- vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
+ // unshadowed for consistency between forward and deferred?
+ amb_da += (da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
+ }
+
+ //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
+ vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
- if (stc.z > 0.0)
- {
+ // use unshadowed for consistency between forward and deferred?
+ amb_da += (da*da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
+ amb_da *= dist_atten * noise;
+ amb_da = min(amb_da, 1.0-lit);
+
+ col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
+ }
+
+
+ if (spec.a > 0.0)
+ {
+ vec3 npos = -normalize(pos);
+ dlit *= min(da*6.0, 1.0) * dist_atten;
+
+ //vec3 ref = dot(pos+lv, norm);
+ vec3 h = normalize(lv+npos);
+ float nh = dot(norm, h);
+ float nv = dot(norm, npos);
+ float vh = dot(npos, h);
+ float sa = nh;
+ float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+
+ if (nh > 0.0)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ vec3 speccol = dlit*scol*spec.rgb*shadow;
+ speccol = clamp(speccol, vec3(0), vec3(1));
+ col += speccol;
+ }
+ }
+
+ if (envIntensity > 0.0)
+ {
+ vec3 ref = reflect(normalize(pos), norm);
+
+ //project from point pos in direction ref to plane proj_p, proj_n
+ vec3 pdelta = proj_p-pos;
+ float ds = dot(ref, proj_n);
+
+ if (ds < 0.0)
+ {
+ vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
+
+ vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
+
+ if (stc.z > 0.0)
+ {
stc /= stc.w;
-
- if (stc.x < 1.0 &&
- stc.y < 1.0 &&
- stc.x > 0.0 &&
- stc.y > 0.0)
- {
- col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
- }
- }
- }
- }
+
+ if (stc.x < 1.0 &&
+ stc.y < 1.0 &&
+ stc.x > 0.0 &&
+ stc.y > 0.0)
+ {
+ col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
+ }
+ }
+ }
+ }
+#endif
- //not sure why, but this line prevents MATBUG-194
- col = max(col, vec3(0.0));
+ //not sure why, but this line prevents MATBUG-194
+ col = max(col, vec3(0.0));
- frag_color.rgb = col;
- frag_color.a = 0.0;
+ //output linear
+ frag_color.rgb = col;
+ frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
new file mode 100644
index 0000000000..1dce85a83b
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
@@ -0,0 +1,204 @@
+/**
+ * @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$
+ */
+
+uniform mat4 modelview_projection_matrix;
+
+// SKY ////////////////////////////////////////////////////////////////////////
+// The vertex shader for creating the atmospheric sky
+///////////////////////////////////////////////////////////////////////////////
+
+// 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 float haze_horizon;
+uniform float haze_density;
+
+uniform float cloud_shadow;
+uniform float density_multiplier;
+uniform float distance_multiplier;
+uniform float max_y;
+
+uniform vec4 glow;
+uniform float sun_moon_glow_factor;
+
+uniform vec4 cloud_color;
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+
+VARYING vec3 pos;
+
+/////////////////////////////////////////////////////////////////////////
+// The fragment shader for the sky
+/////////////////////////////////////////////////////////////////////////
+
+uniform sampler2D rainbow_map;
+uniform sampler2D halo_map;
+
+uniform float moisture_level;
+uniform float droplet_radius;
+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;
+}
+
+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;
+}
+
+/// Soft clips the light with a gamma correction
+vec3 scaleSoftClip(vec3 light);
+
+void main()
+{
+
+ // World / view / projection
+ // Get relative position
+ vec3 P = pos.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);
+
+ // 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
+
+ // Add "minimum anti-solar illumination"
+ temp2.x += .25;
+
+ temp2.x *= sun_moon_glow_factor;
+
+ // Haze color above cloud
+ vec4 color = ( blue_horizon * blue_weight * (sunlight + ambient_color)
+ + (haze_horizon * haze_weight) * (sunlight * temp2.x + ambient_color)
+ );
+
+ // Final atmosphere additive
+ color *= (1. - temp1);
+
+ // 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));
+
+ // Haze color below cloud
+ vec4 additiveColorBelowCloud = (blue_horizon * blue_weight * (sunlight + tmpAmbient)
+ + (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient)
+ );
+
+
+
+ // Attenuate cloud color by atmosphere
+ temp1 = sqrt(temp1); //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.rgb += rainbow(optic_d);
+
+ color.rgb += halo_22;
+
+ color.rgb *= 2.;
+ color.rgb = scaleSoftClip(color.rgb);
+
+ /// 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
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class2/deferred/skyV.glsl
new file mode 100644
index 0000000000..bcf775577a
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/deferred/skyV.glsl
@@ -0,0 +1,42 @@
+/**
+ * @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$
+ */
+
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+
+// SKY ////////////////////////////////////////////////////////////////////////
+// The vertex shader for creating the atmospheric sky
+///////////////////////////////////////////////////////////////////////////////
+
+VARYING vec3 pos;
+
+void main()
+{
+
+ // World / view / projection
+ pos = position.xyz;
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index f7832521fa..b0dff0c628 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -1,5 +1,5 @@
/**
- * @file softenLightF.glsl
+ * @file class2/deferred/softenLightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -22,8 +22,9 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
#extension GL_ARB_texture_rectangle : enable
+#extension GL_ARB_shader_texture_lod : enable
/*[EXTRA_CODE_HERE]*/
@@ -39,456 +40,161 @@ uniform sampler2DRect normalMap;
uniform sampler2DRect lightMap;
uniform sampler2DRect depthMap;
uniform samplerCube environmentMap;
-uniform sampler2D lightFunc;
+uniform sampler2D lightFunc;
uniform float blur_size;
uniform float blur_fidelity;
// Inputs
-uniform vec4 morphFactor;
-uniform vec3 camPosLocal;
-//uniform vec4 camPosWorld;
-uniform vec4 gamma;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 ambient;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
-uniform float haze_horizon;
-uniform float haze_density;
-uniform float cloud_shadow;
-uniform float density_multiplier;
-uniform float distance_multiplier;
-uniform float max_y;
-uniform vec4 glow;
-uniform float global_gamma;
-uniform float scene_light_strength;
uniform mat3 env_mat;
-uniform vec4 shadow_clip;
-uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+uniform int sun_up_factor;
VARYING vec2 vary_fragcoord;
-vec3 vary_PositionEye;
-
-vec3 vary_SunlitColor;
-vec3 vary_AmblitColor;
-vec3 vary_AdditiveColor;
-vec3 vary_AtmosAttenuation;
-
uniform mat4 inv_proj;
uniform vec2 screen_res;
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+vec3 getNorm(vec2 pos_screen);
+vec4 getPositionWithDepth(vec2 pos_screen, float depth);
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
-#endif
+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 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec2 fenc = enc*4-2;
- float f = dot(fenc,fenc);
- float g = sqrt(1-f/4);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1-f/2;
- return n;
-}
-
-vec4 getPosition_d(vec2 pos_screen, float depth)
-{
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
-
-vec4 getPosition(vec2 pos_screen)
-{ //get position in screen space (world units) given window coordinate and depth map
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- return getPosition_d(pos_screen, depth);
-}
-
-vec3 getPositionEye()
-{
- return vary_PositionEye;
-}
-vec3 getSunlitColor()
-{
- return vary_SunlitColor;
-}
-vec3 getAmblitColor()
-{
- return vary_AmblitColor;
-}
-vec3 getAdditiveColor()
-{
- return vary_AdditiveColor;
-}
-vec3 getAtmosAttenuation()
-{
- return vary_AtmosAttenuation;
-}
-
-void setPositionEye(vec3 v)
-{
- vary_PositionEye = v;
-}
-
-void setSunlitColor(vec3 v)
-{
- vary_SunlitColor = v;
-}
-
-void setAmblitColor(vec3 v)
-{
- vary_AmblitColor = v;
-}
-
-void setAdditiveColor(vec3 v)
-{
- vary_AdditiveColor = v;
-}
-
-void setAtmosAttenuation(vec3 v)
-{
- vary_AtmosAttenuation = v;
-}
-
-void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
-
- vec3 P = inPositionEye;
- setPositionEye(P);
-
- vec3 tmpLightnorm = lightnorm.xyz;
-
- vec3 Pn = normalize(P);
- float Plen = length(P);
-
- vec4 temp1 = vec4(0);
- vec3 temp2 = vec3(0);
- vec4 blue_weight;
- vec4 haze_weight;
- vec4 sunlight = sunlight_color;
- vec4 light_atten;
-
- //sunlight attenuation effect (hue and brightness) due to atmosphere
- //this is used later for sunlight modulation at various altitudes
- light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
- //I had thought blue_density and haze_density should have equal weighting,
- //but attenuation due to haze_density tends to seem too strong
-
- temp1 = blue_density + vec4(haze_density);
- blue_weight = blue_density / temp1;
- haze_weight = vec4(haze_density) / temp1;
-
- //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
- temp2.y = max(0.0, tmpLightnorm.y);
- temp2.y = 1. / temp2.y;
- sunlight *= exp( - light_atten * temp2.y);
-
- // main atmospheric scattering line integral
- temp2.z = Plen * density_multiplier;
-
- // Transparency (-> temp1)
- // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
- // compiler gets confused.
- temp1 = exp(-temp1 * temp2.z * distance_multiplier);
-
- //final atmosphere attenuation factor
- setAtmosAttenuation(temp1.rgb);
-
- //compute haze glow
- //(can use temp2.x as temp because we haven't used it yet)
- temp2.x = dot(Pn, tmpLightnorm.xyz);
- temp2.x = 1. - temp2.x;
- //temp2.x is 0 at the sun and increases away from sun
- temp2.x = max(temp2.x, .03); //was glow.y
- //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- temp2.x *= glow.x;
- //higher glow.x gives dimmer glow (because next step is 1 / "angle")
- temp2.x = pow(temp2.x, glow.z);
- //glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- //add "minimum anti-solar illumination"
- temp2.x += .25;
-
- //increase ambient when there are more clouds
- vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
-
- /* decrease value and saturation (that in HSV, not HSL) for occluded areas
- * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
- * // The following line of code performs the equivalent of:
- * float ambAlpha = tmpAmbient.a;
- * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
- * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
- * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
- */
- tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
-
- //haze color
- setAdditiveColor(
- vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
- + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
- + tmpAmbient)));
-
- //brightness of surface both sunlight and ambient
- /*setSunlitColor(pow(vec3(sunlight * .5), vec3(global_gamma)) * global_gamma);
- setAmblitColor(pow(vec3(tmpAmbient * .25), vec3(global_gamma)) * global_gamma);
- setAdditiveColor(pow(getAdditiveColor() * vec3(1.0 - temp1), vec3(global_gamma)) * global_gamma);*/
-
- setSunlitColor(vec3(sunlight * .5));
- setAmblitColor(vec3(tmpAmbient * .25));
- setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
-}
+vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
#ifdef WATER_FOG
-uniform vec4 waterPlane;
-uniform vec4 waterFogColor;
-uniform float waterFogDensity;
-uniform float waterFogKS;
-
-vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
-{
- //normalize view vector
- vec3 view = normalize(pos);
- float es = -(dot(view, waterPlane.xyz));
-
- //find intersection point with water plane and eye vector
-
- //get eye depth
- float e0 = max(-waterPlane.w, 0.0);
-
- vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
-
- //get object depth
- float depth = length(pos - int_v);
-
- //get "thickness" of water
- float l = max(depth, 0.1);
-
- float kd = waterFogDensity;
- float ks = waterFogKS;
- vec4 kc = waterFogColor;
-
- float F = 0.98;
-
- float t1 = -kd * pow(F, ks * e0);
- float t2 = kd + ks * es;
- float t3 = pow(F, t2*l) - 1.0;
-
- float L = min(t1/t2*t3, 1.0);
-
- float D = pow(0.98, l*kd);
-
- color.rgb = color.rgb * D + kc.rgb * L;
- color.a = kc.a + color.a;
-
- return color;
-}
+vec4 applyWaterFogView(vec3 pos, vec4 color);
#endif
-vec3 atmosLighting(vec3 light)
-{
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor();
- return (2.0 * light);
-}
-
-vec3 atmosTransport(vec3 light) {
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor() * 2.0;
- return light;
-}
-
-vec3 fullbrightAtmosTransport(vec3 light) {
- float brightness = dot(light.rgb, vec3(0.33333));
-
- return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
-}
-
-
-
-vec3 atmosGetDiffuseSunlightColor()
-{
- return getSunlitColor();
-}
-
-vec3 scaleDownLight(vec3 light)
-{
- return (light / scene_light_strength );
-}
-
-vec3 scaleUpLight(vec3 light)
-{
- return (light * scene_light_strength);
-}
-
-vec3 atmosAmbient(vec3 light)
-{
- return getAmblitColor() + light / 2.0;
-}
-
-vec3 atmosAffectDirectionalLight(float lightIntensity)
-{
- return getSunlitColor() * lightIntensity;
-}
-
-vec3 scaleSoftClip(vec3 light)
-{
- //soft clip effect:
- light = 1. - clamp(light, vec3(0.), vec3(1.));
- light = 1. - pow(light, gamma.xxx);
-
- return light;
-}
-
-
-vec3 fullbrightScaleSoftClip(vec3 light)
-{
- //soft clip effect:
- return light;
-}
-
void main()
{
- vec2 tc = vary_fragcoord.xy;
- float depth = texture2DRect(depthMap, tc.xy).r;
- vec3 pos = getPosition_d(tc, depth).xyz;
- vec4 norm = texture2DRect(normalMap, tc);
- float envIntensity = norm.z;
- norm.xyz = decode_normal(norm.xy); // unpack norm
-
- float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
+ 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);
+
+ vec4 diffuse = texture2DRect(diffuseRect, tc);
+
+ vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
- float light_gamma = 1.0/1.3;
- da = pow(da, light_gamma);
+ vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
+ scol_ambocc = pow(scol_ambocc, vec2(light_gamma));
+ float scol = max(scol_ambocc.r, diffuse.a);
- vec4 diffuse = texture2DRect(diffuseRect, tc);
+ float ambocc = scol_ambocc.g;
- //convert to gamma space
- diffuse.rgb = linear_to_srgb(diffuse.rgb);
-
- vec3 col;
- float bloom = 0.0;
- {
- vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
-
- vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
- scol_ambocc = pow(scol_ambocc, vec2(light_gamma));
+ vec3 color = vec3(0);
+ float bloom = 0.0;
+ {
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+
+ calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, true);
- float scol = max(scol_ambocc.r, diffuse.a);
+ color.rgb = amblit;
-
+ float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
+ ambient *= 0.5;
+ ambient *= ambient;
+ ambient = (1.0 - ambient);
- float ambocc = scol_ambocc.g;
-
- calcAtmospherics(pos.xyz, ambocc);
-
- col = atmosAmbient(vec3(0));
- float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0-ambient);
+ color.rgb *= ambient;
- col.rgb *= ambient;
+ vec3 sun_contrib = min(da, scol) * sunlit;
- col += atmosAffectDirectionalLight(max(min(da, scol), 0.0));
-
- col *= diffuse.rgb;
-
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+ color.rgb += sun_contrib;
- if (spec.a > 0.0) // specular reflection
- {
- // the old infinite-sky shiny reflection
- //
-
- float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(texture2D(lightFunc, vec2(sa, spec.a)).r);
-
- // add the two types of shiny together
- vec3 spec_contrib = dumbshiny * spec.rgb;
- bloom = dot(spec_contrib, spec_contrib) / 6;
- col += spec_contrib;
- }
-
-
- col = mix(col, diffuse.rgb, diffuse.a);
+ color.rgb *= diffuse.rgb;
- if (envIntensity > 0.0)
- { //add environmentmap
- vec3 env_vec = env_mat * refnormpersp;
-
- vec3 refcol = textureCube(environmentMap, env_vec).rgb;
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
- col = mix(col.rgb, refcol,
- envIntensity);
+ if (spec.a > 0.0) // specular reflection
+ {
- }
-
- if (norm.w < 0.5)
- {
- col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
- col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
- }
+#if 1 //EEP
+ vec3 npos = -normalize(pos.xyz);
- #ifdef WATER_FOG
- vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom));
- col = fogged.rgb;
- bloom = fogged.a;
- #endif
+ //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;
- col = srgb_to_linear(col);
+ 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
- //col = vec3(1,0,1);
- //col.g = envIntensity;
- }
-
- frag_color.rgb = col;
- frag_color.a = bloom;
+ }
+
+ 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
+
+ }
+
+// linear debuggables
+//color.rgb = vec3(final_da);
+//color.rgb = vec3(ambient);
+//color.rgb = vec3(scol);
+//color.rgb = diffuse_srgb.rgb;
+
+ // 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;
}
+
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl
index c840d72784..8b8b338f68 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl
@@ -36,7 +36,5 @@ void main()
//transform vertex
vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
gl_Position = pos;
-
-
vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
index 81af1fdc8a..5ab0b5c5b4 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
@@ -71,70 +71,14 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec2 fenc = enc*4-2;
- float f = dot(fenc,fenc);
- float g = sqrt(1-f/4);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1-f/2;
- return n;
-}
-
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
-#endif
-
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
-
-vec4 correctWithGamma(vec4 col)
-{
- return vec4(srgb_to_linear(col.rgb), col.a);
-}
+vec3 getNorm(vec2 pos_screen);
+vec3 srgb_to_linear(vec3 c);
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret.rgb = srgb_to_linear(ret.rgb);
-
+
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
float det = min(lod/(proj_lod*0.5), 1.0);
@@ -153,7 +97,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret = correctWithGamma(ret);
+ ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
@@ -171,7 +115,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret = correctWithGamma(ret);
+ ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = tc-vec2(0.5);
@@ -182,22 +126,15 @@ vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
return ret;
}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
+vec4 getPosition(vec2 pos_screen);
void main()
{
+ vec3 col = vec3(0,0,0);
+
+#if defined(LOCAL_LIGHT_KILL)
+ discard;
+#else
vec4 frag = vary_fragcoord;
frag.xyz /= frag.w;
frag.xyz = frag.xyz*0.5+0.5;
@@ -206,26 +143,26 @@ void main()
vec3 pos = getPosition(frag.xy).xyz;
vec3 lv = trans_center.xyz-pos.xyz;
float dist = length(lv);
+
+ if (dist >= size)
+ {
+ discard;
+ }
dist /= size;
- if (dist > 1.0)
- {
- discard;
- }
-
+
float shadow = 1.0;
if (proj_shadow_idx >= 0)
{
vec4 shd = texture2DRect(lightMap, frag.xy);
- float sh[2];
- sh[0] = shd.b;
- sh[1] = shd.a;
- shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
+ shadow = (proj_shadow_idx == 0) ? shd.b : shd.a;
+ shadow += shadow_fade;
+ shadow = clamp(shadow, 0.0, 1.0);
}
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
float envIntensity = norm.z;
- norm = decode_normal(norm.xy);
+ norm = getNorm(frag.xy);
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
@@ -252,12 +189,8 @@ void main()
lv = normalize(lv);
float da = dot(norm, lv);
- vec3 col = vec3(0,0,0);
-
- vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
-
+ vec3 diff_tex = srgb_to_linear(texture2DRect(diffuseRect, frag.xy).rgb);
vec4 spec = texture2DRect(specularRect, frag.xy);
-
vec3 dlit = vec3(0, 0, 0);
float noise = texture2D(noiseMap, frag.xy/128.0).b;
@@ -280,23 +213,21 @@ void main()
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
dlit = color.rgb * plcol.rgb * plcol.a;
-
+
col = dlit*lit*diff_tex*shadow;
- amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
+
+ amb_da += (da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
}
//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
- amb_da += (da*da*0.5+0.5)*proj_ambiance;
-
+ amb_da += (da*da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
amb_da *= dist_atten * noise;
-
amb_da = min(amb_da, 1.0-lit);
-
- col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
- }
+ col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
+ }
if (spec.a > 0.0)
{
@@ -317,14 +248,11 @@ void main()
if (nh > 0.0)
{
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
- col += dlit*scol*spec.rgb*shadow;
- //col += spec.rgb;
+ vec3 speccol = dlit*scol*spec.rgb*shadow;
+ speccol = clamp(speccol, vec3(0), vec3(1));
+ col += speccol;
}
}
-
-
-
-
if (envIntensity > 0.0)
{
@@ -354,10 +282,12 @@ void main()
}
}
}
+#endif
//not sure why, but this line prevents MATBUG-194
col = max(col, vec3(0.0));
+ //output linear colors as gamma correction happens down stream
frag_color.rgb = col;
frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
index 265da8df99..8abdeae5ae 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
@@ -35,228 +35,26 @@ out vec4 frag_color;
//class 2, shadows, no SSAO
-uniform sampler2DRect depthMap;
-uniform sampler2DRect normalMap;
-uniform sampler2DShadow shadowMap0;
-uniform sampler2DShadow shadowMap1;
-uniform sampler2DShadow shadowMap2;
-uniform sampler2DShadow shadowMap3;
-uniform sampler2DShadow shadowMap4;
-uniform sampler2DShadow shadowMap5;
-
-
// Inputs
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-uniform float ssao_radius;
-uniform float ssao_max_radius;
-uniform float ssao_factor;
-uniform float ssao_factor_inv;
-
VARYING vec2 vary_fragcoord;
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-uniform vec2 proj_shadow_res;
uniform vec3 sun_dir;
-
-uniform vec2 shadow_res;
uniform float shadow_bias;
-uniform float shadow_offset;
-uniform float spot_shadow_bias;
-uniform float spot_shadow_offset;
+vec3 getNorm(vec2 pos_screen);
+vec4 getPosition(vec2 pos_screen);
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec2 fenc = enc*4-2;
- float f = dot(fenc,fenc);
- float g = sqrt(1-f/4);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1-f/2;
- return n;
-}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
-
-float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
-{
- stc.xyz /= stc.w;
- stc.z += shadow_bias;
-
- stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*0.666666666))/shadow_res.x; // add some jitter to X sample pos according to Y to disguise the snapping going on here
- float cs = shadow2D(shadowMap, stc.xyz).x;
-
- float shadow = cs;
-
- shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
-
-
- return shadow*0.2;
-}
-
-float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
-{
- stc.xyz /= stc.w;
- stc.z += spot_shadow_bias*scl;
- stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap
-
- float cs = shadow2D(shadowMap, stc.xyz).x;
- float shadow = cs;
-
- vec2 off = 1.0/proj_shadow_res;
- off.y *= 1.5;
-
- shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x;
-
- return shadow*0.2;
-}
+float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
+float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen);
void main()
{
- vec2 pos_screen = vary_fragcoord.xy;
-
- //try doing an unproject here
-
- vec4 pos = getPosition(pos_screen);
-
- vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
- norm = decode_normal(norm.xy); // unpack norm
-
- /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL
- {
- frag_color = vec4(0.0); // doesn't matter
- return;
- }*/
-
- float shadow = 0.0;
- float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));
-
- vec3 shadow_pos = pos.xyz;
- vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
-
- vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
-
- if (spos.z > -shadow_clip.w)
- {
- if (dp_directional_light == 0.0)
- {
- // if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup
- shadow = 0.0;
- }
- else
- {
- vec4 lpos;
-
- vec4 near_split = shadow_clip*-0.75;
- vec4 far_split = shadow_clip*-1.25;
- vec4 transition_domain = near_split-far_split;
- float weight = 0.0;
+ vec2 pos_screen = vary_fragcoord.xy;
+ vec4 pos = getPosition(pos_screen);
+ vec3 norm = getNorm(pos_screen);
- if (spos.z < near_split.z)
- {
- lpos = shadow_matrix[3]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w;
- weight += w;
- shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
- }
-
- if (spos.z < near_split.y && spos.z > far_split.z)
- {
- lpos = shadow_matrix[2]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
- w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap2, lpos, 0.5, pos_screen)*w;
- weight += w;
- }
-
- if (spos.z < near_split.x && spos.z > far_split.y)
- {
- lpos = shadow_matrix[1]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
- w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
- shadow += pcfShadow(shadowMap1, lpos, 0.75, pos_screen)*w;
- weight += w;
- }
-
- if (spos.z > far_split.x)
- {
- lpos = shadow_matrix[0]*spos;
-
- float w = 1.0;
- w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
-
- shadow += pcfShadow(shadowMap0, lpos, 1.0, pos_screen)*w;
- weight += w;
- }
-
-
- shadow /= weight;
-
- // take the most-shadowed value out of these two:
- // * the blurred sun shadow in the light (shadow) map
- // * an unblurred dot product between the sun and this norm
- // the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting
- shadow = min(shadow, dp_directional_light);
-
- //lpos.xy /= lpos.w*32.0;
- //if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1)
- //{
- // shadow = 0.0;
- //}
-
- }
- }
- else
- {
- // more distant than the shadow map covers
- shadow = 1.0;
- }
-
- frag_color[0] = shadow;
- frag_color[1] = 1.0;
-
- spos = vec4(shadow_pos+norm*spot_shadow_offset, 1.0);
-
- //spotlight shadow 1
- vec4 lpos = shadow_matrix[4]*spos;
- frag_color[2] = pcfSpotShadow(shadowMap4, lpos, 0.8, pos_screen);
-
- //spotlight shadow 2
- lpos = shadow_matrix[5]*spos;
- frag_color[3] = pcfSpotShadow(shadowMap5, lpos, 0.8, pos_screen);
-
- //frag_color.rgb = pos.xyz;
- //frag_color.b = shadow;
+ frag_color.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen);
+ frag_color.g = 1.0f;
+ frag_color.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen);
+ frag_color.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen);
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
index 5c6fe30daa..64d99bae2c 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
@@ -1,5 +1,5 @@
/**
- * @file sunLightSSAOF.glsl
+ * @file class2/deferred/sunLightSSAOF.glsl
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
@@ -34,290 +34,24 @@ out vec4 frag_color;
//class 2 -- shadows and SSAO
-uniform sampler2DRect depthMap;
-uniform sampler2DRect normalMap;
-uniform sampler2DShadow shadowMap0;
-uniform sampler2DShadow shadowMap1;
-uniform sampler2DShadow shadowMap2;
-uniform sampler2DShadow shadowMap3;
-uniform sampler2DShadow shadowMap4;
-uniform sampler2DShadow shadowMap5;
-uniform sampler2D noiseMap;
-
-
// Inputs
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-uniform float ssao_radius;
-uniform float ssao_max_radius;
-uniform float ssao_factor;
-uniform float ssao_factor_inv;
-
VARYING vec2 vary_fragcoord;
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-uniform vec2 proj_shadow_res;
-uniform vec3 sun_dir;
+vec4 getPosition(vec2 pos_screen);
+vec3 getNorm(vec2 pos_screen);
-uniform vec2 shadow_res;
-
-uniform float shadow_bias;
-uniform float shadow_offset;
-
-uniform float spot_shadow_bias;
-uniform float spot_shadow_offset;
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec2 fenc = enc*4-2;
- float f = dot(fenc,fenc);
- float g = sqrt(1-f/4);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1-f/2;
- return n;
-}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
-
-vec2 getKern(int i)
-{
- vec2 kern[8];
- // exponentially (^2) distant occlusion samples spread around origin
- kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
- kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
- kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
- kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
- kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
- kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
- kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
- kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
-
- return kern[i];
-}
-
-//calculate decreases in ambient lighting when crowded out (SSAO)
-float calcAmbientOcclusion(vec4 pos, vec3 norm)
-{
- float ret = 1.0;
-
- vec2 pos_screen = vary_fragcoord.xy;
- vec3 pos_world = pos.xyz;
- vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy;
-
- float angle_hidden = 0.0;
- float points = 0;
-
- float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
-
- // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?)
- for (int i = 0; i < 8; i++)
- {
- vec2 samppos_screen = pos_screen + scale * reflect(getKern(i), noise_reflect);
- vec3 samppos_world = getPosition(samppos_screen).xyz;
-
- vec3 diff = pos_world - samppos_world;
- float dist2 = dot(diff, diff);
-
- // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
- // --> solid angle shrinking by the square of distance
- //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
- //(k should vary inversely with # of samples, but this is taken care of later)
-
- float funky_val = (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) ? 1.0 : 0.0;
- angle_hidden = angle_hidden + funky_val * min(1.0/dist2, ssao_factor_inv);
-
- // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
- float diffz_val = (diff.z > -1.0) ? 1.0 : 0.0;
- points = points + diffz_val;
- }
-
- angle_hidden = min(ssao_factor*angle_hidden/points, 1.0);
-
- float points_val = (points > 0.0) ? 1.0 : 0.0;
- ret = (1.0 - (points_val * angle_hidden));
-
- ret = max(ret, 0.0);
- return min(ret, 1.0);
-}
-
-float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
-{
- stc.xyz /= stc.w;
- stc.z += shadow_bias;
-
- stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*0.666666666))/shadow_res.x;
- float cs = shadow2D(shadowMap, stc.xyz).x;
-
- float shadow = cs;
-
- shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
-
- return shadow*0.2;
-}
-
-float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
-{
- stc.xyz /= stc.w;
- stc.z += spot_shadow_bias*scl;
- stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap
-
- float cs = shadow2D(shadowMap, stc.xyz).x;
- float shadow = cs;
-
- vec2 off = 1.0/proj_shadow_res;
- off.y *= 1.5;
-
- shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x;
-
- return shadow*0.2;
-}
+float sampleDirectionalShadow(vec3 shadow_pos, vec3 norm, vec2 pos_screen);
+float sampleSpotShadow(vec3 shadow_pos, vec3 norm, int index, vec2 pos_screen);
+float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen);
void main()
{
- vec2 pos_screen = vary_fragcoord.xy;
-
- //try doing an unproject here
-
- vec4 pos = getPosition(pos_screen);
-
- vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
- norm = decode_normal(norm.xy); // unpack norm
-
- /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL
- {
- frag_color = vec4(0.0); // doesn't matter
- return;
- }*/
-
- float shadow = 0.0;
- float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));
-
- vec3 shadow_pos = pos.xyz;
- vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
-
- vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
-
- if (spos.z > -shadow_clip.w)
- {
- if (dp_directional_light == 0.0)
- {
- // if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup
- shadow = 0.0;
- }
- else
- {
- vec4 lpos;
+ vec2 pos_screen = vary_fragcoord.xy;
+ vec4 pos = getPosition(pos_screen);
+ vec3 norm = getNorm(pos_screen);
- vec4 near_split = shadow_clip*-0.75;
- vec4 far_split = shadow_clip*-1.25;
- vec4 transition_domain = near_split-far_split;
- float weight = 0.0;
-
- if (spos.z < near_split.z)
- {
- lpos = shadow_matrix[3]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w;
- weight += w;
- shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
- }
-
- if (spos.z < near_split.y && spos.z > far_split.z)
- {
- lpos = shadow_matrix[2]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
- w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap2, lpos, 0.5, pos_screen)*w;
- weight += w;
- }
-
- if (spos.z < near_split.x && spos.z > far_split.y)
- {
- lpos = shadow_matrix[1]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
- w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
- shadow += pcfShadow(shadowMap1, lpos, 0.75, pos_screen)*w;
- weight += w;
- }
-
- if (spos.z > far_split.x)
- {
- lpos = shadow_matrix[0]*spos;
-
- float w = 1.0;
- w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
-
- shadow += pcfShadow(shadowMap0, lpos, 1.0, pos_screen)*w;
- weight += w;
- }
-
-
- shadow /= weight;
-
- // take the most-shadowed value out of these two:
- // * the blurred sun shadow in the light (shadow) map
- // * an unblurred dot product between the sun and this norm
- // the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting
- shadow = min(shadow, dp_directional_light);
-
- //lpos.xy /= lpos.w*32.0;
- //if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1)
- //{
- // shadow = 0.0;
- //}
-
- }
- }
- else
- {
- // more distant than the shadow map covers
- shadow = 1.0;
- }
-
- frag_color[0] = shadow;
- frag_color[1] = calcAmbientOcclusion(pos, norm);
-
- spos = vec4(shadow_pos+norm*spot_shadow_offset, 1.0);
-
- //spotlight shadow 1
- vec4 lpos = shadow_matrix[4]*spos;
- frag_color[2] = pcfSpotShadow(shadowMap4, lpos, 0.8, pos_screen);
-
- //spotlight shadow 2
- lpos = shadow_matrix[5]*spos;
- frag_color[3] = pcfSpotShadow(shadowMap5, lpos, 0.8, pos_screen);
-
- //frag_color.rgb = pos.xyz;
- //frag_color.b = shadow;
+ frag_color.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen);
+ frag_color.g = calcAmbientOcclusion(pos, norm, pos_screen);
+ frag_color.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen);
+ frag_color.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen);
}
diff --git a/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl
index 3acf9fe883..89d9d1bde3 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl
+++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl
@@ -1,5 +1,5 @@
/**
- * @file sumLightsV.glsl
+ * @file class2\lighting\sumLightsSpecularV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -28,16 +28,16 @@
float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da);
vec3 calcPointLightSpecular(inout vec4 specular, vec3 view, vec3 v, vec3 n, vec3 l, float r, float pw, vec3 lightCol);
-vec3 atmosAmbient(vec3 light);
+vec3 atmosAmbient();
vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 atmosGetDiffuseSunlightColor();
vec3 scaleDownLight(vec3 light);
uniform vec4 light_position[8];
-uniform vec3 light_attenuation[8];
+uniform vec4 light_attenuation[8];
uniform vec3 light_diffuse[8];
-vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol)
+vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor)
{
vec4 col = vec4(0.0, 0.0, 0.0, color.a);
@@ -53,8 +53,8 @@ vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor
col.rgb = scaleDownLight(col.rgb);
// Add windlight lights
- col.rgb += atmosAmbient(baseCol.rgb);
- col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, light_position[0].xyz,atmosGetDiffuseSunlightColor()*baseCol.a, 1.0));
+ col.rgb += atmosAmbient();
+ col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, light_position[0].xyz, atmosGetDiffuseSunlightColor(), 1.0));
col.rgb = min(col.rgb*color.rgb, 1.0);
specularColor.rgb = min(specularColor.rgb*specularSum.rgb, 1.0);
diff --git a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
index c9987ef3b9..30ca88afd2 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
@@ -1,5 +1,5 @@
/**
- * @file sumLightsV.glsl
+ * @file class2\lighting\sumLightsV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -24,9 +24,8 @@
*/
float calcDirectionalLight(vec3 n, vec3 l);
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight);
-vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 scaleDownLight(vec3 light);
@@ -35,24 +34,27 @@ uniform vec3 light_direction[8];
uniform vec3 light_attenuation[8];
uniform vec3 light_diffuse[8];
-vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight)
+vec4 sumLights(vec3 pos, vec3 norm, vec4 color)
{
vec4 col = vec4(0.0, 0.0, 0.0, color.a);
// Collect normal lights (need to be divided by two, as we later multiply by 2)
col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
-
- col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
- col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
-
+ col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
+ col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
col.rgb = scaleDownLight(col.rgb);
+#if defined(LOCAL_LIGHT_KILL)
+ col.rgb = vec3(0);
+i#endif
+
// Add windlight lights
- col.rgb += atmosAmbient(baseLight.rgb);
col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, light_position[0].xyz));
-
+
+#if !defined(SUNLIGHT_KILL)
col.rgb = min(col.rgb*color.rgb, 1.0);
-
+#endif
+
return col;
}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
index fea3cbf69b..ee9c990b12 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericsF.glsl
+ * @file class2\wl\atmosphericsF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -22,23 +22,25 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-
-
-//////////////////////////////////////////////////////////
-// The fragment shader for the terrain atmospherics
-//////////////////////////////////////////////////////////
vec3 getAdditiveColor();
vec3 getAtmosAttenuation();
+vec3 scaleSoftClipFrag(vec3 light);
-uniform sampler2D cloudMap;
-uniform vec4 cloud_pos_density1;
+uniform int no_atmo;
+
+vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
+{
+ if (no_atmo == 1)
+ {
+ return light;
+ }
+ light *= atten.r;
+ light += additive;
+ return light * 2.0;
+}
vec3 atmosLighting(vec3 light)
{
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor();
- return (2.0 * light);
+ return atmosFragLighting(light, getAdditiveColor(), getAtmosAttenuation());
}
-
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersF.glsl
new file mode 100644
index 0000000000..5788871744
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersF.glsl
@@ -0,0 +1,46 @@
+/**
+ * @file class2\wl\atmosphericsHelpersV.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$
+ */
+
+// Output variables
+
+uniform float scene_light_strength;
+uniform int no_atmo;
+
+vec3 atmosFragAmbient(vec3 light, vec3 amblit)
+{
+ if (no_atmo == 1) return light;
+ return amblit + light / 2.0;
+}
+
+vec3 atmosFragAffectDirectionalLight(float lightIntensity, vec3 sunlit)
+{
+ return sunlit * lightIntensity;
+}
+
+vec3 scaleDownLightFrag(vec3 light)
+{
+ return (light / scene_light_strength );
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl
index 62a034ce05..9c42b84eca 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericsHelpersV.glsl
+ * @file class2\wl\atmosphericsHelpersV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -33,29 +33,31 @@ vec3 getAtmosAttenuation();
vec3 getPositionEye();
uniform float scene_light_strength;
+uniform int no_atmo;
-vec3 atmosAmbient(vec3 light)
+vec3 atmosAmbient()
{
- return getAmblitColor() + light / 2.0;
+ if (no_atmo == 1) return vec3(0.16);
+ return getAmblitColor();
}
vec3 atmosAffectDirectionalLight(float lightIntensity)
{
- return getSunlitColor() * lightIntensity;
+ return getSunlitColor() * lightIntensity;
}
vec3 atmosGetDiffuseSunlightColor()
{
- return getSunlitColor();
+ return getSunlitColor();
}
vec3 scaleDownLight(vec3 light)
{
- return (light / scene_light_strength );
+ return (light / scene_light_strength );
}
vec3 scaleUpLight(vec3 light)
{
- return (light * scene_light_strength);
+ return (light * scene_light_strength);
}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
index d174805cc0..4c418e414f 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericsV.glsl
+ * @file class2\wl\atmosphericsV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -22,10 +22,14 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-
// VARYING param funcs
+
+
+uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+uniform int sun_up_factor;
+
void setSunlitColor(vec3 v);
void setAmblitColor(vec3 v);
void setAdditiveColor(vec3 v);
@@ -34,124 +38,19 @@ void setPositionEye(vec3 v);
vec3 getAdditiveColor();
-//VARYING vec4 vary_CloudUVs;
-//VARYING float vary_CloudDensity;
-
-// Inputs
-uniform vec4 morphFactor;
-uniform vec3 camPosLocal;
-//uniform vec4 camPosWorld;
-
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 ambient;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
-uniform float haze_horizon;
-uniform float haze_density;
-uniform float cloud_shadow;
-uniform float density_multiplier;
-uniform float distance_multiplier;
-uniform float max_y;
-uniform vec4 glow;
+void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
void calcAtmospherics(vec3 inPositionEye) {
-
- vec3 P = inPositionEye;
- setPositionEye(P);
-
- //(TERRAIN) limit altitude
- if (P.y > max_y) P *= (max_y / P.y);
- if (P.y < -max_y) P *= (-max_y / P.y);
-
- vec3 tmpLightnorm = lightnorm.xyz;
-
- vec3 Pn = normalize(P);
- float Plen = length(P);
-
- vec4 temp1 = vec4(0);
- vec3 temp2 = vec3(0);
- vec4 blue_weight;
- vec4 haze_weight;
- vec4 sunlight = sunlight_color;
- vec4 light_atten;
-
- //sunlight attenuation effect (hue and brightness) due to atmosphere
- //this is used later for sunlight modulation at various altitudes
- light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
- //I had thought blue_density and haze_density should have equal weighting,
- //but attenuation due to haze_density tends to seem too strong
-
- temp1 = blue_density + vec4(haze_density);
- blue_weight = blue_density / temp1;
- haze_weight = vec4(haze_density) / temp1;
-
- //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
- temp2.y = max(0.0, tmpLightnorm.y);
- temp2.y = 1. / temp2.y;
- sunlight *= exp( - light_atten * temp2.y);
-
- // main atmospheric scattering line integral
- temp2.z = Plen * density_multiplier;
-
- // Transparency (-> temp1)
- // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
- // compiler gets confused.
- temp1 = exp(-temp1 * temp2.z * distance_multiplier);
-
- //final atmosphere attenuation factor
- setAtmosAttenuation(temp1.rgb);
- //vary_AtmosAttenuation = distance_multiplier / 10000.;
- //vary_AtmosAttenuation = density_multiplier * 100.;
- //vary_AtmosAttenuation = vec4(Plen / 100000., 0., 0., 1.);
-
- //compute haze glow
- //(can use temp2.x as temp because we haven't used it yet)
- temp2.x = dot(Pn, tmpLightnorm.xyz);
- temp2.x = 1. - temp2.x;
- //temp2.x is 0 at the sun and increases away from sun
- temp2.x = max(temp2.x, .03); //was glow.y
- //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- temp2.x *= glow.x;
- //higher glow.x gives dimmer glow (because next step is 1 / "angle")
- temp2.x = pow(temp2.x, glow.z);
- //glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- //add "minimum anti-solar illumination"
- temp2.x += .25;
-
-
- //increase ambient when there are more clouds
- vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
-
- //haze color
- setAdditiveColor(
- vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
- + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
- + tmpAmbient)));
-
- //brightness of surface both sunlight and ambient
- setSunlitColor(vec3(sunlight * .5));
- setAmblitColor(vec3(tmpAmbient * .25));
- setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
-
- // vary_SunlitColor = vec3(0);
- // vary_AmblitColor = vec3(0);
- // vary_AdditiveColor = vec4(Pn, 1.0);
-
- /*
- const float cloudShadowScale = 100.;
- // Get cloud uvs for shadowing
- vec3 cloudPos = inPositionEye + camPosWorld - cloudShadowScale / 2.;
- vary_CloudUVs.xy = cloudPos.xz / cloudShadowScale;
-
- // We can take uv1 and multiply it by (TerrainSpan / CloudSpan)
-// cloudUVs *= (((worldMaxZ - worldMinZ) * 20) /40000.);
- vary_CloudUVs *= (10000./40000.);
-
- // Offset by sun vector * (CloudAltitude / CloudSpan)
- vary_CloudUVs.x += tmpLightnorm.x / tmpLightnorm.y * (3000./40000.);
- vary_CloudUVs.y += tmpLightnorm.z / tmpLightnorm.y * (3000./40000.);
- */
+ vec3 P = inPositionEye;
+ setPositionEye(P);
+ vec3 tmpsunlit = vec3(1);
+ vec3 tmpamblit = vec3(1);
+ vec3 tmpaddlit = vec3(1);
+ vec3 tmpattenlit = vec3(1);
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
+ calcAtmosphericVars(inPositionEye, light_dir, 1, tmpsunlit, tmpamblit, tmpaddlit, tmpattenlit, false);
+ setSunlitColor(tmpsunlit);
+ setAmblitColor(tmpamblit);
+ setAdditiveColor(tmpaddlit);
+ setAtmosAttenuation(tmpattenlit);
}
-
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl
index 765b0927c3..ea37610502 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericVars.glsl
+ * @file class2\wl\atmosphericVars.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -32,14 +32,17 @@ vec3 getSunlitColor()
{
return vec3(0,0,0);
}
+
vec3 getAmblitColor()
{
return vec3(0,0,0);
}
+
vec3 getAdditiveColor()
{
return vary_AdditiveColor;
}
+
vec3 getAtmosAttenuation()
{
return vec3(vary_AtmosAttenuation);
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl
index 99dbee15ee..31109aed31 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericVars.glsl
+ * @file class2\wl\atmosphericVars.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl
index 163ef26444..22e16b7e0f 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericVarsWaterF.glsl
+ * @file class2\wl\atmosphericVarsWaterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl
index 553f6752e6..0f2a3ee527 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericVarsWaterV.glsl
+ * @file class2\wl\atmosphericVarsWaterV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
index 96c70651b1..75bf8730df 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
@@ -1,5 +1,5 @@
/**
- * @file WLCloudsF.glsl
+ * @file class2\wl\cloudsF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -22,11 +22,13 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
+out vec4 frag_data[3];
#else
-#define frag_color gl_FragColor
+#define frag_data gl_FragData
#endif
/////////////////////////////////////////////////////////////////////////
@@ -36,69 +38,96 @@ out vec4 frag_color;
VARYING vec4 vary_CloudColorSun;
VARYING vec4 vary_CloudColorAmbient;
VARYING float vary_CloudDensity;
+
+uniform sampler2D cloud_noise_texture;
+uniform sampler2D cloud_noise_texture_next;
+uniform float blend_factor;
+uniform vec4 cloud_pos_density1;
+uniform vec4 cloud_pos_density2;
+uniform float cloud_scale;
+uniform float cloud_variance;
+
VARYING vec2 vary_texcoord0;
VARYING vec2 vary_texcoord1;
VARYING vec2 vary_texcoord2;
VARYING vec2 vary_texcoord3;
-
-uniform sampler2D cloud_noise_texture;
-uniform vec4 cloud_pos_density1;
-uniform vec4 cloud_pos_density2;
-uniform vec4 gamma;
+VARYING float altitude_blend_factor;
/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light) {
- //soft clip effect:
- light = 1. - clamp(light, vec3(0.), vec3(1.));
- light = 1. - pow(light, gamma.xxx);
+vec3 scaleSoftClip(vec3 light);
- return light;
+vec4 cloudNoise(vec2 uv)
+{
+ vec4 a = texture2D(cloud_noise_texture, uv);
+ vec4 b = texture2D(cloud_noise_texture_next, uv);
+ vec4 cloud_noise_sample = mix(a, b, blend_factor);
+ return cloud_noise_sample;
}
void main()
{
- // Set variables
- vec2 uv1 = vary_texcoord0.xy;
- vec2 uv2 = vary_texcoord1.xy;
+ // Set variables
+ vec2 uv1 = vary_texcoord0.xy;
+ vec2 uv2 = vary_texcoord1.xy;
- vec4 cloudColorSun = vary_CloudColorSun;
- vec4 cloudColorAmbient = vary_CloudColorAmbient;
- float cloudDensity = vary_CloudDensity;
- vec2 uv3 = vary_texcoord2.xy;
- vec2 uv4 = vary_texcoord3.xy;
+ vec4 cloudColorSun = vary_CloudColorSun;
+ vec4 cloudColorAmbient = vary_CloudColorAmbient;
+ float cloudDensity = vary_CloudDensity;
+ vec2 uv3 = vary_texcoord2.xy;
+ vec2 uv4 = vary_texcoord3.xy;
- // Offset texture coords
- uv1 += cloud_pos_density1.xy; //large texture, visible density
- uv2 += cloud_pos_density1.xy; //large texture, self shadow
- uv3 += cloud_pos_density2.xy; //small texture, visible density
- uv4 += cloud_pos_density2.xy; //small texture, self shadow
+ if (cloud_scale < 0.001)
+ {
+ discard;
+ }
+ vec2 disturbance = vec2(cloudNoise(uv1 / 8.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
+ vec2 disturbance2 = vec2(cloudNoise((uv1 + uv3) / 4.0f).x, cloudNoise((uv4 + uv2) / 8.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
- // Compute alpha1, the main cloud opacity
- float alpha1 = (texture2D(cloud_noise_texture, uv1).x - 0.5) + (texture2D(cloud_noise_texture, uv3).x - 0.5) * cloud_pos_density2.z;
- alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10. * cloud_pos_density1.z, 1.);
+ // Offset texture coords
+ uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density
+ uv2 += cloud_pos_density1.xy; //large texture, self shadow
+ uv3 += cloud_pos_density2.xy; //small texture, visible density
+ uv4 += cloud_pos_density2.xy; //small texture, self shadow
- // And smooth
- alpha1 = 1. - alpha1 * alpha1;
- alpha1 = 1. - alpha1 * alpha1;
+ float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0 + disturbance2.x + disturbance2.y) * 4.0);
+ cloudDensity *= 1.0 - (density_variance * density_variance);
- // Compute alpha2, for self shadowing effect
- // (1 - alpha2) will later be used as percentage of incoming sunlight
- float alpha2 = (texture2D(cloud_noise_texture, uv2).x - 0.5);
- alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
+ // Compute alpha1, the main cloud opacity
- // And smooth
- alpha2 = 1. - alpha2;
- alpha2 = 1. - alpha2 * alpha2;
+ float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
+ alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
- // Combine
- vec4 color;
- color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
- color *= 2.;
+ // And smooth
+ alpha1 = 1. - alpha1 * alpha1;
+ alpha1 = 1. - alpha1 * alpha1;
- /// Gamma correct for WL (soft clip effect).
- frag_color.rgb = scaleSoftClip(color.rgb);
- frag_color.a = alpha1;
+ alpha1 *= altitude_blend_factor;
+
+ //if (alpha1 < 0.001f)
+ //{
+ // discard;
+ //}
+
+ // Compute alpha2, for self shadowing effect
+ // (1 - alpha2) will later be used as percentage of incoming sunlight
+ float alpha2 = (cloudNoise(uv2).x - 0.5);
+ alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
+
+ // And smooth
+ alpha2 = 1. - alpha2;
+ alpha2 = 1. - alpha2 * alpha2;
+
+ // Combine
+ vec4 color;
+ color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
+ color.rgb *= 2.;
+ color.rgb = scaleSoftClip(color.rgb);
+
+ /// Gamma correct for WL (soft clip effect).
+ frag_data[0] = vec4(color.rgb, alpha1);
+ frag_data[1] = vec4(0.0,0.0,0.0,0.0);
+ frag_data[2] = vec4(0,0,0,1);
}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
index c1dd45cd67..2c1475d547 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
@@ -1,5 +1,5 @@
/**
- * @file WLCloudsV.glsl
+ * @file class2\wl\cloudsV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -40,13 +40,16 @@ 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 ambient;
+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;
@@ -57,6 +60,7 @@ uniform float density_multiplier;
uniform float max_y;
uniform vec4 glow;
+uniform float sun_moon_glow_factor;
uniform vec4 cloud_color;
@@ -73,6 +77,9 @@ void main()
// Get relative position
vec3 P = 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.)
{
@@ -92,16 +99,18 @@ void main()
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)) * (density_multiplier * max_y);
+ light_atten = (blue_density + vec4(haze_density * 0.25)) * (dens_mul * max_y);
// Calculate relative weights
- temp1 = blue_density + haze_density;
+ temp1 = abs(blue_density) + vec4(abs(haze_density));
blue_weight = blue_density / temp1;
haze_weight = haze_density / temp1;
@@ -111,7 +120,7 @@ void main()
sunlight *= exp( - light_atten * temp2.y);
// Distance
- temp2.z = Plen * density_multiplier;
+ temp2.z = Plen * dens_mul;
// Transparency (-> temp1)
// ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati
@@ -130,11 +139,13 @@ void main()
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;
+ vec4 tmpAmbient = ambient_color;
tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
@@ -146,8 +157,6 @@ void main()
);
// CLOUDS
-
- sunlight = sunlight_color;
temp2.y = max(0., lightnorm.y * 2.);
temp2.y = 1. / temp2.y;
sunlight *= exp( - light_atten * temp2.y);
diff --git a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
index 478373d729..68db7fcbb1 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
@@ -1,5 +1,5 @@
/**
- * @file gammaF.glsl
+ * @file class2\wl\gammaF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -22,23 +22,37 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-
-
-uniform vec4 gamma;
+uniform float gamma;
+uniform int no_atmo;
vec3 getAtmosAttenuation();
+vec3 getAdditiveColor();
-/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light) {
- //soft clip effect:
- light = 1. - clamp(light, vec3(0.), vec3(1.));
- light = 1. - pow(light, gamma.xxx);
-
- return light;
+vec3 scaleSoftClipFrag(vec3 light)
+{
+ if (no_atmo == 1)
+ {
+ return light;
+ }
+ //soft clip effect:
+ light = 1. - clamp(light, vec3(0.), vec3(1.));
+ light = 1. - pow(light, vec3(gamma)); // s/b inverted already CPU-side
+ return light;
}
-vec3 fullbrightScaleSoftClip(vec3 light) {
- return mix(scaleSoftClip(light.rgb), light.rgb, getAtmosAttenuation());
+vec3 scaleSoftClip(vec3 light)
+{
+ return scaleSoftClipFrag(light);
+}
+
+vec3 fullbrightScaleSoftClipFrag(vec3 light, vec3 add, vec3 atten)
+{
+ //return mix(scaleSoftClipFrag(light.rgb), add, atten);
+ return scaleSoftClipFrag(light.rgb);
+}
+
+vec3 fullbrightScaleSoftClip(vec3 light)
+{
+ return fullbrightScaleSoftClipFrag(light, getAdditiveColor(), getAtmosAttenuation());
}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
index e2a2367626..7146349453 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
@@ -1,5 +1,5 @@
/**
- * @file WLSkyF.glsl
+ * @file class2/windlight/skyF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -35,17 +35,8 @@ out vec4 frag_color;
VARYING vec4 vary_HazeColor;
-uniform sampler2D cloud_noise_texture;
-uniform vec4 gamma;
-
/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light) {
- //soft clip effect:
- light = 1. - clamp(light, vec3(0.), vec3(1.));
- light = 1. - pow(light, gamma.xxx);
-
- return light;
-}
+vec3 scaleSoftClip(vec3 light);
void main()
{
@@ -56,8 +47,7 @@ void main()
vec4 color;
color = vary_HazeColor;
- color *= 2.;
-
+ color.rgb *= 2.;
/// Gamma correct for WL (soft clip effect).
frag_color.rgb = scaleSoftClip(color.rgb);
frag_color.a = 1.0;
diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
index 3788ddaf2d..0d141342ce 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
@@ -1,5 +1,5 @@
/**
- * @file WLSkyV.glsl
+ * @file class2\wl\skyV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -39,7 +39,9 @@ uniform vec3 camPosLocal;
uniform vec4 lightnorm;
uniform vec4 sunlight_color;
-uniform vec4 ambient;
+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;
@@ -47,9 +49,11 @@ uniform float haze_density;
uniform float cloud_shadow;
uniform float density_multiplier;
+uniform float distance_multiplier;
uniform float max_y;
uniform vec4 glow;
+uniform float sun_moon_glow_factor;
uniform vec4 cloud_color;
@@ -57,11 +61,12 @@ void main()
{
// World / view / projection
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ 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);
- //vec3 P = position.xyz + vec3(0,50,0);
// Set altitude
if (P.y > 0.)
@@ -75,38 +80,40 @@ void main()
// Can normalize then
vec3 Pn = normalize(P);
- float Plen = length(P);
+
+ float Plen = length(P);
// Initialize temp variables
vec4 temp1 = vec4(0.);
vec4 temp2 = vec4(0.);
vec4 blue_weight;
vec4 haze_weight;
- vec4 sunlight = sunlight_color;
+ 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)) * (density_multiplier * max_y);
+ light_atten = (blue_density + vec4(haze_density * 0.25)) * (dens_mul * max_y);
// Calculate relative weights
- temp1 = blue_density + haze_density;
+ 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);
+ 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 * density_multiplier;
+ 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);
-
+ // 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);
@@ -122,35 +129,33 @@ void main()
// Add "minimum anti-solar illumination"
temp2.x += .25;
+ vec4 color = ( blue_horizon * blue_weight * (sunlight + ambient_color)
+ + (haze_horizon * haze_weight) * (sunlight * temp2.x + ambient_color)
+ );
- // Haze color above cloud
- vary_HazeColor = ( blue_horizon * blue_weight * (sunlight + ambient)
- + (haze_horizon * haze_weight) * (sunlight * temp2.x + ambient)
- );
+ // Final atmosphere additive
+ color *= (1. - temp1);
// Increase ambient when there are more clouds
- vec4 tmpAmbient = ambient;
- tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;
+ vec4 tmpAmbient = ambient_color;
+ tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
- sunlight *= (1. - cloud_shadow);
+ 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)
);
- // Final atmosphere additive
- vary_HazeColor *= (1. - temp1);
-
// Attenuate cloud color by atmosphere
temp1 = sqrt(temp1); //less atmos opacity (more transparency) below clouds
// At horizon, blend high altitude sky color towards the darker color below the clouds
- vary_HazeColor += (additiveColorBelowCloud - vary_HazeColor) * (1. - sqrt(temp1));
-
- // won't compile on mac without this being set
- //vary_AtmosAttenuation = vec3(0.0,0.0,0.0);
+ color += (additiveColorBelowCloud - color) * (1. - sqrt(temp1));
+
+ // Haze color above cloud
+ vary_HazeColor = color;
}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
index 8a8e4cb0f6..b53a2e237f 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
@@ -1,5 +1,5 @@
/**
- * @file transportF.glsl
+ * @file class2\wl\transportF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -30,24 +30,33 @@
vec3 getAdditiveColor();
vec3 getAtmosAttenuation();
-uniform sampler2D cloudMap;
-uniform vec4 cloud_pos_density1;
+uniform int no_atmo;
-vec3 atmosTransport(vec3 light) {
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor() * 2.0;
+vec3 atmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
+{
+ light *= atten.r;
+ light += additive * 2.0;
return light;
}
-vec3 fullbrightAtmosTransport(vec3 light) {
- float brightness = dot(light.rgb, vec3(0.33333));
-
- return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
+vec3 atmosTransport(vec3 light)
+{
+ return atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
}
-vec3 fullbrightShinyAtmosTransport(vec3 light) {
- float brightness = dot(light.rgb, vec3(0.33333));
-
- return mix(atmosTransport(light.rgb), (light.rgb + getAdditiveColor().rgb) * (2.0 - brightness), brightness * brightness);
+vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
+{
+ float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1;
+ return mix(atmosTransportFrag(light.rgb, additive, atten), light.rgb + additive, brightness * brightness);
}
+vec3 fullbrightAtmosTransport(vec3 light)
+{
+ return fullbrightAtmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
+}
+
+vec3 fullbrightShinyAtmosTransport(vec3 light)
+{
+ float brightness = dot(light.rgb, vec3(0.33333));
+ return mix(atmosTransport(light.rgb), (light.rgb + getAdditiveColor().rgb) * (2.0 - brightness), brightness * brightness);
+}
diff --git a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl b/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
index 721054b5ad..df9704ec25 100644
--- a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
+++ b/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
@@ -33,7 +33,7 @@ ATTRIBUTE vec4 clothing;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
mat4 getSkinnedTransform();
void calcAtmospherics(vec3 inPositionEye);
@@ -127,7 +127,7 @@ void main()
calcAtmospherics(pos.xyz);
- vec4 col = calcLighting(pos.xyz, norm, color, vec4(0.0));
+ vec4 col = calcLighting(pos.xyz, norm, color);
vertex_color = col;
gl_Position = projection_matrix * pos;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowF.glsl
new file mode 100644
index 0000000000..d973326f93
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowF.glsl
@@ -0,0 +1,44 @@
+/**
+ * @file avatarShadowF.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]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2D diffuseMap;
+
+VARYING vec4 pos;
+VARYING vec2 vary_texcoord0;
+
+vec4 computeMoments(float depth, float a);
+
+void main()
+{
+ frag_color = computeMoments(length(pos), 1.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowV.glsl
new file mode 100644
index 0000000000..1a655e6467
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowV.glsl
@@ -0,0 +1,49 @@
+/**
+ * @file attachmentShadowV.glsl
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 projection_matrix;
+uniform mat4 modelview_matrix;
+uniform mat4 texture_matrix0;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+
+mat4 getObjectSkinnedTransform();
+
+VARYING vec4 pos;
+
+void main()
+{
+ //transform vertex
+ mat4 mat = getObjectSkinnedTransform();
+
+ mat = modelview_matrix * mat;
+ pos = (mat*vec4(position.xyz, 1.0));
+ pos = projection_matrix * vec4(pos.xyz, 1.0);
+
+#if !defined(DEPTH_CLAMP)
+ pos.z = max(pos.z, -pos.w+0.01);
+#endif
+ gl_Position = pos;
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/srgb.glsl b/indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl
similarity index 66%
rename from indra/newview/app_settings/shaders/class1/deferred/srgb.glsl
rename to indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl
index 587f3d5a94..48eefc7a73 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/srgb.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl
@@ -1,5 +1,5 @@
/**
- * @file srgb.glsl
+ * @file avatarShadowF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,24 +23,30 @@
* $/LicenseInfo$
*/
-vec3 srgb_to_linear(vec3 cs)
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2D diffuseMap;
+
+#if !defined(DEPTH_CLAMP)
+VARYING vec4 post_pos;
+#endif
+
+VARYING vec4 pos;
+
+vec4 computeMoments(float depth, float a);
+
+void main()
{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
-
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
- return mix(high_range, low_range, lte);
-
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
-
- bvec3 lt = lessThan(cl,vec3(0.0031308));
- return mix(high_range, low_range, lt);
+ frag_color = computeMoments(length(pos), 1.0);
+#if !defined(DEPTH_CLAMP)
+ gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
+#endif
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/avatarShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/avatarShadowV.glsl
new file mode 100644
index 0000000000..164b355f20
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/avatarShadowV.glsl
@@ -0,0 +1,68 @@
+/**
+ * @file avatarShadowV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 projection_matrix;
+
+mat4 getSkinnedTransform();
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+
+#if !defined(DEPTH_CLAMP)
+VARYING vec4 post_pos;
+#endif
+
+VARYING vec4 pos;
+
+void main()
+{
+ vec3 norm;
+
+ vec4 pos_in = vec4(position.xyz, 1.0);
+ mat4 trans = getSkinnedTransform();
+
+ pos.x = dot(trans[0], pos_in);
+ pos.y = dot(trans[1], pos_in);
+ pos.z = dot(trans[2], pos_in);
+ pos.w = 1.0;
+
+ norm.x = dot(trans[0].xyz, normal);
+ norm.y = dot(trans[1].xyz, normal);
+ norm.z = dot(trans[2].xyz, normal);
+ norm = normalize(norm);
+
+ pos = projection_matrix * pos;
+
+#if !defined(DEPTH_CLAMP)
+ post_pos = pos;
+ gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+#else
+ gl_Position = pos;
+#endif
+
+}
+
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl
new file mode 100644
index 0000000000..32210f60dc
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl
@@ -0,0 +1,119 @@
+/**
+ * @file class3/deferred/cloudsF.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$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2D diffuseMap;
+
+VARYING vec4 pos;
+VARYING float target_pos_x;
+VARYING float vary_CloudDensity;
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
+VARYING vec2 vary_texcoord3;
+
+uniform sampler2D cloud_noise_texture;
+uniform sampler2D cloud_noise_texture_next;
+uniform float blend_factor;
+uniform vec4 cloud_pos_density1;
+uniform vec4 cloud_pos_density2;
+uniform vec4 cloud_color;
+uniform float cloud_shadow;
+uniform float cloud_scale;
+uniform float cloud_variance;
+uniform vec3 camPosLocal;
+uniform vec3 sun_dir;
+uniform float sun_size;
+uniform float far_z;
+
+vec4 cloudNoise(vec2 uv)
+{
+ vec4 a = texture2D(cloud_noise_texture, uv);
+ vec4 b = texture2D(cloud_noise_texture_next, uv);
+ vec4 cloud_noise_sample = mix(a, b, blend_factor);
+ return normalize(cloud_noise_sample);
+}
+
+vec4 computeMoments(float depth, float alpha);
+
+void main()
+{
+ if (cloud_scale >= 0.001)
+ {
+ // Set variables
+ vec2 uv1 = vary_texcoord0.xy;
+ vec2 uv2 = vary_texcoord1.xy;
+ vec2 uv3 = vary_texcoord2.xy;
+ float cloudDensity = 2.0 * (cloud_shadow - 0.25);
+
+ vec2 uv4 = vary_texcoord3.xy;
+
+ vec2 disturbance = vec2(cloudNoise(uv1 / 8.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
+ vec2 disturbance2 = vec2(cloudNoise((uv1 + uv3) / 4.0f).x, cloudNoise((uv4 + uv2) / 8.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
+
+ // Offset texture coords
+ uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density
+ uv2 += cloud_pos_density1.xy; //large texture, self shadow
+ uv3 += cloud_pos_density2.xy; //small texture, visible density
+ uv4 += cloud_pos_density2.xy; //small texture, self shadow
+
+ float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0 + disturbance2.x + disturbance2.y) * 4.0);
+
+ cloudDensity *= 1.0 - (density_variance * density_variance);
+
+ // Compute alpha1, the main cloud opacity
+ float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
+ alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
+
+ // And smooth
+ alpha1 = 1. - alpha1 * alpha1;
+ alpha1 = 1. - alpha1 * alpha1;
+
+ if (alpha1 < 0.001f)
+ {
+ discard;
+ }
+
+ // Compute alpha2, for self shadowing effect
+ // (1 - alpha2) will later be used as percentage of incoming sunlight
+ float alpha2 = (cloudNoise(uv2).x - 0.5);
+ alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
+
+ // And smooth
+ alpha2 = 1. - alpha2;
+ alpha2 = 1. - alpha2 * alpha2;
+
+ frag_color = computeMoments(length(pos), alpha1);
+ }
+ else
+ {
+ frag_color = vec4(0);
+ }
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudShadowV.glsl
new file mode 100644
index 0000000000..effb070f93
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/cloudShadowV.glsl
@@ -0,0 +1,63 @@
+/**
+ * @file cloudShadowV.glsl
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
+uniform float shadow_target_width;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+#if !defined(DEPTH_CLAMP)
+VARYING float pos_zd2;
+#endif
+
+VARYING vec4 pos;
+VARYING float target_pos_x;
+VARYING vec2 vary_texcoord0;
+VARYING vec4 vertex_color;
+
+void passTextureIndex();
+
+void main()
+{
+ //transform vertex
+ vec4 pre_pos = vec4(position.xyz, 1.0);
+ pos = modelview_projection_matrix * pre_pos;
+ target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
+
+#if !defined(DEPTH_CLAMP)
+ pos_zd2 = pos.z * 0.5;
+ gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+#else
+ gl_Position = pos;
+#endif
+
+ passTextureIndex();
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+ vertex_color = diffuse_color;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl
new file mode 100644
index 0000000000..e40d7e7c75
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl
@@ -0,0 +1,166 @@
+/**
+ * @file class3/deferred/cloudsF.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$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+
+/////////////////////////////////////////////////////////////////////////
+// The fragment shader for the sky
+/////////////////////////////////////////////////////////////////////////
+
+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 vec3 vary_pos;
+
+uniform sampler2D cloud_noise_texture;
+uniform sampler2D cloud_noise_texture_next;
+uniform float blend_factor;
+uniform vec4 cloud_pos_density1;
+uniform vec4 cloud_pos_density2;
+uniform vec4 cloud_color;
+uniform float cloud_shadow;
+uniform float cloud_scale;
+uniform float cloud_variance;
+uniform vec3 camPosLocal;
+uniform vec3 sun_dir;
+uniform float sun_size;
+uniform float far_z;
+
+uniform sampler2D transmittance_texture;
+uniform sampler3D scattering_texture;
+uniform sampler3D single_mie_scattering_texture;
+uniform sampler2D irradiance_texture;
+uniform sampler2D sh_input_r;
+uniform sampler2D sh_input_g;
+uniform sampler2D sh_input_b;
+
+vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance);
+
+/// Soft clips the light with a gamma correction
+vec3 scaleSoftClip(vec3 light);
+
+vec4 cloudNoise(vec2 uv)
+{
+ vec4 a = texture2D(cloud_noise_texture, uv);
+ vec4 b = texture2D(cloud_noise_texture_next, uv);
+ vec4 cloud_noise_sample = mix(a, b, blend_factor);
+ return cloud_noise_sample;
+}
+
+void main()
+{
+ // Set variables
+ vec2 uv1 = vary_texcoord0.xy;
+ vec2 uv2 = vary_texcoord1.xy;
+ vec2 uv3 = vary_texcoord2.xy;
+ float cloudDensity = 2.0 * (cloud_shadow - 0.25);
+
+ if (cloud_scale < 0.001)
+ {
+ discard;
+ }
+
+ vec2 uv4 = vary_texcoord3.xy;
+
+ vec2 disturbance = vec2(cloudNoise(uv1 / 16.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
+
+ // Offset texture coords
+ uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density
+ uv2 += cloud_pos_density1.xy; //large texture, self shadow
+ uv3 += cloud_pos_density2.xy; //small texture, visible density
+ uv4 += cloud_pos_density2.xy; //small texture, self shadow
+
+ float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0) * 4.0);
+
+ cloudDensity *= 1.0 - (density_variance * density_variance);
+
+ // Compute alpha1, the main cloud opacity
+ float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
+ alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
+
+ // And smooth
+ alpha1 = 1. - alpha1 * alpha1;
+ alpha1 = 1. - alpha1 * alpha1;
+
+ if (alpha1 < 0.001f)
+ {
+ discard;
+ }
+
+ // Compute alpha2, for self shadowing effect
+ // (1 - alpha2) will later be used as percentage of incoming sunlight
+ float alpha2 = (cloudNoise(uv2).x - 0.5);
+ alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
+
+ // And smooth
+ alpha2 = 1. - alpha2;
+ alpha2 = 1. - alpha2 * alpha2;
+
+ vec3 view_ray = vary_pos.xyz + camPosLocal;
+
+ vec3 view_direction = normalize(view_ray);
+ vec3 sun_direction = normalize(sun_dir);
+ vec3 earth_center = vec3(0, 0, -6360.0f);
+ vec3 camPos = (camPosLocal / 1000.0f) - earth_center;
+
+ vec3 transmittance;
+ vec3 radiance_sun = GetSkyLuminance(camPos, view_direction, 1.0 - alpha1, sun_direction, transmittance);
+
+ vec3 sun_color = vec3(1.0) - exp(-radiance_sun * 0.0001);
+
+ // Combine
+ vec4 color;
+
+ vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265));
+
+ vec4 l1r = texture2D(sh_input_r, vec2(0,0));
+ vec4 l1g = texture2D(sh_input_g, vec2(0,0));
+ vec4 l1b = texture2D(sh_input_b, vec2(0,0));
+
+ vec3 sun_indir = vec3(-view_direction.xy, view_direction.z);
+ vec3 amb = vec3(dot(l1r, l1tap * vec4(1, sun_indir)),
+ dot(l1g, l1tap * vec4(1, sun_indir)),
+ dot(l1b, l1tap * vec4(1, sun_indir)));
+
+
+ amb = max(vec3(0), amb);
+
+ color.rgb = sun_color * cloud_color.rgb * (1. - alpha2);
+ color.rgb = pow(color.rgb, vec3(1.0 / 2.2));
+ color.rgb += amb;
+
+ frag_data[0] = vec4(color.rgb, alpha1);
+ frag_data[1] = vec4(0);
+ frag_data[2] = vec4(0,1,0,1);
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl
new file mode 100644
index 0000000000..71e422ddf0
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl
@@ -0,0 +1,70 @@
+/**
+ * @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$
+ */
+
+uniform mat4 modelview_projection_matrix;
+uniform mat4 modelview_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+
+//////////////////////////////////////////////////////////////////////////
+// The vertex shader for creating the atmospheric sky
+///////////////////////////////////////////////////////////////////////////////
+
+// Output parameters
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
+VARYING vec2 vary_texcoord3;
+VARYING vec3 vary_pos;
+
+// Inputs
+uniform float cloud_scale;
+uniform vec4 lightnorm;
+uniform vec3 camPosLocal;
+
+void main()
+{
+ vary_pos = position;
+
+ // 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 /= max(0.001, 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.;
+
+ // END CLOUDS
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl
new file mode 100644
index 0000000000..e27bbce094
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl
@@ -0,0 +1,79 @@
+/**
+ * @file class1/deferred/deferredUtil.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform sampler2DRect normalMap;
+uniform sampler2DRect depthMap;
+
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+
+vec2 getScreenCoordinate(vec2 screenpos)
+{
+ vec2 sc = screenpos.xy * 2.0;
+ if (screen_res.x > 0 && screen_res.y > 0)
+ {
+ sc /= screen_res;
+ }
+ return sc - vec2(1.0, 1.0);
+}
+
+vec3 getNorm(vec2 screenpos)
+{
+ vec2 enc = texture2DRect(normalMap, screenpos.xy).xy;
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+
+float getDepth(vec2 pos_screen)
+{
+ float depth = texture2DRect(depthMap, pos_screen).r;
+ return depth;
+}
+
+vec4 getPosition(vec2 pos_screen)
+{
+ float depth = getDepth(pos_screen);
+ vec2 sc = getScreenCoordinate(pos_screen);
+ vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
+ vec4 pos = inv_proj * ndc;
+ pos /= pos.w;
+ pos.w = 1.0;
+ return pos;
+}
+
+vec4 getPositionWithDepth(vec2 pos_screen, float depth)
+{
+ vec2 sc = getScreenCoordinate(pos_screen);
+ vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
+ vec4 pos = inv_proj * ndc;
+ pos /= pos.w;
+ pos.w = 1.0;
+ return pos;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl b/indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl
new file mode 100644
index 0000000000..cdaff4b09f
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl
@@ -0,0 +1,202 @@
+/**
+ * @file depthToShadowVolumeG.glsl
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+#extension GL_ARB_geometry_shader4 : enable
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+layout (triangles) in;
+layout (triangle_strip, max_vertices = 128) out;
+
+uniform sampler2DRect depthMap;
+uniform mat4 shadowMatrix[6];
+uniform vec4 lightpos;
+
+VARYING vec2 vary_texcoord0;
+
+out vec3 to_vec;
+
+void cross_products(out vec4 ns[3], int a, int b, int c)
+{
+ ns[0] = cross(gl_PositionIn[b].xyz - gl_PositionIn[a].xyz, gl_PositionIn[c].xyz - gl_PositionIn[a].xyz);
+ ns[1] = cross(gl_PositionIn[c].xyz - gl_PositionIn[b].xyz, gl_PositionIn[a].xyz - gl_PositionIn[b].xyz);
+ ns[2] = cross(gl_PositionIn[a].xyz - gl_PositionIn[c].xyz, gl_PositionIn[b].xyz - gl_PositionIn[c].xyz);
+}
+
+vec3 getLightDirection(vec4 lightpos, vec3 pos)
+{
+
+ vec3 lightdir = lightpos.xyz - lightpos.w * pos;
+ return lightdir;
+}
+
+void emitTri(vec4 v[3])
+{
+ gl_Position = proj_matrix * v[0];
+ EmitVertex();
+
+ gl_Position = proj_matrix * v[1];
+ EmitVertex();
+
+ gl_Position = proj_matrix * v[2];
+ EmitVertex();
+
+ EndPrimitive();
+}
+
+void emitQuad(vec4 v[4]
+{
+ // Emit a quad as a triangle strip.
+ gl_Position = proj_matrix*v[0];
+ EmitVertex();
+
+ gl_Position = proj_matrix*v[1];
+ EmitVertex();
+
+ gl_Position = proj_matrix*v[2];
+ EmitVertex();
+
+ gl_Position = proj_matrix*v[3];
+ EmitVertex();
+
+ EndPrimitive();
+}
+
+void emitPrimitives(int layer)
+{
+ int i = layer;
+ gl_Layer = i;
+
+ vec4 depth1 = vec4(texture2DRect(depthMap, tc0).rg, texture2DRect(depthMap, tc1).rg));
+ vec3 depth2 = vec4(texture2DRect(depthMap, tc2).rg, texture2DRect(depthMap, tc3).rg));
+ vec3 depth3 = vec4(texture2DRect(depthMap, tc4).rg, texture2DRect(depthMap, tc5).rg));
+ vec3 depth4 = vec4(texture2DRect(depthMap, tc6).rg, texture2DRect(depthMap, tc7).rg));
+
+ depth1 = min(depth1, depth2);
+ depth1 = min(depth1, depth3);
+ depth1 = min(depth1, depth4);
+
+ vec2 depth = min(depth1.xy, depth1.zw);
+
+ int side = sqrt(gl_VerticesIn);
+
+ for (int j = 0; j < side; j++)
+ {
+ for (int k = 0; k < side; ++k)
+ {
+ vec3 pos = gl_PositionIn[(j * side) + k].xyz;
+ vec4 v = shadowMatrix[i] * vec4(pos, 1.0);
+ gl_Position = v;
+ to_vec = pos - light_position.xyz * depth;
+ EmitVertex();
+ }
+
+ EndPrimitive();
+ }
+
+ vec3 norms[3]; // Normals
+ vec3 lightdir3]; // Directions toward light
+
+ vec4 v[4]; // Temporary vertices
+
+ vec4 or_pos[3] =
+ { // Triangle oriented toward light source
+ gl_PositionIn[0],
+ gl_PositionIn[2],
+ gl_PositionIn[4]
+ };
+
+ // Compute normal at each vertex.
+ cross_products(n, 0, 2, 4);
+
+ // Compute direction from vertices to light.
+ lightdir[0] = getLightDirection(lightpos, gl_PositionIn[0].xyz);
+ lightdir[1] = getLightDirection(lightpos, gl_PositionIn[2].xyz);
+ lightdir[2] = getLightDirection(lightpos, gl_PositionIn[4].xyz);
+
+ // Check if the main triangle faces the light.
+ bool faces_light = true;
+ if (!(dot(ns[0],d[0]) > 0
+ |dot(ns[1],d[1]) > 0
+ |dot(ns[2],d[2]) > 0))
+ {
+ // Flip vertex winding order in or_pos.
+ or_pos[1] = gl_PositionIn[4];
+ or_pos[2] = gl_PositionIn[2];
+ faces_light = false;
+ }
+
+ // Near cap: simply render triangle.
+ emitTri(or_pos);
+
+ // Far cap: extrude positions to infinity.
+ v[0] =vec4(lightpos.w * or_pos[0].xyz - lightpos.xyz,0);
+ v[1] =vec4(lightpos.w * or_pos[2].xyz - lightpos.xyz,0);
+ v[2] =vec4(lightpos.w * or_pos[1].xyz - lightpos.xyz,0);
+
+ emitTri(v);
+
+ // Loop over all edges and extrude if needed.
+ for ( int i=0; i<3; i++ )
+ {
+ // Compute indices of neighbor triangle.
+ int v0 = i*2;
+ int nb = (i*2+1);
+ int v1 = (i*2+2) % 6;
+ cross_products(n, v0, nb, v1);
+
+ // Compute direction to light, again as above.
+ d[0] =lightpos.xyz-lightpos.w*gl_PositionIn[v0].xyz;
+ d[1] =lightpos.xyz-lightpos.w*gl_PositionIn[nb].xyz;
+ d[2] =lightpos.xyz-lightpos.w*gl_PositionIn[v1].xyz;
+
+ bool is_parallel = gl_PositionIn[nb].w < 1e-5;
+
+ // Extrude the edge if it does not have a
+ // neighbor, or if it's a possible silhouette.
+ if (is_parallel ||
+ ( faces_light != (dot(ns[0],d[0])>0 ||
+ dot(ns[1],d[1])>0 ||
+ dot(ns[2],d[2])>0) ))
+ {
+ // Make sure sides are oriented correctly.
+ int i0 = faces_light ? v0 : v1;
+ int i1 = faces_light ? v1 : v0;
+
+ v[0] = gl_PositionIn[i0];
+ v[1] = vec4(lightpos.w*gl_PositionIn[i0].xyz - lightpos.xyz, 0);
+ v[2] = gl_PositionIn[i1];
+ v[3] = vec4(lightpos.w*gl_PositionIn[i1].xyz - lightpos.xyz, 0);
+
+ emitQuad(v);
+ }
+ }
+}
+
+void main()
+{
+ // Output
+ emitPrimitives(0);
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl b/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl
new file mode 100644
index 0000000000..34d26cddea
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl
@@ -0,0 +1,70 @@
+/**
+ * @file class3/deferred/gatherSkyShF.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$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+
+VARYING vec2 vary_frag;
+
+uniform vec2 screen_res;
+uniform sampler2D sh_input_r;
+uniform sampler2D sh_input_g;
+uniform sampler2D sh_input_b;
+
+void main()
+{
+ vec2 offset = vec2(2.0) / screen_res;
+
+ vec4 r = vec4(0);
+ vec4 g = vec4(0);
+ vec4 b = vec4(0);
+
+ vec2 tc = vary_frag * 2.0;
+
+ r += texture2D(sh_input_r, tc + vec2(0, 0));
+ r += texture2D(sh_input_r, tc + vec2(offset.x, 0));
+ r += texture2D(sh_input_r, tc + vec2(0, offset.y));
+ r += texture2D(sh_input_r, tc + vec2(offset.x, offset.y));
+ r /= 4.0f;
+
+ g += texture2D(sh_input_g, tc + vec2(0, 0));
+ g += texture2D(sh_input_g, tc + vec2(offset.x, 0));
+ g += texture2D(sh_input_g, tc + vec2(0, offset.y));
+ g += texture2D(sh_input_g, tc + vec2(offset.x, offset.y));
+ g /= 4.0f;
+
+ b += texture2D(sh_input_b, tc + vec2(0, 0));
+ b += texture2D(sh_input_b, tc + vec2(offset.x, 0));
+ b += texture2D(sh_input_b, tc + vec2(0, offset.y));
+ b += texture2D(sh_input_b, tc + vec2(offset.x, offset.y));
+ b /= 4.0f;
+
+ frag_data[0] = r;
+ frag_data[1] = g;
+ frag_data[2] = b;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl b/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl
new file mode 100644
index 0000000000..337c8a50fe
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl
@@ -0,0 +1,40 @@
+/**
+ * @file gatherSkyShV.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$
+ */
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec2 vary_frag;
+uniform vec2 screen_res;
+
+void main()
+{
+ // pass through untransformed fullscreen pos
+ float oo_divisor = screen_res.x / 64.0;
+ vec3 pos = (position.xyz * oo_divisor) + vec3(oo_divisor - 1, oo_divisor - 1, 0);
+ gl_Position = vec4(pos.xyz, 1.0);
+ vary_frag = texcoord0 * oo_divisor;
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl b/indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl
new file mode 100644
index 0000000000..d5d91c88f0
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl
@@ -0,0 +1,111 @@
+/**
+ * @file class3/deferred/genSkyShF.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$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+
+VARYING vec2 vary_frag;
+
+uniform vec3 sun_dir;
+
+uniform sampler2D transmittance_texture;
+uniform sampler3D scattering_texture;
+uniform sampler3D single_mie_scattering_texture;
+uniform sampler2D irradiance_texture;
+
+vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance);
+
+vec3 calcDirection(vec2 tc)
+{
+ float phi = tc.y * 2.0 * 3.14159265;
+ float cosTheta = sqrt(1.0 - tc.x);
+ float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
+ return vec3(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);
+}
+
+// reverse mapping above to convert a hemisphere direction into phi/theta values
+void getPhiAndThetaFromDirection(vec3 dir, out float phi, out float theta)
+{
+ float sin_theta;
+ float cos_theta;
+ cos_theta = dir.z;
+ theta = acos(cos_theta);
+ sin_theta = sin(theta);
+ phi = abs(sin_theta) > 0.0001 ? acos(dir.x / sin_theta) : 1.0;
+}
+
+// reverse mapping above to convert a hemisphere direction into an SH texture sample pos
+vec2 calcShUvFromDirection(vec3 dir)
+{
+ vec2 uv;
+ float phi;
+ float theta;
+ getPhiAndThetaFromDirection(dir, phi, theta);
+ uv.y = phi / 2.0 * 3.14159265;
+ uv.x = theta / 2.0 * 3.14159265;
+ return uv;
+}
+
+void projectToL1(vec3 n, vec3 c, vec4 basis, out vec4 coeffs[3])
+{
+ coeffs[0] = vec4(basis.x, n * basis.yzw * c.r);
+ coeffs[1] = vec4(basis.x, n * basis.yzw * c.g);
+ coeffs[2] = vec4(basis.x, n * basis.yzw * c.b);
+}
+
+void main()
+{
+ float Y00 = sqrt(1.0 / 3.14159265) * 0.5;
+ float Y1x = sqrt(3.0 / 3.14159265) * 0.5;
+ float Y1y = Y1x;
+ float Y1z = Y1x;
+
+ vec4 L1 = vec4(Y00, Y1x, Y1y, Y1z);
+
+ vec3 view_direction = calcDirection(vary_frag);
+ vec3 sun_direction = normalize(sun_dir);
+ vec3 cam_pos = vec3(0, 0, 6360);
+
+ vec3 transmittance;
+ vec3 radiance = GetSkyLuminance(cam_pos, view_direction, 0.0f, sun_direction, transmittance);
+
+ vec3 color = vec3(1.0) - exp(-radiance * 0.0001);
+
+ color = pow(color, vec3(1.0/2.2));
+
+ vec4 coeffs[3];
+ coeffs[0] = vec4(0);
+ coeffs[1] = vec4(0);
+ coeffs[2] = vec4(0);
+
+ projectToL1(view_direction, color.rgb, L1, coeffs);
+
+ frag_data[0] = coeffs[0];
+ frag_data[1] = coeffs[1];
+ frag_data[2] = coeffs[2];
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl b/indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl
new file mode 100644
index 0000000000..b466883dc7
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl
@@ -0,0 +1,37 @@
+/**
+ * @file genSkyShV.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$
+ */
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec2 vary_frag;
+
+void main()
+{
+ // pass through untransformed fullscreen pos
+ gl_Position = vec4(position.xyz, 1.0);
+ vary_frag = texcoord0;
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl b/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl
new file mode 100644
index 0000000000..33c5667cae
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl
@@ -0,0 +1,44 @@
+/**
+ * @file class3/deferred/indirect.glsl
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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]*/
+
+uniform sampler2D sh_input_r;
+uniform sampler2D sh_input_g;
+uniform sampler2D sh_input_b;
+
+vec3 GetIndirect(vec3 norm)
+{
+ vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265));
+ vec4 l1r = texture2D(sh_input_r, vec2(0,0));
+ vec4 l1g = texture2D(sh_input_g, vec2(0,0));
+ vec4 l1b = texture2D(sh_input_b, vec2(0,0));
+ vec3 indirect = vec3(dot(l1r, l1tap * vec4(1, norm.xyz)),
+ dot(l1g, l1tap * vec4(1, norm.xyz)),
+ dot(l1b, l1tap * vec4(1, norm.xyz)));
+ indirect = clamp(indirect, vec3(0), vec3(1.0));
+ return indirect;
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/lightUtil.glsl b/indra/newview/app_settings/shaders/class3/deferred/lightUtil.glsl
new file mode 100644
index 0000000000..8bb3f07fc6
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/lightUtil.glsl
@@ -0,0 +1,117 @@
+/**
+ * @file lightInfo.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$
+ */
+
+struct DirectionalLightInfo
+{
+ vec4 pos;
+ float depth;
+ vec4 normal;
+ vec3 normalizedLightDirection;
+ vec3 normalizedToLight;
+ float lightIntensity;
+ vec3 lightDiffuseColor;
+ float specExponent;
+ float shadow;
+};
+
+struct SpotLightInfo
+{
+ vec4 pos;
+ float depth;
+ vec4 normal;
+ vec3 normalizedLightDirection;
+ vec3 normalizedToLight;
+ float lightIntensity;
+ float attenuation;
+ float distanceToLight;
+ vec3 lightDiffuseColor;
+ float innerHalfAngleCos;
+ float outerHalfAngleCos;
+ float spotExponent;
+ float specExponent;
+ float shadow;
+};
+
+struct PointLightInfo
+{
+ vec4 pos;
+ float depth;
+ vec4 normal;
+ vec3 normalizedToLight;
+ float lightIntensity;
+ float attenuation;
+ float distanceToLight;
+ vec3 lightDiffuseColor;
+ float lightRadius;
+ float specExponent;
+ vec3 worldspaceLightDirection;
+ float shadow;
+};
+
+float attenuate(float attenuationSelection, float distanceToLight)
+{
+// LLRENDER_REVIEW
+// sh/could eventually consume attenuation func defined in texture
+ return (attenuationSelection == 0.0f) ? 1.0f : // none
+ (attenuationSelection < 1.0f) ? (1.0f / distanceToLight) : // linear atten
+ (attenuationSelection < 2.0f) ? (1.0f / (distanceToLight*distanceToLight)) // quadratic atten
+ : (1.0f / (distanceToLight*distanceToLight*distanceToLight)); // cubic atten
+}
+
+
+vec3 lightDirectional(struct DirectionalLightInfo dli)
+{
+ float lightIntensity = dli.lightIntensity;
+ lightIntensity *= dot(dli.normal.xyz, dli.normalizedLightDirection);
+ //lightIntensity *= directionalShadowSample(vec4(dli.pos.xyz, 1.0f), dli.depth, dli.directionalShadowMap, dli.directionalShadowMatrix);
+ return lightIntensity * dli.lightDiffuseColor;
+}
+
+
+vec3 lightSpot(struct SpotLightInfo sli)
+{
+ float penumbraRange = (sli.outerHalfAngleCos - sli.innerHalfAngleCos);
+ float coneAngleCos = max(dot(sli.normalizedLightDirection, sli.normalizedToLight), 0.0);
+ float coneAttenFactor = (coneAngleCos <= sli.outerHalfAngleCos) ? 1.0f : pow(smoothstep(1,0, sli.outerHalfAngleCos / penumbraRange), sli.spotExponent);
+ float distanceAttenuation = attenuate(sli.attenuation, sli.distanceToLight);
+ float lightIntensity = sli.lightIntensity;
+ lightIntensity *= distanceAttenuation;
+ lightIntensity *= max(dot(sli.normal.xyz, sli.normalizedLightDirection), 0.0);
+ lightIntensity *= coneAttenFactor;
+ lightIntensity *= sli.shadow;
+ return lightIntensity * sli.lightDiffuseColor;
+}
+
+vec3 lightPoint(struct PointLightInfo pli)
+{
+ float padRadius = pli.lightRadius * 0.1; // distance for which to perform smoothed dropoff past light radius
+ float distanceAttenuation = attenuate(pli.attenuation, pli.distanceToLight);
+ float lightIntensity = pli.lightIntensity;
+ lightIntensity*= distanceAttenuation;
+ lightIntensity *= clamp((padRadius - pli.distanceToLight + pli.lightRadius) / padRadius, 0.0, 1.0);
+ lightIntensity *= pli.shadow;
+ lightIntensity *= max(dot(pli.normal.xyz, pli.normalizedToLight), 0.0);
+ return lightIntensity * pli.lightDiffuseColor;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
new file mode 100644
index 0000000000..9d62b9d180
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
@@ -0,0 +1,291 @@
+/**
+ * @file multiSpotLightF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+#extension GL_ARB_shader_texture_lod : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2DRect diffuseRect;
+uniform sampler2DRect specularRect;
+uniform sampler2DRect depthMap;
+uniform sampler2DRect normalMap;
+uniform samplerCube environmentMap;
+uniform sampler2DRect lightMap;
+uniform sampler2D noiseMap;
+uniform sampler2D projectionMap;
+uniform sampler2D lightFunc;
+
+uniform mat4 proj_mat; //screen space to light space
+uniform float proj_near; //near clip for projection
+uniform vec3 proj_p; //plane projection is emitting from (in screen space)
+uniform vec3 proj_n;
+uniform float proj_focus; //distance from plane to begin blurring
+uniform float proj_lod; //(number of mips in proj map)
+uniform float proj_range; //range between near clip and far clip plane of projection
+uniform float proj_ambient_lod;
+uniform float proj_ambiance;
+uniform float near_clip;
+uniform float far_clip;
+
+uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
+uniform float sun_wash;
+uniform int proj_shadow_idx;
+uniform float shadow_fade;
+
+uniform vec3 center;
+uniform float size;
+uniform vec3 color;
+uniform float falloff;
+
+VARYING vec4 vary_fragcoord;
+uniform vec2 screen_res;
+
+uniform mat4 inv_proj;
+
+vec3 getNorm(vec2 pos_screen);
+
+vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+
+ float det = min(lod/(proj_lod*0.5), 1.0);
+
+ float d = min(dist.x, dist.y);
+
+ d *= min(1, d * (proj_lod - lod));
+
+ float edge = 0.25*det;
+
+ ret *= clamp(d/edge, 0.0, 1.0);
+
+ return ret;
+}
+
+vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+
+ float det = min(lod/(proj_lod*0.5), 1.0);
+
+ float d = min(dist.x, dist.y);
+
+ float edge = 0.25*det;
+
+ ret *= clamp(d/edge, 0.0, 1.0);
+
+ return ret;
+}
+
+vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ vec2 dist = tc-vec2(0.5);
+
+ float d = dot(dist,dist);
+
+ ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
+
+ return ret;
+}
+
+
+vec4 getPosition(vec2 pos_screen);
+
+void main()
+{
+ vec4 frag = vary_fragcoord;
+ frag.xyz /= frag.w;
+ frag.xyz = frag.xyz*0.5+0.5;
+ frag.xy *= screen_res;
+
+ vec3 pos = getPosition(frag.xy).xyz;
+ vec3 lv = center.xyz-pos.xyz;
+ float dist = length(lv);
+ dist /= size;
+ if (dist > 1.0)
+ {
+ discard;
+ }
+
+ float shadow = 1.0;
+
+ if (proj_shadow_idx >= 0)
+ {
+ vec4 shd = texture2DRect(lightMap, frag.xy);
+ shadow = (proj_shadow_idx == 0) ? shd.b : shd.a;
+ shadow += shadow_fade;
+ shadow = clamp(shadow, 0.0, 1.0);
+ }
+
+ vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
+
+ float envIntensity = norm.z;
+
+ norm = getNorm(frag.xy);
+
+ norm = normalize(norm);
+ float l_dist = -dot(lv, proj_n);
+
+ vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
+ if (proj_tc.z < 0.0)
+ {
+ discard;
+ }
+
+ proj_tc.xyz /= proj_tc.w;
+
+ float fa = (falloff*0.5)+1.0;
+ float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0;
+ if (dist_atten <= 0.0)
+ {
+ discard;
+ }
+
+ lv = proj_origin-pos.xyz;
+ lv = normalize(lv);
+ float da = dot(norm, lv);
+
+ vec3 col = vec3(0,0,0);
+
+ vec3 diff_tex = srgb_to_linear(texture2DRect(diffuseRect, frag.xy).rgb);
+
+ vec4 spec = texture2DRect(specularRect, frag.xy);
+
+ vec3 dlit = vec3(0, 0, 0);
+
+ float noise = texture2D(noiseMap, frag.xy/128.0).b;
+ if (proj_tc.z > 0.0 &&
+ proj_tc.x < 1.0 &&
+ proj_tc.y < 1.0 &&
+ proj_tc.x > 0.0 &&
+ proj_tc.y > 0.0)
+ {
+ float amb_da = proj_ambiance;
+ float lit = 0.0;
+
+ if (da > 0.0)
+ {
+ lit = da * dist_atten * noise;
+
+ float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
+ float lod = diff * proj_lod;
+
+ vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
+
+ dlit = color.rgb * plcol.rgb * plcol.a;
+
+ col = dlit*lit*diff_tex*shadow;
+ amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
+ }
+
+ //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
+ vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
+
+ amb_da += (da*da*0.5+0.5)*(1.0-shadow)*proj_ambiance;
+
+ amb_da *= dist_atten * noise;
+
+ amb_da = min(amb_da, 1.0-lit);
+
+ col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
+ }
+
+
+ if (spec.a > 0.0)
+ {
+ vec3 npos = -normalize(pos);
+ dlit *= min(da*6.0, 1.0) * dist_atten;
+
+ //vec3 ref = dot(pos+lv, norm);
+ vec3 h = normalize(lv+npos);
+ float nh = dot(norm, h);
+ float nv = dot(norm, npos);
+ float vh = dot(npos, h);
+ float sa = nh;
+ float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+
+ if (nh > 0.0)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ col += dlit*scol*spec.rgb*shadow;
+ //col += spec.rgb;
+ }
+ }
+
+ if (envIntensity > 0.0)
+ {
+ vec3 ref = reflect(normalize(pos), norm);
+
+ //project from point pos in direction ref to plane proj_p, proj_n
+ vec3 pdelta = proj_p-pos;
+ float ds = dot(ref, proj_n);
+
+ if (ds < 0.0)
+ {
+ vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
+
+ vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
+
+ if (stc.z > 0.0)
+ {
+ stc /= stc.w;
+
+ if (stc.x < 1.0 &&
+ stc.y < 1.0 &&
+ stc.x > 0.0 &&
+ stc.y > 0.0)
+ {
+ col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
+ }
+ }
+ }
+ }
+
+ //not sure why, but this line prevents MATBUG-194
+ col = max(col, vec3(0.0));
+
+ col = scaleDownLight(col);
+
+ //output linear space color as gamma correction happens down stream
+ frag_color.rgb = col;
+ frag_color.a = 0.0;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl
new file mode 100644
index 0000000000..ca9ce3a2e1
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl
@@ -0,0 +1,37 @@
+/**
+ * @file pointShadowBlur.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform samplerCube cube_map;
+
+in vec3 to_vec;
+
+out vec4 fragColor;
+
+void main()
+{
+ vec4 vcol = texture(cube_map, to_vec);
+ fragColor = vec4(vcol.rgb, 1.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl
new file mode 100644
index 0000000000..c8991f7a18
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl
@@ -0,0 +1,73 @@
+/**
+ * @file class3/deferred/shVisF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+ out vec4 frag_color;
+#else
+ #define frag_color gl_FragColor
+#endif
+
+/////////////////////////////////////////////////////////////////////////
+// Fragment shader for L1 SH debug rendering
+/////////////////////////////////////////////////////////////////////////
+
+uniform sampler2D sh_input_r;
+uniform sampler2D sh_input_g;
+uniform sampler2D sh_input_b;
+
+uniform mat3 inv_modelviewprojection;
+
+VARYING vec4 vary_pos;
+
+void main(void)
+{
+ vec2 coord = vary_pos.xy + vec2(0.5,0.5);
+
+ coord.x *= (1.6/0.9);
+
+ if (dot(coord, coord) > 0.25)
+ {
+ discard;
+ }
+
+ vec4 n = vec4(coord*2.0, 0.0, 1);
+ //n.y = -n.y;
+ n.z = sqrt(max(1.0-n.x*n.x-n.y*n.y, 0.0));
+ //n.xyz = inv_modelviewprojection * n.xyz;
+
+ vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265));
+ vec4 l1r = texture2D(sh_input_r, vec2(0,0));
+ vec4 l1g = texture2D(sh_input_g, vec2(0,0));
+ vec4 l1b = texture2D(sh_input_b, vec2(0,0));
+ vec3 indirect = vec3(
+ dot(l1r, l1tap * n),
+ dot(l1g, l1tap * n),
+ dot(l1b, l1tap * n));
+
+ //indirect = pow(indirect, vec3(0.45));
+ indirect *= 3.0;
+
+ frag_color = vec4(indirect, 1.0);
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl
new file mode 100644
index 0000000000..8f32dfde79
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl
@@ -0,0 +1,33 @@
+/**
+ * @file class3/deferred/shVisV.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$
+ */
+ATTRIBUTE vec3 position;
+VARYING vec4 vary_pos;
+
+void main()
+{
+ // Output
+ vary_pos = vec4(position, 1);
+ gl_Position = vary_pos;
+}
diff --git a/indra/newview/llfloaterdeleteenvpreset.h b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl
similarity index 53%
rename from indra/newview/llfloaterdeleteenvpreset.h
rename to indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl
index 1211505273..345c07a354 100644
--- a/indra/newview/llfloaterdeleteenvpreset.h
+++ b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl
@@ -1,6 +1,5 @@
/**
- * @file llfloaterdeleteenvpreset.h
- * @brief Floater to delete a water / sky / day cycle preset.
+ * @file shadowAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -24,39 +23,36 @@
* $/LicenseInfo$
*/
-#ifndef LL_LLFLOATERDELETEENVPRESET_H
-#define LL_LLFLOATERDELETEENVPRESET_H
+/*[EXTRA_CODE_HERE]*/
-#include "llfloater.h"
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
-class LLComboBox;
+uniform sampler2D diffuseMap;
-class LLFloaterDeleteEnvPreset : public LLFloater
+#if !defined(DEPTH_CLAMP)
+VARYING float pos_zd2;
+#endif
+
+VARYING float pos_w;
+
+VARYING float target_pos_x;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 pos;
+
+vec4 computeMoments(float depth, float a);
+
+void main()
{
- LOG_CLASS(LLFloaterDeleteEnvPreset);
+ float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a;
-public:
- LLFloaterDeleteEnvPreset(const LLSD &key);
+ frag_color = computeMoments(length(pos), float a);
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void onOpen(const LLSD& key);
-
- void onBtnDelete();
- void onBtnCancel();
-
-private:
- void populatePresetsList();
- void populateWaterPresetsList();
- void populateSkyPresetsList();
- void populateDayCyclesList();
-
- void postPopulate();
-
- void onDeleteDayCycleConfirmation();
- void onDeleteSkyPresetConfirmation();
- void onDeleteWaterPresetConfirmation();
-
- LLComboBox* mPresetCombo;
-};
-
-#endif // LL_LLFLOATERDELETEENVPRESET_H
+#if !defined(DEPTH_CLAMP)
+ gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0);
+#endif
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl
new file mode 100644
index 0000000000..af1461c297
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl
@@ -0,0 +1,66 @@
+/**
+ * @file shadowAlphaMaskV.glsl
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
+uniform float shadow_target_width;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+#if !defined(DEPTH_CLAMP)
+VARYING float pos_zd2;
+#endif
+
+VARYING float target_pos_x;
+VARYING vec4 pos;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+void passTextureIndex();
+
+void main()
+{
+ //transform vertex
+ vec4 pre_pos = vec4(position.xyz, 1.0);
+ vec4 pos = modelview_projection_matrix * pre_pos;
+ target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
+
+ pos_w = pos.w;
+
+#if !defined(DEPTH_CLAMP)
+ pos_zd2 = pos.z * 0.5;
+
+ gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+#else
+ gl_Position = pos;
+#endif
+
+ passTextureIndex();
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+ vertex_color = diffuse_color;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl
new file mode 100644
index 0000000000..50f1ffd626
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl
@@ -0,0 +1,74 @@
+/**
+ * @file class3/deferred/shadowAlphaMaskF.glsl
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2D diffuseMap;
+
+#if !defined(DEPTH_CLAMP)
+VARYING float pos_zd2;
+#endif
+
+VARYING float pos_w;
+
+VARYING float target_pos_x;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+vec4 getPosition(vec2 screen_coord);
+vec4 computeMoments(float depth, float a);
+
+void main()
+{
+ vec4 pos = getPosition(vary_texcoord0.xy);
+
+ float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a;
+
+ if (alpha < 0.05) // treat as totally transparent
+ {
+ discard;
+ }
+
+ if (alpha < 0.88) // treat as semi-transparent
+ {
+ if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25)
+ {
+ discard;
+ }
+ }
+
+ frag_color = computeMoments(length(pos.xyz), alpha);
+
+#if !defined(DEPTH_CLAMP)
+ gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0);
+#endif
+
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl
new file mode 100644
index 0000000000..6a646f5e9e
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl
@@ -0,0 +1,67 @@
+/**
+ * @file class3/deferred/shadowAlphaMaskV.glsl
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
+uniform float shadow_target_width;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+#if !defined(DEPTH_CLAMP)
+VARYING float pos_zd2;
+#endif
+
+VARYING vec4 pos;
+VARYING float target_pos_x;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+void passTextureIndex();
+
+void main()
+{
+ //transform vertex
+ vec4 pre_pos = vec4(position.xyz, 1.0);
+
+ pos = modelview_projection_matrix * pre_pos;
+
+ target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
+
+#if !defined(DEPTH_CLAMP)
+ pos_zd2 = pos.z * 0.5;
+
+ gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+#else
+ gl_Position = pos;
+#endif
+
+ passTextureIndex();
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+
+ vertex_color = diffuse_color;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl
new file mode 100644
index 0000000000..db8c75fb8a
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl
@@ -0,0 +1,50 @@
+/**
+ * @file class3/deferred/shadowCubeV.glsl
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+
+#if !defined(DEPTH_CLAMP)
+VARYING vec4 post_pos;
+#endif
+
+uniform vec3 box_center;
+uniform vec3 box_size;
+
+void main()
+{
+ //transform vertex
+ vec3 p = position*box_size+box_center;
+ vec4 pos = modelview_projection_matrix*vec4(p.xyz, 1.0);
+
+#if !defined(DEPTH_CLAMP)
+ post_pos = pos;
+
+ gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+#else
+ gl_Position = pos;
+#endif
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl
new file mode 100644
index 0000000000..3350267130
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl
@@ -0,0 +1,49 @@
+/**
+ * @file class3/deferred/shadowF.glsl
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2D diffuseMap;
+
+#if !defined(DEPTH_CLAMP)
+VARYING float pos_zd2;
+#endif
+
+VARYING vec4 pos;
+VARYING float target_pos_x;
+
+vec4 computeMoments(float depth, float a);
+
+void main()
+{
+ frag_color = computeMoments(length(pos), 1.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl
new file mode 100644
index 0000000000..2f69a353e8
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl
@@ -0,0 +1,157 @@
+/**
+ * @file class3/deferred/shadowUtil.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform sampler2D shadowMap0;
+uniform sampler2D shadowMap1;
+uniform sampler2D shadowMap2;
+uniform sampler2D shadowMap3;
+uniform sampler2D shadowMap4;
+uniform sampler2D shadowMap5;
+
+uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+uniform vec2 shadow_res;
+uniform vec2 proj_shadow_res;
+uniform mat4 shadow_matrix[6];
+uniform vec4 shadow_clip;
+uniform float shadow_bias;
+
+uniform float spot_shadow_bias;
+uniform float spot_shadow_offset;
+
+float getDepth(vec2 screenpos);
+vec3 getNorm(vec2 screenpos);
+vec4 getPosition(vec2 pos_screen);
+
+float ReduceLightBleeding(float p_max, float Amount)
+{
+ return smoothstep(Amount, 1, p_max);
+}
+
+float ChebyshevUpperBound(vec2 m, float t, float min_v, float Amount)
+{
+ float p = (t <= m.x) ? 1.0 : 0.0;
+
+ float v = m.y - (m.x*m.x);
+ v = max(v, min_v);
+
+ float d = t - m.x;
+
+ float p_max = v / (v + d*d);
+
+ p_max = ReduceLightBleeding(p_max, Amount);
+
+ return max(p, p_max);
+}
+
+vec4 computeMoments(float depth, float a)
+{
+ float m1 = depth;
+ float dx = dFdx(depth);
+ float dy = dFdy(depth);
+ float m2 = m1*m1 + 0.25 * a * (dx*dx + dy*dy);
+ return vec4(m1, m2, a, max(dx, dy));
+}
+
+float vsmDirectionalSample(vec4 stc, float depth, sampler2D shadowMap, mat4 shadowMatrix)
+{
+ vec4 lpos = shadowMatrix * stc;
+ vec4 moments = texture2D(shadowMap, lpos.xy);
+ return ChebyshevUpperBound(moments.rg, depth - shadow_bias * 256.0f, 0.125, 0.9);
+}
+
+float vsmSpotSample(vec4 stc, float depth, sampler2D shadowMap, mat4 shadowMatrix)
+{
+ vec4 lpos = shadowMatrix * stc;
+ vec4 moments = texture2D(shadowMap, lpos.xy);
+ lpos.xyz /= lpos.w;
+ lpos.xy *= 0.5;
+ lpos.xy += 0.5;
+ return ChebyshevUpperBound(moments.rg, depth - spot_shadow_bias * 16.0f, 0.125, 0.9);
+}
+
+#if VSM_POINT_SHADOWS
+float vsmPointSample(float lightDistance, vec3 lightDirection, samplerCube shadow_cube_map)
+{
+ vec4 moments = textureCube(shadow_cube_map, light_direction);
+ return ChebyshevUpperBound(moments.rg, light_distance, 0.01, 0.25);
+}
+#endif
+
+float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen)
+{
+ if (pos.z < -shadow_clip.w)
+ {
+ discard;
+ }
+
+ float depth = getDepth(pos_screen);
+
+ vec4 spos = vec4(pos,1.0);
+ vec4 near_split = shadow_clip*-0.75;
+ vec4 far_split = shadow_clip*-1.25;
+
+ float shadow = 0.0f;
+ float weight = 1.0;
+
+ if (spos.z < near_split.z)
+ {
+ shadow += vsmDirectionalSample(spos, depth, shadowMap3, shadow_matrix[3]);
+ weight += 1.0f;
+ }
+ if (spos.z < near_split.y)
+ {
+ shadow += vsmDirectionalSample(spos, depth, shadowMap2, shadow_matrix[2]);
+ weight += 1.0f;
+ }
+ if (spos.z < near_split.x)
+ {
+ shadow += vsmDirectionalSample(spos, depth, shadowMap1, shadow_matrix[1]);
+ weight += 1.0f;
+ }
+ if (spos.z > far_split.x)
+ {
+ shadow += vsmDirectionalSample(spos, depth, shadowMap0, shadow_matrix[0]);
+ weight += 1.0f;
+ }
+
+ shadow /= weight;
+
+ return shadow;
+}
+
+float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen)
+{
+ if (pos.z < -shadow_clip.w)
+ {
+ discard;
+ }
+
+ float depth = getDepth(pos_screen);
+
+ pos += norm * spot_shadow_offset;
+ return vsmSpotSample(vec4(pos, 1.0), depth, (index == 0) ? shadowMap4 : shadowMap5, shadow_matrix[4 + index]);
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl
new file mode 100644
index 0000000000..6577fe0ecf
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl
@@ -0,0 +1,62 @@
+/**
+ * @file class3/deferred/shadowV.glsl
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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;
+uniform float shadow_target_width;
+uniform mat4 texture_matrix0;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+
+#if !defined(DEPTH_CLAMP)
+VARYING float pos_zd2;
+#endif
+
+VARYING vec4 pos;
+VARYING float target_pos_x;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+void passTextureIndex();
+
+void main()
+{
+ //transform vertex
+ vec4 pre_pos = vec4(position.xyz, 1.0);
+
+ pos = modelview_projection_matrix * pre_pos;
+
+ target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
+
+#if !defined(DEPTH_CLAMP)
+ pos_zd2 = pos.z * 0.5;
+
+ gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+#else
+ gl_Position = pos;
+#endif
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl
new file mode 100644
index 0000000000..6de01cb667
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl
@@ -0,0 +1,111 @@
+/**
+ * @file class3/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$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+
+VARYING vec2 vary_frag;
+
+uniform vec3 camPosLocal;
+uniform vec3 sun_dir;
+uniform float sun_size;
+uniform float far_z;
+uniform mat4 inv_proj;
+uniform mat4 inv_modelview;
+
+uniform sampler2D transmittance_texture;
+uniform sampler3D scattering_texture;
+uniform sampler3D single_mie_scattering_texture;
+uniform sampler2D irradiance_texture;
+uniform sampler2D rainbow_map;
+uniform sampler2D halo_map;
+
+uniform float moisture_level;
+uniform float droplet_radius;
+uniform float ice_level;
+
+vec3 GetSolarLuminance();
+vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance);
+vec3 GetSkyLuminanceToPoint(vec3 camPos, vec3 pos, float shadow_length, vec3 dir, out vec3 transmittance);
+
+vec3 ColorFromRadiance(vec3 radiance);
+vec3 rainbow(float d)
+{
+ 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)
+{
+ float v = sqrt(max(0, 1 - (d*d)));
+ return texture2D(halo_map, vec2(0, v)).rgb * ice_level;
+}
+
+void main()
+{
+ vec3 pos = vec3((vary_frag * 2.0) - vec2(1.0, 1.0f), 1.0);
+ vec4 view_pos = (inv_proj * vec4(pos, 1.0f));
+
+ view_pos /= view_pos.w;
+
+ vec3 view_ray = (inv_modelview * vec4(view_pos.xyz, 0.0f)).xyz + camPosLocal;
+
+ vec3 view_direction = normalize(view_ray);
+ vec3 sun_direction = normalize(sun_dir);
+ vec3 earth_center = vec3(0, 0, -6360.0f);
+ vec3 camPos = (camPosLocal / 1000.0f) - earth_center;
+
+ vec3 transmittance;
+ vec3 radiance_sun = GetSkyLuminance(camPos, view_direction, 0.0f, sun_direction, transmittance);
+ vec3 solar_luminance = GetSolarLuminance();
+
+ // If the view ray intersects the Sun, add the Sun radiance.
+ float s = dot(view_direction, sun_direction);
+
+ // cheesy solar disc...
+ if (s >= (sun_size * 0.999))
+ {
+ radiance_sun += pow(smoothstep(0.0, 1.3, (s - (sun_size * 0.9))), 2.0) * solar_luminance * transmittance;
+ }
+ s = smoothstep(0.9, 1.0, s) * 16.0f;
+
+ vec3 color = ColorFromRadiance(radiance_sun);
+
+ float optic_d = dot(view_direction, sun_direction);
+ vec3 halo_22 = halo22(optic_d);
+
+ color.rgb += rainbow(optic_d) * optic_d;
+ color.rgb += halo_22;
+
+ color = pow(color, vec3(1.0/2.2));
+
+ frag_data[0] = vec4(color, 1.0 + s);
+ frag_data[1] = vec4(0.0);
+ frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class3/deferred/skyV.glsl
new file mode 100644
index 0000000000..2eb222ada4
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/skyV.glsl
@@ -0,0 +1,37 @@
+/**
+ * @file class3/deferred/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$
+ */
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec2 vary_frag;
+
+void main()
+{
+ // pass through untransformed fullscreen pos at back of frustum for proper sky depth testing
+ gl_Position = vec4(position.xy, 1.0f, 1.0);
+ vary_frag = texcoord0;
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
new file mode 100644
index 0000000000..7ed9e7b4fc
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -0,0 +1,177 @@
+/**
+ * @file class3/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$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2DRect diffuseRect;
+uniform sampler2DRect specularRect;
+uniform sampler2DRect normalMap;
+uniform sampler2DRect lightMap;
+uniform sampler2DRect depthMap;
+uniform sampler2D lightFunc;
+
+uniform samplerCube environmentMap;
+uniform float blur_size;
+uniform float blur_fidelity;
+
+// Inputs
+uniform vec4 morphFactor;
+uniform vec3 camPosLocal;
+uniform float cloud_shadow;
+uniform float max_y;
+uniform vec4 glow;
+uniform mat3 env_mat;
+uniform vec4 shadow_clip;
+
+uniform vec3 sun_dir;
+VARYING vec2 vary_fragcoord;
+
+uniform mat4 inv_proj;
+uniform mat4 inv_modelview;
+
+uniform vec2 screen_res;
+
+uniform sampler2D transmittance_texture;
+uniform sampler3D scattering_texture;
+uniform sampler3D single_mie_scattering_texture;
+uniform sampler2D irradiance_texture;
+
+uniform sampler2D sh_input_r;
+uniform sampler2D sh_input_g;
+uniform sampler2D sh_input_b;
+
+vec3 GetSunAndSkyIrradiance(vec3 camPos, vec3 norm, vec3 dir, out vec3 sky_irradiance);
+vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance);
+vec3 GetSkyLuminanceToPoint(vec3 camPos, vec3 pos, float shadow_length, vec3 dir, out vec3 transmittance);
+
+vec3 ColorFromRadiance(vec3 radiance);
+vec4 getPositionWithDepth(vec2 pos_screen, float depth);
+vec4 getPosition(vec2 pos_screen);
+vec3 getNorm(vec2 pos_screen);
+
+#ifdef WATER_FOG
+vec4 applyWaterFogView(vec3 pos, vec4 color);
+#endif
+
+void main()
+{
+ vec2 tc = vary_fragcoord.xy;
+ float depth = texture2DRect(depthMap, tc.xy).r;
+ vec3 pos = getPositionWithDepth(tc, depth).xyz;
+ vec4 norm = texture2DRect(normalMap, tc);
+ float envIntensity = norm.z;
+ norm.xyz = getNorm(tc);
+
+ float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
+
+ vec4 diffuse = texture2DRect(diffuseRect, tc); // sRGB
+ diffuse.rgb = srgb_to_linear(diffuse.rgb);
+
+ vec3 col;
+ float bloom = 0.0;
+ {
+ vec3 camPos = (camPosLocal / 1000.0f) + vec3(0, 0, 6360.0f);
+
+ vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
+
+ vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
+
+ float scol = max(scol_ambocc.r, diffuse.a);
+
+ float ambocc = scol_ambocc.g;
+
+ vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265));
+ vec4 l1r = texture2D(sh_input_r, vec2(0,0));
+ vec4 l1g = texture2D(sh_input_g, vec2(0,0));
+ vec4 l1b = texture2D(sh_input_b, vec2(0,0));
+
+ vec3 indirect = vec3(dot(l1r, l1tap * vec4(1, norm.xyz)),
+ dot(l1g, l1tap * vec4(1, norm.xyz)),
+ dot(l1b, l1tap * vec4(1, norm.xyz)));
+
+ indirect = clamp(indirect, vec3(0), vec3(1.0));
+
+ vec3 transmittance;
+ vec3 sky_irradiance;
+ vec3 sun_irradiance = GetSunAndSkyIrradiance(camPos, norm.xyz, sun_dir, sky_irradiance);
+ vec3 inscatter = GetSkyLuminanceToPoint(camPos, (pos / 1000.f) + vec3(0, 0, 6360.0f), scol, sun_dir, transmittance);
+
+ vec3 radiance = scol * (sun_irradiance + sky_irradiance) + inscatter;
+ vec3 atmo_color = ColorFromRadiance(radiance);
+
+ col = atmo_color + indirect;
+ col *= transmittance;
+ col *= diffuse.rgb;
+
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+
+ if (spec.a > 0.0) // specular reflection
+ {
+ // the old infinite-sky shiny reflection
+ //
+ float sa = dot(refnormpersp, sun_dir.xyz);
+ vec3 dumbshiny = scol * texture2D(lightFunc, vec2(sa, spec.a)).r * atmo_color;
+
+ // add the two types of shiny together
+ vec3 spec_contrib = dumbshiny * spec.rgb * 0.25;
+ bloom = dot(spec_contrib, spec_contrib);
+ col += spec_contrib;
+ }
+
+ col = mix(col, diffuse.rgb, diffuse.a);
+
+ if (envIntensity > 0.0)
+ { //add environmentmap
+ vec3 env_vec = env_mat * refnormpersp;
+ vec3 sun_direction = (inv_modelview * vec4(sun_dir, 1.0)).xyz;
+ vec3 radiance_sun = GetSkyLuminance(camPos, env_vec, 0.0f, sun_direction, transmittance);
+ vec3 refcol = ColorFromRadiance(radiance_sun);
+ col = mix(col.rgb, refcol, envIntensity);
+ }
+
+ /*if (norm.w < 0.5)
+ {
+ col = scaleSoftClipFrag(col);
+ }*/
+
+ #ifdef WATER_FOG
+ vec4 fogged = applyWaterFogView(pos,vec4(col, bloom));
+ col = fogged.rgb;
+ bloom = fogged.a;
+ #endif
+ }
+
+ //output linear since gamma correction happens down stream
+ frag_color.rgb = col;
+ frag_color.a = bloom;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl
new file mode 100644
index 0000000000..9d872b8df8
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl
@@ -0,0 +1,38 @@
+/**
+ * @file class3/deferred/softenLightV.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$
+ */
+ATTRIBUTE vec3 position;
+
+VARYING vec2 vary_fragcoord;
+
+uniform mat4 modelview_projection_matrix;
+uniform vec2 screen_res;
+
+void main()
+{
+ //transform vertex
+ vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ gl_Position = pos;
+ vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
new file mode 100644
index 0000000000..56b0f4e5ce
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
@@ -0,0 +1,287 @@
+/**
+ * @file spotLightF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+#extension GL_ARB_shader_texture_lod : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2DRect diffuseRect;
+uniform sampler2DRect specularRect;
+uniform sampler2DRect depthMap;
+uniform sampler2DRect normalMap;
+uniform samplerCube environmentMap;
+uniform sampler2DRect lightMap;
+uniform sampler2D noiseMap;
+uniform sampler2D projectionMap;
+uniform sampler2D lightFunc;
+
+uniform mat4 proj_mat; //screen space to light space
+uniform float proj_near; //near clip for projection
+uniform vec3 proj_p; //plane projection is emitting from (in screen space)
+uniform vec3 proj_n;
+uniform float proj_focus; //distance from plane to begin blurring
+uniform float proj_lod; //(number of mips in proj map)
+uniform float proj_range; //range between near clip and far clip plane of projection
+uniform float proj_ambient_lod;
+uniform float proj_ambiance;
+uniform float near_clip;
+uniform float far_clip;
+
+uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
+uniform float sun_wash;
+uniform int proj_shadow_idx;
+uniform float shadow_fade;
+
+uniform float size;
+uniform vec3 color;
+uniform float falloff;
+
+VARYING vec3 trans_center;
+VARYING vec4 vary_fragcoord;
+uniform vec2 screen_res;
+
+uniform mat4 inv_proj;
+
+vec3 getNorm(vec2 pos_screen);
+
+vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+
+ float det = min(lod/(proj_lod*0.5), 1.0);
+
+ float d = min(dist.x, dist.y);
+
+ d *= min(1, d * (proj_lod - lod));
+
+ float edge = 0.25*det;
+
+ ret *= clamp(d/edge, 0.0, 1.0);
+
+ return ret;
+}
+
+vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+
+ float det = min(lod/(proj_lod*0.5), 1.0);
+
+ float d = min(dist.x, dist.y);
+
+ float edge = 0.25*det;
+
+ ret *= clamp(d/edge, 0.0, 1.0);
+
+ return ret;
+}
+
+vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ vec2 dist = tc-vec2(0.5);
+
+ float d = dot(dist,dist);
+
+ ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
+
+ return ret;
+}
+
+
+vec4 getPosition(vec2 pos_screen);
+
+void main()
+{
+ vec4 frag = vary_fragcoord;
+ frag.xyz /= frag.w;
+ frag.xyz = frag.xyz*0.5+0.5;
+ frag.xy *= screen_res;
+
+ vec3 pos = getPosition(frag.xy).xyz;
+ vec3 lv = trans_center.xyz-pos.xyz;
+ float dist = length(lv);
+ dist /= size;
+ if (dist > 1.0)
+ {
+ discard;
+ }
+
+ float shadow = 1.0;
+
+ if (proj_shadow_idx >= 0)
+ {
+ vec4 shd = texture2DRect(lightMap, frag.xy);
+ shadow = (proj_shadow_idx == 0) ? shd.b : shd.a;
+ shadow += shadow_fade;
+ shadow = clamp(shadow, 0.0, 1.0);
+ }
+
+ vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
+ float envIntensity = norm.z;
+ norm = getNorm(frag.xy);
+
+ norm = normalize(norm);
+ float l_dist = -dot(lv, proj_n);
+
+ vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
+ if (proj_tc.z < 0.0)
+ {
+ discard;
+ }
+
+ proj_tc.xyz /= proj_tc.w;
+
+ float fa = (falloff*0.5) + 1.0;
+ float dist_atten = min(1.0 - (dist - 1.0 * (1.0 - fa)) / fa, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0;
+
+ if (dist_atten <= 0.0)
+ {
+ discard;
+ }
+
+ lv = proj_origin-pos.xyz;
+ lv = normalize(lv);
+ float da = dot(norm, lv);
+
+ vec3 col = vec3(0,0,0);
+
+ vec3 diff_tex = srgb_to_linear(texture2DRect(diffuseRect, frag.xy).rgb);
+
+ vec4 spec = texture2DRect(specularRect, frag.xy);
+
+ vec3 dlit = vec3(0, 0, 0);
+
+ float noise = texture2D(noiseMap, frag.xy/128.0).b;
+ if (proj_tc.z > 0.0 &&
+ proj_tc.x < 1.0 &&
+ proj_tc.y < 1.0 &&
+ proj_tc.x > 0.0 &&
+ proj_tc.y > 0.0)
+ {
+ float amb_da = proj_ambiance;
+ float lit = 0.0;
+
+ if (da > 0.0)
+ {
+ lit = da * dist_atten * noise;
+
+ float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
+ float lod = diff * proj_lod;
+
+ vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
+
+ dlit = color.rgb * plcol.rgb * plcol.a;
+
+ col = dlit*lit*diff_tex*shadow;
+ amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
+ }
+
+ //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
+ vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
+
+ amb_da += (da*da*0.5+0.5)*(1.0-shadow)*proj_ambiance;
+
+ amb_da *= dist_atten * noise;
+
+ amb_da = min(amb_da, 1.0-lit);
+
+ col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
+ }
+
+
+ if (spec.a > 0.0)
+ {
+ dlit *= min(da*6.0, 1.0) * dist_atten;
+ vec3 npos = -normalize(pos);
+
+ //vec3 ref = dot(pos+lv, norm);
+ vec3 h = normalize(lv+npos);
+ float nh = dot(norm, h);
+ float nv = dot(norm, npos);
+ float vh = dot(npos, h);
+ float sa = nh;
+ float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+
+ if (nh > 0.0)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ col += dlit*scol*spec.rgb*shadow;
+ }
+ }
+
+
+ if (envIntensity > 0.0)
+ {
+ vec3 ref = reflect(normalize(pos), norm);
+
+ //project from point pos in direction ref to plane proj_p, proj_n
+ vec3 pdelta = proj_p-pos;
+ float ds = dot(ref, proj_n);
+
+ if (ds < 0.0)
+ {
+ vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
+
+ vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
+
+ if (stc.z > 0.0)
+ {
+ stc /= stc.w;
+
+ if (stc.x < 1.0 &&
+ stc.y < 1.0 &&
+ stc.x > 0.0 &&
+ stc.y > 0.0)
+ {
+ col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
+ }
+ }
+ }
+ }
+
+ //not sure why, but this line prevents MATBUG-194
+ col = max(col, vec3(0.0));
+
+ frag_color.rgb = col;
+ frag_color.a = 0.0;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl
new file mode 100644
index 0000000000..112b498c90
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl
@@ -0,0 +1,57 @@
+/**
+ * @file class3\deferred\sunLightF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+//class 2, shadows, no SSAO
+
+// Inputs
+VARYING vec2 vary_fragcoord;
+
+vec4 getPosition(vec2 pos_screen);
+vec3 getNorm(vec2 pos_screen);
+
+float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
+float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen);
+
+void main()
+{
+ vec2 pos_screen = vary_fragcoord.xy;
+ vec4 pos = getPosition(pos_screen);
+ vec3 norm = getNorm(pos_screen);
+
+ frag_color.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen);
+ frag_color.g = 1.0f;
+ frag_color.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen);
+ frag_color.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen);
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl
new file mode 100644
index 0000000000..342a2ff3ed
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl
@@ -0,0 +1,61 @@
+/**
+ * @file class3\deferred\sunLightSSAOF.glsl
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+//class 2 -- shadows and SSAO
+
+// Inputs
+VARYING vec2 vary_fragcoord;
+
+uniform vec3 sun_dir;
+
+vec4 getPosition(vec2 pos_screen);
+vec3 getNorm(vec2 pos_screen);
+
+float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
+float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen);
+
+//calculate decreases in ambient lighting when crowded out (SSAO)
+float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen);
+
+void main()
+{
+ vec2 pos_screen = vary_fragcoord.xy;
+ vec4 pos = getPosition(pos_screen);
+ vec3 norm = getNorm(pos_screen);
+
+ frag_color.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen);
+ frag_color.b = calcAmbientOcclusion(pos, norm, pos_screen);
+ frag_color.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen);
+ frag_color.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen);
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/sunLightV.glsl b/indra/newview/app_settings/shaders/class3/deferred/sunLightV.glsl
new file mode 100644
index 0000000000..bc5eb5181d
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/sunLightV.glsl
@@ -0,0 +1,41 @@
+/**
+ * @file sunLightV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+
+VARYING vec2 vary_fragcoord;
+
+uniform vec2 screen_res;
+
+void main()
+{
+ //transform vertex
+ vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ gl_Position = pos;
+
+ vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl
new file mode 100644
index 0000000000..41673d1669
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl
@@ -0,0 +1,59 @@
+/**
+ * @file treeShadowF.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$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform float minimum_alpha;
+
+uniform sampler2D diffuseMap;
+
+VARYING vec4 pos;
+VARYING vec2 vary_texcoord0;
+
+vec4 computeMoments(float d, float a);
+
+void main()
+{
+ float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a;
+
+ if (alpha < minimum_alpha)
+ {
+ discard;
+ }
+
+ frag_color = computeMoments(length(pos), 1.0);
+
+#if !defined(DEPTH_CLAMP)
+ gl_FragDepth = max(pos.z/pos.w*0.5+0.5, 0.0);
+#endif
+
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/treeShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/treeShadowV.glsl
new file mode 100644
index 0000000000..15e769ac10
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/treeShadowV.glsl
@@ -0,0 +1,43 @@
+/**
+ * @file treeShadowV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 pos;
+VARYING vec2 vary_texcoord0;
+
+void main()
+{
+ //transform vertex
+ pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
+
+ gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/deferred/underWaterF.glsl
new file mode 100644
index 0000000000..540226e672
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/underWaterF.glsl
@@ -0,0 +1,115 @@
+/**
+ * @file underWaterF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+
+uniform sampler2D diffuseMap;
+uniform sampler2D bumpMap;
+uniform sampler2D screenTex;
+uniform sampler2D refTex;
+uniform sampler2D screenDepth;
+
+uniform vec4 fogCol;
+uniform vec3 lightDir;
+uniform vec3 specular;
+uniform float lightExp;
+uniform vec2 fbScale;
+uniform float refScale;
+uniform float znear;
+uniform float zfar;
+uniform float kd;
+uniform vec4 waterPlane;
+uniform vec3 eyeVec;
+uniform vec4 waterFogColor;
+uniform float waterFogDensity;
+uniform float waterFogKS;
+uniform vec2 screenRes;
+
+//bigWave is (refCoord.w, view.w);
+VARYING vec4 refCoord;
+VARYING vec4 littleWave;
+VARYING vec4 view;
+
+vec2 encode_normal(vec3 n);
+
+vec4 applyWaterFog(vec4 color, vec3 viewVec)
+{
+ //normalize view vector
+ vec3 view = normalize(viewVec);
+ float es = -view.z;
+
+ //find intersection point with water plane and eye vector
+
+ //get eye depth
+ float e0 = max(-waterPlane.w, 0.0);
+
+ //get object depth
+ float depth = length(viewVec);
+
+ //get "thickness" of water
+ float l = max(depth, 0.1);
+
+ float kd = waterFogDensity;
+ float ks = waterFogKS;
+ vec4 kc = waterFogColor;
+
+ float F = 0.98;
+
+ float t1 = -kd * pow(F, ks * e0);
+ float t2 = kd + ks * es;
+ float t3 = pow(F, t2*l) - 1.0;
+
+ float L = min(t1/t2*t3, 1.0);
+
+ float D = pow(0.98, l*kd);
+ return color * D + kc * L;
+}
+
+void main()
+{
+ vec4 color;
+
+ //get detail normals
+ vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
+ vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
+ vec3 wavef = normalize(wave1+wave2+wave3);
+
+ //figure out distortion vector (ripply)
+ vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
+ distort = distort+wavef.xy*refScale;
+
+ vec4 fb = texture2D(screenTex, distort);
+
+ frag_data[0] = vec4(fb.rgb, 1.0); // diffuse
+ frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
+ frag_data[2] = vec4(encode_normal(wavef), 0.0, 0.0); // normalxyz, displace
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl
new file mode 100644
index 0000000000..c65cf48c67
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl
@@ -0,0 +1,174 @@
+/**
+ * @file waterF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+
+uniform sampler2D bumpMap;
+uniform sampler2D bumpMap2;
+uniform float blend_factor;
+uniform sampler2D screenTex;
+uniform sampler2D refTex;
+
+uniform float sunAngle;
+uniform float sunAngle2;
+uniform vec3 lightDir;
+uniform vec3 specular;
+uniform float lightExp;
+uniform float refScale;
+uniform float kd;
+uniform vec2 screenRes;
+uniform vec3 normScale;
+uniform float fresnelScale;
+uniform float fresnelOffset;
+uniform float blurMultiplier;
+uniform vec2 screen_res;
+uniform mat4 norm_mat; //region space to screen space
+
+//bigWave is (refCoord.w, view.w);
+VARYING vec4 refCoord;
+VARYING vec4 littleWave;
+VARYING vec4 view;
+VARYING vec4 vary_position;
+
+vec3 scaleSoftClip(vec3 c);
+vec2 encode_normal(vec3 n);
+
+vec3 BlendNormal(vec3 bump1, vec3 bump2)
+{
+ //vec3 normal = bump1.xyz * vec3( 2.0, 2.0, 2.0) - vec3(1.0, 1.0, 0.0);
+ //vec3 normal2 = bump2.xyz * vec3(-2.0, -2.0, 2.0) + vec3(1.0, 1.0, -1.0);
+ //vec3 n = normalize(normal * dot(normal, normal2) - (normal2 * normal.z));
+ vec3 n = normalize(mix(bump1, bump2, blend_factor));
+ return n;
+}
+
+void main()
+{
+ vec4 color;
+ float dist = length(view.xy);
+
+ //normalize view vector
+ vec3 viewVec = normalize(view.xyz);
+
+ //get wave normals
+ vec3 wave1_a = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
+ vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
+
+
+ vec3 wave1_b = texture2D(bumpMap2, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
+ vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
+
+ vec3 wave1 = BlendNormal(wave1_a, wave1_b);
+ vec3 wave2 = BlendNormal(wave2_a, wave2_b);
+ vec3 wave3 = BlendNormal(wave3_a, wave3_b);
+
+ //get base fresnel components
+
+ vec3 df = vec3(
+ dot(viewVec, wave1),
+ dot(viewVec, (wave2 + wave3) * 0.5),
+ dot(viewVec, wave3)
+ ) * fresnelScale + fresnelOffset;
+ df *= df;
+
+ vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
+
+ float dist2 = dist;
+ dist = max(dist, 5.0);
+
+ float dmod = sqrt(dist);
+
+ vec2 dmod_scale = vec2(dmod*dmod, dmod);
+
+ //get reflected color
+ vec2 refdistort1 = wave1.xy*normScale.x;
+ vec2 refvec1 = distort+refdistort1/dmod_scale;
+ vec4 refcol1 = texture2D(refTex, refvec1);
+
+ vec2 refdistort2 = wave2.xy*normScale.y;
+ vec2 refvec2 = distort+refdistort2/dmod_scale;
+ vec4 refcol2 = texture2D(refTex, refvec2);
+
+ vec2 refdistort3 = wave3.xy*normScale.z;
+ vec2 refvec3 = distort+refdistort3/dmod_scale;
+ vec4 refcol3 = texture2D(refTex, refvec3);
+
+ vec4 refcol = refcol1 + refcol2 + refcol3;
+ float df1 = df.x + df.y + df.z;
+ refcol *= df1 * 0.333;
+
+ vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
+ wavef.z *= max(-viewVec.z, 0.1);
+ wavef = normalize(wavef);
+
+ float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
+
+ vec2 refdistort4 = wavef.xy*0.125;
+ refdistort4.y -= abs(refdistort4.y);
+ vec2 refvec4 = distort+refdistort4/dmod;
+ float dweight = min(dist2*blurMultiplier, 1.0);
+ vec4 baseCol = texture2D(refTex, refvec4);
+
+ refcol = mix(baseCol*df2, refcol, dweight);
+
+ //get specular component
+ float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
+
+ //harden specular
+ spec = pow(spec, 128.0);
+
+ //figure out distortion vector (ripply)
+ vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
+
+ vec4 fb = texture2D(screenTex, distort2);
+
+ //mix with reflection
+ // Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug
+ color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
+
+ color.rgb *= 2.0f;
+ color.rgb = scaleSoftClip(color.rgb);
+
+ vec4 pos = vary_position;
+
+ color.rgb += spec * specular;
+ color.a = spec * sunAngle2;
+
+ vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz);
+
+ frag_data[0] = vec4(color.rgb, color); // diffuse
+ frag_data[1] = vec4(spec * specular, spec); // speccolor, spec
+ frag_data[2] = vec4(encode_normal(wavef.xyz), 0.05, 0);// normalxy, 0, 0
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterV.glsl
new file mode 100644
index 0000000000..02000d90ca
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/waterV.glsl
@@ -0,0 +1,95 @@
+/**
+ * @file waterV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+
+
+uniform vec2 d1;
+uniform vec2 d2;
+uniform float time;
+uniform vec3 eyeVec;
+uniform float waterHeight;
+
+VARYING vec4 refCoord;
+VARYING vec4 littleWave;
+VARYING vec4 view;
+
+VARYING vec4 vary_position;
+
+float wave(vec2 v, float t, float f, vec2 d, float s)
+{
+ return (dot(d, v)*f + t*s)*f;
+}
+
+void main()
+{
+ //transform vertex
+ vec4 pos = vec4(position.xyz, 1.0);
+ mat4 modelViewProj = modelview_projection_matrix;
+
+ vec4 oPosition;
+
+ //get view vector
+ vec3 oEyeVec;
+ oEyeVec.xyz = pos.xyz-eyeVec;
+
+ float d = length(oEyeVec.xy);
+ float ld = min(d, 2560.0);
+
+ pos.xy = eyeVec.xy + oEyeVec.xy/d*ld;
+ view.xyz = oEyeVec;
+
+ d = clamp(ld/1536.0-0.5, 0.0, 1.0);
+ d *= d;
+
+ oPosition = vec4(position, 1.0);
+ oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d);
+ vary_position = modelview_matrix * oPosition;
+ oPosition = modelViewProj * oPosition;
+
+ refCoord.xyz = oPosition.xyz + vec3(0,0,0.2);
+
+ //get wave position parameter (create sweeping horizontal waves)
+ vec3 v = pos.xyz;
+ v.x += (cos(v.x*0.08/*+time*0.01*/)+sin(v.y*0.02))*6.0;
+
+ //push position for further horizon effect.
+ pos.xyz = oEyeVec.xyz*(waterHeight/oEyeVec.z);
+ pos.w = 1.0;
+ pos = modelview_matrix*pos;
+
+ //pass wave parameters to pixel shader
+ vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055;
+ //get two normal map (detail map) texture coordinates
+ littleWave.xy = (v.xy) * vec2(0.45, 0.9) + d2 * time * 0.13;
+ littleWave.zw = (v.xy) * vec2(0.1, 0.2) + d1 * time * 0.1;
+ view.w = bigWave.y;
+ refCoord.w = bigWave.x;
+
+ gl_Position = oPosition;
+}
diff --git a/indra/newview/app_settings/shaders/class3/lighting/lightV.glsl b/indra/newview/app_settings/shaders/class3/lighting/lightV.glsl
new file mode 100644
index 0000000000..30ad493331
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/lighting/lightV.glsl
@@ -0,0 +1,43 @@
+/**
+ * @file class3\lighting\lightV.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$
+ */
+
+
+
+// All lights, no specular highlights
+vec3 atmosAmbient();
+vec4 sumLights(vec3 pos, vec3 norm, vec4 color);
+float getAmbientClamp();
+
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color)
+{
+ vec4 c = sumLights(pos, norm, color);
+
+#if !defined(AMBIENT_KILL)
+ c.rgb += atmosAmbient() * color.rgb * getAmbientClamp();
+#endif
+
+ return c;
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl
index e043ac873e..c1aee69c30 100644
--- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl
+++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl
@@ -1,5 +1,5 @@
/**
- * @file sumLightsV.glsl
+ * @file class3\lighting\sumLightsSpecularV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -26,16 +26,16 @@
float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da);
vec3 calcPointLightSpecular(inout vec4 specular, vec3 view, vec3 v, vec3 n, vec3 l, float r, float pw, vec3 lightCol);
-vec3 atmosAmbient(vec3 light);
+vec3 atmosAmbient();
vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 atmosGetDiffuseSunlightColor();
vec3 scaleDownLight(vec3 light);
uniform vec4 light_position[8];
-uniform vec3 light_attenuation[8];
+uniform vec4 light_attenuation[8];
uniform vec3 light_diffuse[8];
-vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol)
+vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor)
{
vec4 col = vec4(0.0, 0.0, 0.0, color.a);
@@ -55,8 +55,8 @@ vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor
col.rgb = scaleDownLight(col.rgb);
// Add windlight lights
- col.rgb += atmosAmbient(baseCol.rgb);
- col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, light_position[0].xyz,atmosGetDiffuseSunlightColor()*baseCol.a, 1.0));
+ col.rgb += atmosAmbient();
+ col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, light_position[0].xyz,atmosGetDiffuseSunlightColor(), 1.0));
col.rgb = min(col.rgb*color.rgb, 1.0);
specularColor.rgb = min(specularColor.rgb*specularSum.rgb, 1.0);
diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
index dadff40933..4b663dd5b2 100644
--- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
+++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
@@ -1,5 +1,5 @@
/**
- * @file sumLightsV.glsl
+ * @file class3\lighting\sumLightsV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -25,37 +25,40 @@
float calcDirectionalLight(vec3 n, vec3 l);
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight);
-vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 scaleDownLight(vec3 light);
-vec3 scaleUpLight(vec3 light);
uniform vec4 light_position[8];
uniform vec3 light_direction[8];
-uniform vec3 light_attenuation[8];
+uniform vec4 light_attenuation[8];
uniform vec3 light_diffuse[8];
-vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight)
+vec4 sumLights(vec3 pos, vec3 norm, vec4 color)
{
vec4 col = vec4(0.0, 0.0, 0.0, color.a);
// Collect normal lights (need to be divided by two, as we later multiply by 2)
// Collect normal lights
- col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
- col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
- col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].z);
- col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].z);
- col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].z);
- col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].z);
+ col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
+ col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
+ col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
+ col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
+ col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
+ col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
col.rgb += light_diffuse[1].rgb*calcDirectionalLight(norm, light_position[1].xyz);
- col.rgb = scaleDownLight(col.rgb);
+ col.rgb = scaleDownLight(col.rgb);
+
+#if defined(LOCAL_LIGHT_KILL)
+ col.rgb = vec3(0);
+#endif
// Add windlight lights
+#if !defined(SUNLIGHT_KILL)
col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, light_position[0].xyz));
- col.rgb += atmosAmbient(baseLight.rgb);
+#endif
col.rgb = min(col.rgb*color.rgb, 1.0);
diff --git a/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl
new file mode 100644
index 0000000000..c6ea3ec9d4
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl
@@ -0,0 +1,73 @@
+/**
+ * @file class3\wl\advancedAtmoF.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$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+in vec3 view_dir;
+
+uniform vec3 cameraPosLocal;
+uniform vec3 sun_dir;
+uniform float sun_size;
+
+uniform sampler2D transmittance_texture;
+uniform sampler3D scattering_texture;
+uniform sampler3D mie_scattering_texture;
+uniform sampler2D irradiance_texture;
+
+vec3 GetSolarLuminance();
+vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 sun_dir, out vec3 transmittance);
+vec3 GetSkyLuminanceToPoint(vec3 camPos, vec3 pos, float shadow_length, vec3 sun_dir, out vec3 transmittance);
+vec3 GetSunAndSkyIlluminance(vec3 pos, vec3 norm, vec3 sun_dir, out vec3 sky_irradiance);
+
+void main()
+{
+ vec3 view_direction = normalize(view_dir);
+
+ vec3 camPos = cameraPosLocal;
+ vec3 transmittance;
+ vec3 sky_illum;
+ vec3 radiance = GetSkyLuminance(camPos, view_direction, 0.0f, sun_dir, transmittance);
+ vec3 radiance2 = GetSunAndSkyIlluminance(camPos, view_direction, sun_dir, sky_illum);
+
+ //radiance *= transmittance;
+
+ // If the view ray intersects the Sun, add the Sun radiance.
+ if (dot(view_direction, sun_dir) >= sun_size)
+ {
+ radiance = radiance + transmittance * GetSolarLuminance();
+ }
+
+ //vec3 color = vec3(1.0) - exp(-radiance);
+ //color = pow(color, vec3(1.0 / 2.2));
+
+ frag_color.rgb = radiance;
+
+ frag_color.a = 1.0;
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl
new file mode 100644
index 0000000000..65bb00b1f6
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl
@@ -0,0 +1,43 @@
+/**
+ * @file class3\wl\advancedAtmoV.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;
+
+// Inputs
+uniform vec3 camPosLocal;
+
+out vec3 view_dir;
+
+void main()
+{
+ // World / view / projection
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+
+ // this will be normalized in the frag shader...
+ view_dir = position.xyz - camPosLocal.xyz;
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl
new file mode 100644
index 0000000000..2b70ba76dc
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl
@@ -0,0 +1,46 @@
+/**
+ * @file class3\wl\atmosphericsF.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$
+ */
+
+vec3 getAdditiveColor();
+vec3 getAtmosAttenuation();
+vec3 scaleSoftClipFrag(vec3 light);
+
+uniform int no_atmo;
+
+vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
+{
+ if (no_atmo == 1)
+ {
+ return light;
+ }
+ light *= atten.r;
+ light += additive;
+ return light * 2.0;
+}
+
+vec3 atmosLighting(vec3 light)
+{
+ return atmosFragLighting(light, getAdditiveColor(), getAtmosAttenuation());
+}
diff --git a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl
new file mode 100644
index 0000000000..b76192d73f
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl
@@ -0,0 +1,51 @@
+/**
+ * @file class3\wl\atmosphericsV.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$
+ */
+
+// VARYING param funcs
+void setSunlitColor(vec3 v);
+void setAmblitColor(vec3 v);
+void setAdditiveColor(vec3 v);
+void setAtmosAttenuation(vec3 v);
+void setPositionEye(vec3 v);
+
+vec3 getAdditiveColor();
+
+void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
+
+void calcAtmospherics(vec3 inPositionEye) {
+
+ vec3 P = inPositionEye;
+ setPositionEye(P);
+ vec3 tmpsunlit = vec3(1);
+ vec3 tmpamblit = vec3(1);
+ vec3 tmpaddlit = vec3(1);
+ vec3 tmpattenlit = vec3(1);
+ calcAtmosphericVars(inPositionEye, vec3(0), 1, tmpsunlit, tmpamblit, tmpaddlit, tmpattenlit, true);
+ setSunlitColor(tmpsunlit);
+ setAmblitColor(tmpamblit);
+ setAdditiveColor(tmpaddlit);
+ setAtmosAttenuation(tmpattenlit);
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl
new file mode 100644
index 0000000000..545a32a227
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl
@@ -0,0 +1,68 @@
+/**
+ * @file class3\wl\transportF.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$
+ */
+
+//////////////////////////////////////////////////////////
+// The fragment shader for the terrain atmospherics
+//////////////////////////////////////////////////////////
+
+vec3 getAdditiveColor();
+vec3 getAtmosAttenuation();
+
+uniform int no_atmo;
+
+vec3 atmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
+{
+ if (no_atmo == 1)
+ {
+ return light;
+ }
+ // fullbright responds minimally to atmos scatter effects
+ light *= min(15.0 * atten.r, 1.0);
+ light += (0.1 * additive);
+ return light * 2.0;
+}
+
+vec3 atmosTransport(vec3 light)
+{
+ return atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
+}
+
+vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
+{
+ float brightness = dot(light.rgb, vec3(0.33333));
+ return vec3(1,0,1);
+ //return atmosTransportFrag(light * 0.5, additive * (brightness * 0.5 + 0.5), atten);
+}
+
+vec3 fullbrightAtmosTransport(vec3 light)
+{
+ return atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
+}
+
+vec3 fullbrightShinyAtmosTransport(vec3 light)
+{
+ float brightness = dot(light.rgb, vec3(0.33333));
+ return atmosTransportFrag(light * 0.5, getAdditiveColor() * (brightness * brightness), getAtmosAttenuation());
+}
diff --git a/indra/newview/app_settings/shaders/shader_hierarchy.txt b/indra/newview/app_settings/shaders/shader_hierarchy.txt
index d8bbf69b38..8ef04d8e1f 100644
--- a/indra/newview/app_settings/shaders/shader_hierarchy.txt
+++ b/indra/newview/app_settings/shaders/shader_hierarchy.txt
@@ -1,3 +1,9 @@
+Class 3 is highest quality / lowest performance
+Class 2 is medium quality / medium performance
+Class 1 is lowest quality / highest performance
+
+Shaders WILL fall back to "lower" classes for functionality.
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
avatar/avatarV.glsl - gAvatarProgram, gAvatarWaterProgram
main() - avatar/avatarV.glsl
@@ -7,7 +13,6 @@ avatar/avatarV.glsl - gAvatarProgram, gAvatarWaterProgram
sumLights() - lighting/sumLightsV.glsl
calcDirectionalLight() - lighting/lightFuncV.glsl
calcPointLight() - lighting/lightFuncV.glsl
- scaleDownLight() - windlight/atmosphericsHelpersV.glsl
atmosAmbient() - windlight/atmosphericsHelpersV.glsl
atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -28,7 +33,6 @@ avatar/eyeballV.glsl - gAvatarEyeballProgram
atmosAmbient() - windlight/atmosphericsHelpersV.glsl
atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
atmosGetDiffuseSunlightColor() - windlight/atmosphericsHelpersV.glsl
- scaleDownLight() - windlight/atmosphericsHelpersV.glsl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
avatar/eyeballF.glsl - gAvatarEyeballProgram
main() - avatar/eyeballF.glsl
@@ -53,7 +57,6 @@ environment/terrainV.glsl - gTerrainProgram, gTerrainWaterProgram
sumLights() - lighting/sumLightsV.glsl
calcDirectionalLight() - lighting/lightFuncV.glsl
calcPointLight() - lighting/lightFuncV.glsl
- scaleDownLight() - windlight/atmosphericsHelpersV.glsl
atmosAmbient() - windlight/atmosphericsHelpersV.glsl
atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -120,7 +123,6 @@ objects/shinyV.glsl - gObjectShinyProgram, gObjectShinyWaterProgram
sumLights() - lighting/sumLightsV.glsl
calcDirectionalLight() - lighting/lightFuncV.glsl
calcPointLight() - lighting/lightFuncV.glsl
- scaleDownLight() - windlight/atmosphericsHelpersV.glsl
atmosAmbient() - windlight/atmosphericsHelpersV.glsl
atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -143,7 +145,6 @@ objects/simpleV.glsl - gObjectSimpleProgram, gObjectSimpleWaterProgram
sumLights() - lighting/sumLightsV.glsl
calcDirectionalLight() - lighting/lightFuncV.glsl
calcPointLight() - lighting/lightFuncV.glsl
- scaleDownLight() - windlight/atmosphericsHelpersV.glsl
atmosAmbient() - windlight/atmosphericsHelpersV.glsl
atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/indra/newview/app_settings/ultra_graphics.xml b/indra/newview/app_settings/ultra_graphics.xml
index 3e7fccbd5f..eb2cd356d9 100644
--- a/indra/newview/app_settings/ultra_graphics.xml
+++ b/indra/newview/app_settings/ultra_graphics.xml
@@ -34,8 +34,6 @@
-
-
diff --git a/indra/newview/app_settings/windlight/clouds/Altocumulus.tga b/indra/newview/app_settings/windlight/clouds/Altocumulus.tga
deleted file mode 100644
index 675cb16091..0000000000
Binary files a/indra/newview/app_settings/windlight/clouds/Altocumulus.tga and /dev/null differ
diff --git a/indra/newview/app_settings/windlight/clouds/Cumulo-Nimbus.tga b/indra/newview/app_settings/windlight/clouds/Cumulo-Nimbus.tga
deleted file mode 100644
index 88d5582ebf..0000000000
Binary files a/indra/newview/app_settings/windlight/clouds/Cumulo-Nimbus.tga and /dev/null differ
diff --git a/indra/newview/app_settings/windlight/clouds/Default.tga b/indra/newview/app_settings/windlight/clouds/Default.tga
deleted file mode 100644
index c95ce7fec4..0000000000
Binary files a/indra/newview/app_settings/windlight/clouds/Default.tga and /dev/null differ
diff --git a/indra/newview/app_settings/windlight/clouds/Layered.tga b/indra/newview/app_settings/windlight/clouds/Layered.tga
deleted file mode 100644
index 1321d23781..0000000000
Binary files a/indra/newview/app_settings/windlight/clouds/Layered.tga and /dev/null differ
diff --git a/indra/newview/exopostprocess.cpp b/indra/newview/exopostprocess.cpp
index d8658ff924..acef0015f6 100644
--- a/indra/newview/exopostprocess.cpp
+++ b/indra/newview/exopostprocess.cpp
@@ -42,7 +42,7 @@ exoPostProcess::~exoPostProcess()
void exoPostProcess::ExodusRenderPostStack(LLRenderTarget *src, LLRenderTarget *dst)
{
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
if (sExodusRenderVignette.mV[0] > 0.f && LLPipeline::sRenderDeferred)
ExodusRenderVignette(src, dst); // Don't render vignette here in non-deferred. Do it in the glow combine shader.
@@ -50,7 +50,7 @@ void exoPostProcess::ExodusRenderPostStack(LLRenderTarget *src, LLRenderTarget *
}
void exoPostProcess::ExodusRenderPostSettingsUpdate()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);
sExodusRenderVignette = gSavedSettings.getVector3("FSRenderVignette");
}
void exoPostProcess::ExodusRenderPostUpdate()
diff --git a/indra/newview/exopostprocess.h b/indra/newview/exopostprocess.h
index 909a6d3ed1..c2b9a68147 100644
--- a/indra/newview/exopostprocess.h
+++ b/indra/newview/exopostprocess.h
@@ -82,7 +82,7 @@ public:
// Cached settings.
static LLVector3 sExodusRenderVignette;
- S32 mVertexShaderLevel;
+ S32 mShaderLevel;
};
#endif
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index 79613daf1a..2399f01f35 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -66,6 +66,7 @@ RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
RenderDeferred 1 1
RenderDeferredSSAO 1 1
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderUseStreamVBO 1 1
RenderFSAASamples 1 16
@@ -98,6 +99,7 @@ VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
@@ -129,6 +131,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
@@ -159,6 +162,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
@@ -189,6 +193,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -219,6 +224,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -249,6 +255,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -279,6 +286,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -309,6 +317,7 @@ WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
RenderDeferred 1 1
RenderDeferredSSAO 1 1
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderFSAASamples 1 2
@@ -320,6 +329,7 @@ RenderVBOEnable 1 0
RenderShadowDetail 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
//
// Class 0 Hardware (just old)
@@ -375,6 +385,7 @@ WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
RenderShadowDetail 0 0
+RenderUseAdvancedAtmospherics 0 0
//
// No Vertex Shaders available
@@ -388,6 +399,7 @@ WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
RenderShadowDetail 0 0
+RenderUseAdvancedAtmospherics 0 0
//
// GL_ARB_map_buffer_range exists
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index 8d1a61da79..53814541ac 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -66,6 +66,7 @@ RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
RenderDeferred 1 1
RenderDeferredSSAO 1 1
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
@@ -97,6 +98,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
@@ -128,6 +130,7 @@ VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
@@ -158,6 +161,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
@@ -188,6 +192,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -217,6 +222,7 @@ RenderVolumeLODFactor 1 2.0
VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
@@ -248,6 +254,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -278,6 +285,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -308,6 +316,7 @@ WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
RenderDeferred 1 1
RenderDeferredSSAO 1 1
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderFSAASamples 1 2
@@ -319,6 +328,7 @@ RenderVBOEnable 1 0
RenderShadowDetail 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
//
// Class 0 Hardware (just old)
@@ -373,6 +383,7 @@ VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
+RenderUseAdvancedAtmospherics 0 0
RenderShadowDetail 0 0
//
@@ -386,6 +397,7 @@ VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
+RenderUseAdvancedAtmospherics 0 0
RenderShadowDetail 0 0
//
@@ -413,6 +425,7 @@ RenderReflectionDetail 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
+RenderUseAdvancedAtmospherics 0 0
RenderShadowDetail 0 0
//
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 53f8bfe7f3..b9192ecb12 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -66,6 +66,7 @@ RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
RenderDeferred 1 1
RenderDeferredSSAO 1 1
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderUseStreamVBO 1 1
RenderFSAASamples 1 16
@@ -98,6 +99,7 @@ VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
@@ -129,6 +131,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
@@ -159,6 +162,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
@@ -189,6 +193,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -219,6 +224,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -249,6 +255,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -280,6 +287,7 @@ WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
+RenderUseAdvancedAtmospherics 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -309,6 +317,7 @@ WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
RenderDeferred 1 1
RenderDeferredSSAO 1 1
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderFSAASamples 1 2
@@ -320,6 +329,7 @@ RenderVBOEnable 1 0
RenderShadowDetail 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
//
// Class 0 Hardware (just old)
@@ -368,6 +378,7 @@ VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
+RenderUseAdvancedAtmospherics 0 0
RenderShadowDetail 0 0
//
@@ -381,6 +392,7 @@ VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
+RenderUseAdvancedAtmospherics 0 0
RenderShadowDetail 0 0
//
@@ -407,6 +419,7 @@ RenderReflectionDetail 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
+RenderUseAdvancedAtmospherics 0 0
RenderShadowDetail 0 0
//
diff --git a/indra/newview/fsfloatercontacts.cpp b/indra/newview/fsfloatercontacts.cpp
index d2082490c7..0a5f31ce85 100644
--- a/indra/newview/fsfloatercontacts.cpp
+++ b/indra/newview/fsfloatercontacts.cpp
@@ -125,7 +125,7 @@ BOOL FSFloaterContacts::postBuild()
mFriendsTab->childSetAction("map_btn", boost::bind(&FSFloaterContacts::onMapButtonClicked, this));
mFriendsTab->childSetAction("pay_btn", boost::bind(&FSFloaterContacts::onPayButtonClicked, this));
mFriendsTab->childSetAction("remove_btn", boost::bind(&FSFloaterContacts::onDeleteFriendButtonClicked, this));
- mFriendsTab->childSetAction("add_btn", boost::bind(&FSFloaterContacts::onAddFriendWizButtonClicked, this));
+ mFriendsTab->childSetAction("add_btn", boost::bind(&FSFloaterContacts::onAddFriendWizButtonClicked, this, _1));
mFriendsTab->setDefaultBtn("im_btn");
mFriendsTab->getChild("friend_count")->setTextArg("COUNT", llformat("%d", mFriendsList->getItemCount()));
@@ -372,10 +372,10 @@ void FSFloaterContacts::onAvatarPicked(const uuid_vec_t& ids, const std::vector<
}
}
-void FSFloaterContacts::onAddFriendWizButtonClicked()
+void FSFloaterContacts::onAddFriendWizButtonClicked(LLUICtrl* ctrl)
{
// Show add friend wizard.
- LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&FSFloaterContacts::onAvatarPicked, _1, _2), FALSE, TRUE);
+ LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&FSFloaterContacts::onAvatarPicked, _1, _2), FALSE, TRUE, TRUE, "", ctrl);
// Need to disable 'ok' button when friend occurs in selection
if (picker)
{
diff --git a/indra/newview/fsfloatercontacts.h b/indra/newview/fsfloatercontacts.h
index 3f1c0fd99e..398de020e9 100644
--- a/indra/newview/fsfloatercontacts.h
+++ b/indra/newview/fsfloatercontacts.h
@@ -127,7 +127,7 @@ private:
void onTeleportButtonClicked();
void onPayButtonClicked();
void onDeleteFriendButtonClicked();
- void onAddFriendWizButtonClicked();
+ void onAddFriendWizButtonClicked(LLUICtrl* ctrl);
void onContactSetsButtonClicked();
void onMapButtonClicked();
diff --git a/indra/newview/fsfloatercontactsetconfiguration.cpp b/indra/newview/fsfloatercontactsetconfiguration.cpp
index b81653b1c9..839f750a75 100644
--- a/indra/newview/fsfloatercontactsetconfiguration.cpp
+++ b/indra/newview/fsfloatercontactsetconfiguration.cpp
@@ -28,18 +28,28 @@
*/
#include "llviewerprecompiledheaders.h"
+
#include "fsfloatercontactsetconfiguration.h"
+
#include "lggcontactsets.h"
+#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llcolorswatch.h"
#include "lllineeditor.h"
-#include "llbutton.h"
#include "llnotificationsutil.h"
+#include "llviewercontrol.h"
FSFloaterContactSetConfiguration::FSFloaterContactSetConfiguration(const LLSD& target_set)
-: LLFloater(target_set)
+: LLFloater(target_set),
+ mContextConeOpacity(0.f),
+ mContextConeInAlpha(0.f),
+ mContextConeOutAlpha(0.f),
+ mContextConeFadeTime(0.f)
{
mContactSet = target_set.asString();
+ mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
+ mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
+ mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
}
BOOL FSFloaterContactSetConfiguration::postBuild()
@@ -57,13 +67,13 @@ BOOL FSFloaterContactSetConfiguration::postBuild()
{
mSetSwatch->setCommitCallback(boost::bind(&FSFloaterContactSetConfiguration::onCommitSetColor, this));
}
-
+
mGlobalSwatch = getChild("global_swatch");
if (mGlobalSwatch)
{
mGlobalSwatch->setCommitCallback(boost::bind(&FSFloaterContactSetConfiguration::onCommitDefaultColor, this));
}
-
+
mNotificationCheckBox = getChild("show_set_notifications");
if (mNotificationCheckBox)
{
@@ -72,6 +82,13 @@ BOOL FSFloaterContactSetConfiguration::postBuild()
return TRUE;
}
+void FSFloaterContactSetConfiguration::draw()
+{
+ static LLCachedControl max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, mFrustumOrigin.get(), mContextConeFadeTime, mContextConeInAlpha, mContextConeOutAlpha);
+ LLFloater::draw();
+}
+
void FSFloaterContactSetConfiguration::onOpen(const LLSD& target_set)
{
mSetSwatch->set(LGGContactSets::getInstance()->getSetColor(mContactSet), TRUE);
@@ -119,3 +136,11 @@ void FSFloaterContactSetConfiguration::updateTitle()
map["NAME"] = mContactSet;
setTitle(getString("title", map));
}
+
+void FSFloaterContactSetConfiguration::setFrustumOrigin(LLView* frustumOrigin)
+{
+ if (frustumOrigin)
+ {
+ mFrustumOrigin = frustumOrigin->getHandle();
+ }
+}
diff --git a/indra/newview/fsfloatercontactsetconfiguration.h b/indra/newview/fsfloatercontactsetconfiguration.h
index a3449c5d3f..0e229440ec 100644
--- a/indra/newview/fsfloatercontactsetconfiguration.h
+++ b/indra/newview/fsfloatercontactsetconfiguration.h
@@ -43,7 +43,9 @@ public:
FSFloaterContactSetConfiguration(const LLSD& target_set);
BOOL postBuild();
void onOpen(const LLSD& target_set);
-
+ void draw();
+ void setFrustumOrigin(LLView* frustumOrigin);
+
private:
~FSFloaterContactSetConfiguration(){};
void onCommitSetColor();
@@ -55,12 +57,18 @@ private:
// Wish there was something better to use for this...
std::string mContactSet;
-
+
LLCheckBoxCtrl* mNotificationCheckBox;
LLColorSwatchCtrl* mSetSwatch;
LLColorSwatchCtrl* mGlobalSwatch;
LLLineEditor* mSetName;
LLButton* mRenameButton;
+
+ LLHandle mFrustumOrigin;
+ F32 mContextConeOpacity;
+ F32 mContextConeInAlpha;
+ F32 mContextConeOutAlpha;
+ F32 mContextConeFadeTime;
};
#endif //FS_FLOATERCONTACTSETCONFIGURATION_H
diff --git a/indra/newview/fsfloaterimport.cpp b/indra/newview/fsfloaterimport.cpp
index c8c86dfd66..c03e92db1a 100644
--- a/indra/newview/fsfloaterimport.cpp
+++ b/indra/newview/fsfloaterimport.cpp
@@ -1197,7 +1197,7 @@ void FSFloaterImport::uploadAsset(LLUUID asset_id, LLUUID inventory_item)
LLUUID folder_id = gInventory.findCategoryUUIDForType(folder_type);
LLInventoryType::EType inventory_type = LLInventoryType::defaultForAssetType(asset_type);
bool new_file_agent_inventory = false;
- LLWearableType::EType wearable_type = NOT_WEARABLE;
+ LLWearableType::EType wearable_type = (LLWearableType::EType)NO_INV_SUBTYPE;
std::string perms_prefix = "";
if (name.empty())
@@ -1301,7 +1301,7 @@ void FSFloaterImport::uploadAsset(LLUUID asset_id, LLUUID inventory_item)
LLPointer cb = new FSCreateItemCallback(ci_data);
create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
folder_id, LLTransactionID::tnull, name, description, asset_type, inventory_type,
- NOT_WEARABLE, PERM_ALL, cb);
+ NO_INV_SUBTYPE, PERM_ALL, cb);
return;
}
else
@@ -1325,7 +1325,7 @@ void FSFloaterImport::uploadAsset(LLUUID asset_id, LLUUID inventory_item)
LLPointer cb = new FSCreateItemCallback(ci_data);
create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
folder_id, LLTransactionID::tnull, name, description, asset_type, inventory_type,
- NOT_WEARABLE, PERM_MOVE | PERM_TRANSFER, cb);
+ NO_INV_SUBTYPE, PERM_MOVE | PERM_TRANSFER, cb);
return;
}
else
@@ -1375,7 +1375,7 @@ void FSFloaterImport::uploadAsset(LLUUID asset_id, LLUUID inventory_item)
LLPointer cb = new FSCreateItemCallback(ci_data);
create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
folder_id, LLTransactionID::tnull, name, description, asset_type, inventory_type,
- NOT_WEARABLE, PERM_ALL, cb);
+ NO_INV_SUBTYPE, PERM_ALL, cb);
return;
}
else
diff --git a/indra/newview/fslightshare.cpp b/indra/newview/fslightshare.cpp
deleted file mode 100644
index fd32ddffa3..0000000000
--- a/indra/newview/fslightshare.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * @file fslightshare.cpp
- * @brief Firestorm Lightshare handler
- *
- * $LicenseInfo:firstyear=2012&license=fsviewerlgpl$
- * Phoenix Firestorm Viewer Source Code
- * Copyright (C) 2012, Cinder Roxley
- * Lightshare is a registered trademark of Magne Metaverse Research, LLC
- *
- * 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
- *
- * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
- * http://www.firestormviewer.org
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "fslightshare.h"
-#include "llviewermessage.h"
-#include "llwaterparammanager.h"
-#include "llwlparammanager.h"
-#include "llenvmanager.h"
-#include "llviewercontrol.h"
-#include "llstatusbar.h"
-
-FSLightshare::FSLightshare() : mLightshareState(false)
-{}
-
-// virtual
-FSLightshare::~FSLightshare()
-{}
-
-void FSLightshare::processLightshareMessage(LLMessageSystem* msg)
-{
- /// TODO: It would be nice to handle this per event like parcel wl rather than a blanket boolean turning
- /// Lightshare on or off
- if (!gSavedSettings.getBOOL("FSOpenSimLightshare"))
- {
- LL_INFOS() << "Received Lightshare message from the region, but Lightshare is disabled." << LL_ENDL;
- return;
- }
- // Be paranoid!
- if (!msg)
- {
- return;
- }
- std::string method;
- msg->getStringFast(_PREHASH_MethodData, _PREHASH_Method, method);
- if (method != "Windlight")
- {
- return;
- }
- S32 size = msg->getSizeFast(_PREHASH_ParamList, 0, _PREHASH_Parameter);
- if (size < 0 || 250 < size)
- {
- return;
- }
- // Ok, it checks out (sorta)
-
- S32 count = msg->getNumberOfBlocksFast(_PREHASH_ParamList);
- for (S32 i = 0; i < count; ++i)
- {
- size = msg->getSizeFast(_PREHASH_ParamList, i, _PREHASH_Parameter);
- if (size >= 0)
- {
- char buffer[250];
- msg->getBinaryDataFast(_PREHASH_ParamList, _PREHASH_Parameter, buffer, size, i, 249);
- LightsharePacket* ls_packet = (LightsharePacket*)buffer; // <-- warning! ugly stupid, not byte-order safe!
-
- LL_INFOS() << "Received Lightshare message from the region, processing it." << LL_ENDL;
- processWater(ls_packet);
- processSky(ls_packet);
- }
- }
- setState(true);
- gStatusBar->updateParcelIcons();
-}
-
-void FSLightshare::processLightshareReset()
-{
- LLEnvManagerNew::getInstance()->usePrefs();
- setState(false);
- gStatusBar->updateParcelIcons();
-}
-
-// static
-void FSLightshare::processSky(LightsharePacket* ls_packet)
-{
- LLWLParamManager* wlparammgr = LLWLParamManager::getInstance();
- wlparammgr->mAnimator.deactivate();
- LLWLParamSet & param_set = wlparammgr->mCurParams;
-
- param_set.setSunAngle(F_TWO_PI * ls_packet->sunMoonPosiiton);
- param_set.setEastAngle(F_TWO_PI * ls_packet->eastAngle);
- param_set.set("sunlight_color", ls_packet->sunMoonColor.red * 3.0f, ls_packet->sunMoonColor.green * 3.0f, ls_packet->sunMoonColor.blue * 3.0f, ls_packet->sunMoonColor.alpha * 3.0f);
- param_set.set("ambient", ls_packet->ambient.red * 3.0f, ls_packet->ambient.green * 3.0f, ls_packet->ambient.blue * 3.0f, ls_packet->ambient.alpha * 3.0f);
- param_set.set("blue_horizon", ls_packet->horizon.red * 2.0f, ls_packet->horizon.green *2.0f, ls_packet->horizon.blue * 2.0f, ls_packet->horizon.alpha * 2.0f);
- param_set.set("blue_density", ls_packet->blueDensity.red * 2.0f, ls_packet->blueDensity.green * 2.0f, ls_packet->blueDensity.blue * 2.0f, ls_packet->blueDensity.alpha * 2.0f);
- param_set.set("haze_horizon", ls_packet->hazeHorizon, ls_packet->hazeHorizon, ls_packet->hazeHorizon, 1.f);
- param_set.set("haze_density", ls_packet->hazeDensity, ls_packet->hazeDensity, ls_packet->hazeDensity, 1.f);
- param_set.set("cloud_shadow", ls_packet->cloudCoverage, ls_packet->cloudCoverage, ls_packet->cloudCoverage, ls_packet->cloudCoverage);
- param_set.set("density_multiplier", ls_packet->densityMultiplier / 1000.0f);
- param_set.set("distance_multiplier", ls_packet->distanceMultiplier, ls_packet->distanceMultiplier, ls_packet->distanceMultiplier, ls_packet->distanceMultiplier);
- param_set.set("max_y",(F32)ls_packet->maxAltitude);
- param_set.set("cloud_color", ls_packet->cloudColor.red, ls_packet->cloudColor.green, ls_packet->cloudColor.blue, ls_packet->cloudColor.alpha);
- param_set.set("cloud_pos_density1", ls_packet->cloudXYDensity.X, ls_packet->cloudXYDensity.Y, ls_packet->cloudXYDensity.Z);
- param_set.set("cloud_pos_density2", ls_packet->cloudDetailXYDensity.X, ls_packet->cloudDetailXYDensity.Y, ls_packet->cloudDetailXYDensity.Z);
- param_set.set("cloud_scale", ls_packet->cloudScale, 0.f, 0.f, 1.f);
- param_set.set("gamma", ls_packet->sceneGamma, ls_packet->sceneGamma, ls_packet->sceneGamma, 0.0f);
- param_set.set("glow",(2 - ls_packet->sunGlowSize) * 20 , 0.f, -ls_packet->sunGlowFocus * 5);
- param_set.setCloudScrollX(ls_packet->cloudScrollX + 10.0f);
- param_set.setCloudScrollY(ls_packet->cloudScrollY + 10.0f);
- param_set.setEnableCloudScrollX(!ls_packet->cloudScrollXLock);
- param_set.setEnableCloudScrollY(!ls_packet->cloudScrollYLock);
- param_set.setStarBrightness(ls_packet->starBrightness);
-
- LLWLParamKey ls_key;
- ls_key.name = "LightshareCurrentRegion";
- ls_key.scope = LLEnvKey::SCOPE_LOCAL;
- wlparammgr->setParamSet(ls_key, param_set);
-
- wlparammgr->propagateParameters();
-}
-
-// static
-void FSLightshare::processWater(LightsharePacket* ls_packet)
-{
- LLWaterParamManager* wwparammgr = LLWaterParamManager::getInstance();
- LLWaterParamSet & param_set = wwparammgr->mCurParams;
-
- param_set.set("waterFogColor", ls_packet->waterColor.red / 256.f, ls_packet->waterColor.green / 256.f, ls_packet->waterColor.blue / 256.f);
- param_set.set("waterFogDensity", pow(2.0f, ls_packet->waterFogDensityExponent));
- param_set.set("underWaterFogMod", ls_packet->underwaterFogModifier);
- param_set.set("normScale", ls_packet->reflectionWaveletScale.X,ls_packet->reflectionWaveletScale.Y,ls_packet->reflectionWaveletScale.Z);
- param_set.set("fresnelScale", ls_packet->fresnelScale);
- param_set.set("fresnelOffset", ls_packet->fresnelOffset);
- param_set.set("scaleAbove", ls_packet->refractScaleAbove);
- param_set.set("scaleBelow", ls_packet->refractScaleBelow);
- param_set.set("blurMultiplier", ls_packet->blurMultiplier);
- param_set.set("wave1Dir", ls_packet->littleWaveDirection.X, ls_packet->littleWaveDirection.Y);
- param_set.set("wave2Dir", ls_packet->bigWaveDirection.X, ls_packet->bigWaveDirection.Y);
-
- LLUUID normalMapTexture;
-
- std::string out = llformat("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- (U8)(ls_packet->normalMapTexture[0]),
- (U8)(ls_packet->normalMapTexture[1]),
- (U8)(ls_packet->normalMapTexture[2]),
- (U8)(ls_packet->normalMapTexture[3]),
- (U8)(ls_packet->normalMapTexture[4]),
- (U8)(ls_packet->normalMapTexture[5]),
- (U8)(ls_packet->normalMapTexture[6]),
- (U8)(ls_packet->normalMapTexture[7]),
- (U8)(ls_packet->normalMapTexture[8]),
- (U8)(ls_packet->normalMapTexture[9]),
- (U8)(ls_packet->normalMapTexture[10]),
- (U8)(ls_packet->normalMapTexture[11]),
- (U8)(ls_packet->normalMapTexture[12]),
- (U8)(ls_packet->normalMapTexture[13]),
- (U8)(ls_packet->normalMapTexture[14]),
- (U8)(ls_packet->normalMapTexture[15]));
-
- normalMapTexture.set(out);
-
- wwparammgr->setNormalMapID(normalMapTexture);
- wwparammgr->setParamSet("LightshareCurrentRegion", param_set);
- wwparammgr->setNormalMapID(normalMapTexture);
-
- wwparammgr->propagateParameters();
-}
-
-void FSLightshare::setState(bool has_lightshare)
-{
- mLightshareState = has_lightshare;
-}
diff --git a/indra/newview/fslightshare.h b/indra/newview/fslightshare.h
deleted file mode 100644
index e5b95ace0e..0000000000
--- a/indra/newview/fslightshare.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * @file fslightshare.h
- * @brief Firestorm Lightshare handler definitions
- *
- * $LicenseInfo:firstyear=2012&license=fsviewerlgpl$
- * Phoenix Firestorm Viewer Source Code
- * Copyright (C) 2012, Cinder Roxley
- * Lightshare is a registered trademark of Magne Metaverse Research, LLC
- *
- * 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
- *
- * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
- * http://www.firestormviewer.org
- * $/LicenseInfo$
- */
-
-#ifndef FS_LIGHTSHARE_H
-#define FS_LIGHTSHARE_H
-
-#include "llsingleton.h"
-
-struct LSColor3
-{
- LSColor3() {};
- LSColor3(F32 pRed, F32 pGreen, F32 pBlue)
- {
- red=pRed;
- green=pGreen;
- blue=pBlue;
- }
- F32 red;
- F32 green;
- F32 blue;
-};
-
-struct LSVector3
-{
- LSVector3() {}
- LSVector3(F32 pX, F32 pY, F32 pZ)
- {
- X=pX;
- Y=pY;
- Z=pZ;
- }
- F32 X;
- F32 Y;
- F32 Z;
-};
-
-struct LSVector2
-{
- LSVector2() {}
- LSVector2(F32 pX, F32 pY)
- {
- X=pX;
- Y=pY;
- }
- F32 X;
- F32 Y;
-};
-
-struct LSColor4
-{
- LSColor4() {}
- LSColor4(F32 pRed, F32 pGreen, F32 pBlue, F32 pAlpha)
- {
- red=pRed;
- green=pGreen;
- blue=pBlue;
- alpha=pAlpha;
- }
- F32 red;
- F32 green;
- F32 blue;
- F32 alpha;
-};
-
-struct LightsharePacket
-{
- LightsharePacket() {}
- LSColor3 waterColor;
- F32 waterFogDensityExponent;
- F32 underwaterFogModifier;
- LSVector3 reflectionWaveletScale;
- F32 fresnelScale;
- F32 fresnelOffset;
- F32 refractScaleAbove;
- F32 refractScaleBelow;
- F32 blurMultiplier;
- LSVector2 littleWaveDirection;
- LSVector2 bigWaveDirection;
- unsigned char normalMapTexture[16];
- LSColor4 horizon;
- F32 hazeHorizon;
- LSColor4 blueDensity;
- F32 hazeDensity;
- F32 densityMultiplier;
- F32 distanceMultiplier;
- LSColor4 sunMoonColor;
- F32 sunMoonPosiiton;
- LSColor4 ambient;
- F32 eastAngle;
- F32 sunGlowFocus;
- F32 sunGlowSize;
- F32 sceneGamma;
- F32 starBrightness;
- LSColor4 cloudColor;
- LSVector3 cloudXYDensity;
- F32 cloudCoverage;
- F32 cloudScale;
- LSVector3 cloudDetailXYDensity;
- F32 cloudScrollX;
- F32 cloudScrollY;
- unsigned short maxAltitude;
- char cloudScrollXLock;
- char cloudScrollYLock;
- char drawClassicClouds;
-};
-
-class FSLightshare : public LLSingleton
-{
- LOG_CLASS(FSLightshare);
-
- LLSINGLETON(FSLightshare);
- virtual ~FSLightshare();
-
-public:
- void processLightshareMessage(LLMessageSystem* msg);
- void processLightshareReset();
- bool getState() { return mLightshareState; };
-
-private:
- static void processWater(LightsharePacket* ls_packet);
- static void processSky(LightsharePacket* ls_packet);
- void setState(bool has_lightshare);
-
- bool mLightshareState;
-};
-
-#endif // FS_LIGHTSHARE_H
diff --git a/indra/newview/fslslbridge.cpp b/indra/newview/fslslbridge.cpp
index e0f5354fa4..084e409594 100644
--- a/indra/newview/fslslbridge.cpp
+++ b/indra/newview/fslslbridge.cpp
@@ -1159,7 +1159,7 @@ void FSLSLBridge::create_script_inner()
mCurrentFullName,
LLAssetType::AT_LSL_TEXT,
LLInventoryType::IT_LSL,
- NOT_WEARABLE,
+ NO_INV_SUBTYPE,
PERM_ALL,
cb);
}
@@ -1264,7 +1264,7 @@ void FSLSLBridgeScriptCallback::fire(const LLUUID& inv_item)
LL_INFOS("FSLSLBridge") << "Updating script ID for bridge and enqueing upload. Inventory ID: " << inv_item.asString() << LL_ENDL;
FSLSLBridge::instance().mScriptItemID = inv_item;
- LLResourceUploadInfo::ptr_t uploadInfo(boost::make_shared(obj->getID(), inv_item, LLScriptAssetUpload::MONO, true, LLUUID::null, buffer,
+ LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared(obj->getID(), inv_item, LLScriptAssetUpload::MONO, true, LLUUID::null, buffer,
[](LLUUID, LLUUID, LLUUID, LLSD) {
FSLSLBridge::getInstance()->setTimerResult(FSLSLBridge::SCRIPT_UPLOAD_FINISHED);
}));
diff --git a/indra/newview/fspanelcontactsets.cpp b/indra/newview/fspanelcontactsets.cpp
index dd28c3164f..c9dada71f8 100644
--- a/indra/newview/fspanelcontactsets.cpp
+++ b/indra/newview/fspanelcontactsets.cpp
@@ -29,15 +29,16 @@
#include "llviewerprecompiledheaders.h"
-#include "llnotificationsutil.h"
-
#include "fspanelcontactsets.h"
+
#include "fsfloatercontacts.h"
+#include "fsfloatercontactsetconfiguration.h"
#include "lggcontactsets.h"
#include "llavataractions.h"
#include "llcallingcard.h"
#include "llfloateravatarpicker.h"
#include "llfloaterreg.h"
+#include "llnotificationsutil.h"
#include "llpanelpeoplemenus.h"
#include "llslurl.h"
@@ -63,8 +64,8 @@ BOOL FSPanelContactSets::postBuild()
{
childSetAction("add_set_btn", boost::bind(&FSPanelContactSets::onClickAddSet, this));
childSetAction("remove_set_btn", boost::bind(&FSPanelContactSets::onClickRemoveSet, this));
- childSetAction("config_btn", boost::bind(&FSPanelContactSets::onClickConfigureSet, this));
- childSetAction("add_btn", boost::bind(&FSPanelContactSets::onClickAddAvatar, this));
+ childSetAction("config_btn", boost::bind(&FSPanelContactSets::onClickConfigureSet, this, _1));
+ childSetAction("add_btn", boost::bind(&FSPanelContactSets::onClickAddAvatar, this, _1));
childSetAction("remove_btn", boost::bind(&FSPanelContactSets::onClickRemoveAvatar, this));
childSetAction("profile_btn", boost::bind(&FSPanelContactSets::onClickOpenProfile, this));
childSetAction("start_im_btn", boost::bind(&FSPanelContactSets::onClickStartIM, this));
@@ -222,11 +223,11 @@ void FSPanelContactSets::refreshSetList()
resetControls();
}
-void FSPanelContactSets::onClickAddAvatar()
+void FSPanelContactSets::onClickAddAvatar(LLUICtrl* ctrl)
{
LLFloater* root_floater = gFloaterView->getParentFloater(this);
LLFloater* avatar_picker = LLFloaterAvatarPicker::show(boost::bind(&FSPanelContactSets::handlePickerCallback, this, _1, mContactSetCombo->getValue().asString()),
- TRUE, TRUE, TRUE, root_floater->getName());
+ TRUE, TRUE, TRUE, root_floater->getName(), ctrl);
if (root_floater && avatar_picker)
{
root_floater->addDependentFloater(avatar_picker);
@@ -277,12 +278,15 @@ void FSPanelContactSets::onClickRemoveSet()
LLNotificationsUtil::add("RemoveContactSet", args, payload, &LGGContactSets::handleRemoveContactSetCallback);
}
-void FSPanelContactSets::onClickConfigureSet()
+void FSPanelContactSets::onClickConfigureSet(LLUICtrl* ctrl)
{
LLFloater* root_floater = gFloaterView->getParentFloater(this);
- LLFloater* config_floater = LLFloaterReg::showInstance("fs_contact_set_config", LLSD(mContactSetCombo->getValue().asString()));
+ FSFloaterContactSetConfiguration* config_floater = LLFloaterReg::showTypedInstance("fs_contact_set_config", LLSD(mContactSetCombo->getValue().asString()));
+ config_floater->setFrustumOrigin(ctrl);
if (root_floater && config_floater)
+ {
root_floater->addDependentFloater(config_floater);
+ }
}
void FSPanelContactSets::onClickOpenProfile()
diff --git a/indra/newview/fspanelcontactsets.h b/indra/newview/fspanelcontactsets.h
index f4d30a4a73..0f30a0fa81 100644
--- a/indra/newview/fspanelcontactsets.h
+++ b/indra/newview/fspanelcontactsets.h
@@ -43,13 +43,13 @@ public:
FSPanelContactSets();
BOOL postBuild();
void refreshSetList();
-
+
private:
~FSPanelContactSets();
-
+
void onSelectAvatar();
void generateAvatarList(const std::string& contact_set);
- void onClickAddAvatar();
+ void onClickAddAvatar(LLUICtrl* ctrl);
void handlePickerCallback(const uuid_vec_t& ids, const std::string& set);
void onClickRemoveAvatar();
void onClickOpenProfile();
@@ -57,20 +57,20 @@ private:
void onClickOfferTeleport();
void onClickAddSet();
void onClickRemoveSet();
- void onClickConfigureSet();
+ void onClickConfigureSet(LLUICtrl* ctrl);
void onClickRemoveDisplayName();
void onClickSetPseudonym();
void onClickRemovePseudonym();
-
+
void refreshContactSets();
void removeAvatarFromSet();
void resetControls();
-
+
void updateSets(LGGContactSets::EContactSetUpdate type);
boost::signals2::connection mContactSetChangedConnection;
-
+
uuid_vec_t mAvatarSelections;
-
+
LLComboBox* mContactSetCombo;
LLAvatarList* mAvatarList;
};
diff --git a/indra/newview/fspanelprefs.cpp b/indra/newview/fspanelprefs.cpp
index 955a55aac1..40c2c3bc2e 100644
--- a/indra/newview/fspanelprefs.cpp
+++ b/indra/newview/fspanelprefs.cpp
@@ -35,7 +35,6 @@
#include "llagent.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
-#include "lldiriterator.h"
#include "llfloaterreg.h"
#include "llinventorymodel.h"
#include "llstartup.h"
@@ -69,8 +68,6 @@ BOOL FSPanelPrefs::postBuild()
getChild("reset_default_folders")->setCommitCallback(boost::bind(&FSPanelPrefs::onResetDefaultFolders, this));
- populateCloudCombo();
-
LLTextureCtrl* tex_ctrl = getChild("texture control");
tex_ctrl->setCommitCallback(boost::bind(&FSPanelPrefs::onCommitTexture, this, _2));
tex_ctrl->setDefaultImageAssetID(LLUUID(gSavedSettings.getString("DefaultObjectTexture")));
@@ -222,23 +219,6 @@ void FSPanelPrefs::onBeamDelete()
refreshBeamLists();
}
-void FSPanelPrefs::populateCloudCombo()
-{
- LLComboBox* cloud_combo = findChild("cloud_combo");
- if (cloud_combo)
- {
- const std::string cloudDir(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight" + gDirUtilp->getDirDelimiter() + "clouds"));
-
- LLDirIterator dir_iter(cloudDir, "*.tga");
- std::string file;
- while (dir_iter.next(file))
- {
- cloud_combo->add(file);
- }
- cloud_combo->setSimple(gSavedSettings.getString("FSCloudTexture"));
- }
-}
-
void FSPanelPrefs::onCommitTexture(const LLSD& data)
{
LLTextureCtrl* texture_ctrl = findChild("texture control");
diff --git a/indra/newview/fspanelprefs.h b/indra/newview/fspanelprefs.h
index 0ea56a1b38..3343cbedaa 100644
--- a/indra/newview/fspanelprefs.h
+++ b/indra/newview/fspanelprefs.h
@@ -50,8 +50,6 @@ private:
void onBeamColorDelete();
void onBeamDelete();
- void populateCloudCombo();
-
void onCommitTexture(const LLSD& data);
void onCommitCopy();
void onCommitTrans();
diff --git a/indra/newview/kcwlinterface.cpp b/indra/newview/kcwlinterface.cpp
deleted file mode 100644
index c33fc8e452..0000000000
--- a/indra/newview/kcwlinterface.cpp
+++ /dev/null
@@ -1,709 +0,0 @@
-/**
- * @file kcwlinterface.cpp
- * @brief Parcel Windlight Interface
- *
- * Copyright (C) 2010, Kadah Coba
- *
- * 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
- *
- * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
- * http://www.firestormviewer.org
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "kcwlinterface.h"
-
-#include "llagent.h"
-#include "llcallingcard.h" // isBuddy
-#include "lldaycyclemanager.h"
-#include "llparcel.h"
-#include "llslurl.h"
-#include "llstartup.h"
-#include "llstatusbar.h"
-#include "llviewercontrol.h" // gSavedSettings, gSavedPerAccountSettings
-#include "llviewerparcelmgr.h"
-#include "llwaterparammanager.h"
-#include "llwlparammanager.h"
-#include "rlvhandler.h"
-
-#include
-
-const F32 PARCEL_WL_CHECK_TIME = 5.f;
-const S32 PARCEL_WL_MIN_ALT_CHANGE = 3;
-const std::string PARCEL_WL_DEFAULT = "Default";
-
-const S32 NO_ZONES = -1; // Parcel WL is using default sky or region defaults (no height-mapped parcel WL)
-const S32 NO_SETTINGS = -2; // We didn't receive any parcel WL settings yet
-
-KCWindlightInterface::KCWindlightInterface() :
- LLEventTimer(PARCEL_WL_CHECK_TIME),
- mWLset(false),
- mWeChangedIt(false),
- mCurrentSpace(NO_SETTINGS),
- mLastParcelID(-1),
- mLastRegion(NULL),
- mHasRegionOverride(false),
- mHaveRegionSettings(false),
- mDisabled(false),
- mUsingParcelWLSkyDefault(false)
-{
- if (!gSavedSettings.getBOOL("FSWLParcelEnabled") || !gSavedSettings.getBOOL("UseEnvironmentFromRegionAlways"))
- {
- mEventTimer.stop();
- mDisabled = true;
- }
-
- mParcelMgrConnection = gAgent.addParcelChangedCallback(boost::bind(&KCWindlightInterface::parcelChange, this));
-}
-
-KCWindlightInterface::~KCWindlightInterface()
-{
- if (mParcelMgrConnection.connected())
- {
- mParcelMgrConnection.disconnect();
- }
-}
-
-void KCWindlightInterface::parcelChange()
-{
- if (checkSettings())
- {
- return;
- }
-
- mDisabled = false;
-
- S32 this_parcel_id = 0;
- std::string desc;
-
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
-
- // Since we cannot depend on the order in which the EnvironmentSettings cap and parcel info
- // will come in, we must check if the other has set something before this one for the current region.
- if (gAgent.getRegion() != mLastRegion)
- {
- mHaveRegionSettings = false;
- mLastRegion = gAgent.getRegion();
- mCurrentSpace = NO_SETTINGS;
- }
- mHasRegionOverride = false;
- mUsingParcelWLSkyDefault = false;
-
- if (parcel)
- {
- this_parcel_id = parcel->getLocalID();
- desc = parcel->getDesc();
- }
-
- if ( (this_parcel_id != mLastParcelID) || (mLastParcelDesc != desc) ) //parcel changed
- {
- LL_DEBUGS() << "Agent in new parcel: " << this_parcel_id << LL_ENDL;
-
- mLastParcelID = this_parcel_id;
- mLastParcelDesc = desc;
- mCurrentSpace = NO_SETTINGS;
- mCurrentSettings.clear();
- setWL_Status(false); //clear the status bar icon
- const LLVector3& agent_pos_region = gAgent.getPositionAgent();
- mLastZ = lltrunc( agent_pos_region.mV[VZ] );
-
- //clear the last notification if its still open
- if (mSetWLNotification && !mSetWLNotification->isRespondedTo())
- {
- LLSD response = mSetWLNotification->getResponseTemplate();
- response["Ignore"] = true;
- mSetWLNotification->respond(response);
- }
-
- mEventTimer.reset();
- mEventTimer.start();
-
- // Apply new WL settings instantly on TP
- if (mTPing)
- {
- mTPing = false;
- tick();
- }
- }
-}
-
-
-BOOL KCWindlightInterface::tick()
-{
- if ((LLStartUp::getStartupState() < STATE_STARTED) || checkSettings())
- {
- return FALSE;
- }
-
- //TODO: there has to be a better way of doing this...
- if (mCurrentSettings.has("sky"))
- {
- const LLVector3& agent_pos_region = gAgent.getPositionAgent();
- S32 z = lltrunc( agent_pos_region.mV[VZ] );
- if (llabs(z - mLastZ) >= PARCEL_WL_MIN_ALT_CHANGE)
- {
- mLastZ = z;
- applySkySettings(mCurrentSettings);
- }
- return FALSE;
- }
-
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
-
- if (parcel)
- {
- if (!loadFromParcel(parcel) || !mCurrentSettings.has("sky"))
- {
- mEventTimer.stop();
- }
- }
-
- return FALSE;
-}
-
-
-void KCWindlightInterface::applySettings(const LLSD& settings)
-{
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if (!settings.has("local_id") || (settings["local_id"].asInteger() == parcel->getLocalID()) )
- {
- mCurrentSettings = settings;
-
- mHasRegionOverride = settings.has("region_override");
-
- bool non_region_default_applied = applySkySettings(settings);
-
- // We can only apply a water preset if we didn't set region WL default previously
- // or there will be unpredictable behavior where the region WL defaults will be
- // disabled again and sky/day cycle presets will be reverted to whatever the user
- // has set before.
- if (non_region_default_applied)
- {
- if (settings.has("water") && (!mHaveRegionSettings || mHasRegionOverride))
- {
- LL_INFOS() << "Applying WL water set: " << settings["water"].asString() << LL_ENDL;
- LLWLParamManager::getInstance()->mAnimator.stopInterpolation();
- LLEnvManagerNew::instance().setUseWaterPreset(settings["water"].asString());
- setWL_Status(true);
- }
- else
- {
- LL_INFOS() << "Applying region default WL water set" << LL_ENDL;
- // Not nice to not interpolate, but these 2836724 methods of changing a WL
- // setting will nicely screw up each other and this will most likely happen
- // if calling useRegionWater() because it doesn't even interpolate at all.
- LLWLParamManager::getInstance()->mAnimator.stopInterpolation();
- LLEnvManagerNew::instance().useRegionWater();
- }
- }
- else
- {
- LL_WARNS() << "Cannot apply Parcel WL water preset because region WL default has been set due to invalid sky preset" << LL_ENDL;
- }
- }
-}
-
-bool KCWindlightInterface::applySkySettings(const LLSD& settings)
-{
- if (settings.has("sky"))
- {
- LL_DEBUGS() << "Checking if agent is in a defined zone" << LL_ENDL;
-
- //TODO: there has to be a better way of doing this...
- mEventTimer.reset();
- mEventTimer.start();
-
- const LLVector3& agent_pos_region = gAgent.getPositionAgent();
- S32 z = lltrunc( agent_pos_region.mV[VZ] );
- LLSD::array_const_iterator end_it = settings["sky"].endArray();
- for (LLSD::array_const_iterator space_it = settings["sky"].beginArray(); space_it != end_it; ++space_it)
- {
- S32 lower = (*space_it)["lower"].asInteger();
- S32 upper = (*space_it)["upper"].asInteger();
- if ( (z >= lower) && (z <= upper) )
- {
- if (lower != mCurrentSpace) //workaround: only apply once
- {
- mCurrentSpace = lower; //use lower as an id
- LL_INFOS() << "Applying WL sky set: " << (*space_it)["preset"].asString() << " (agent in zone " << lower << " to " << upper << ")" << LL_ENDL;
- applyWindlightPreset((*space_it)["preset"].asString());
- }
- return true;
- }
- }
-
- LL_DEBUGS() << "Agent is not within a defined zone. Trying default now" << LL_ENDL;
- }
-
- if (mCurrentSpace != NO_ZONES)
- {
- mCurrentSpace = NO_ZONES;
- // set notes on KCWindlightInterface::haveParcelOverride
- if (settings.has("sky_default") && (!mHaveRegionSettings || mHasRegionOverride))
- {
- LL_INFOS() << "Applying WL sky set: " << settings["sky_default"] << " (Parcel WL Default)" << LL_ENDL;
- mUsingParcelWLSkyDefault = true;
- applyWindlightPreset(settings["sky_default"].asString());
- }
- else //reset to default
- {
- mUsingParcelWLSkyDefault = false;
- std::string reason;
- if (!settings.has("sky_default"))
- {
- reason = "No zone or not in a defined zone and no default sky defined";
- }
- else if (mHaveRegionSettings && !mHasRegionOverride)
- {
- reason = "No zone defined or not in a defined zone, region has custom WL and \"RegionOverride\" parameter was not set";
- }
-
- LL_INFOS() << "Applying WL sky set \"Region Default\": " << reason << LL_ENDL;
- applyWindlightPreset(PARCEL_WL_DEFAULT);
- return false;
- }
- }
-
- return true;
-}
-
-void KCWindlightInterface::applyWindlightPreset(const std::string& preset)
-{
- if (rlv_handler_t::isEnabled() && gRlvHandler.hasBehaviour(RLV_BHVR_SETENV))
- {
- return;
- }
-
- LLWLParamManager::getInstance()->mAnimator.stopInterpolation();
- LLWLParamManager* wlprammgr = LLWLParamManager::getInstance();
- LLWLParamKey key(preset, LLEnvKey::SCOPE_LOCAL);
- if ( (preset != PARCEL_WL_DEFAULT) && (wlprammgr->hasParamSet(key)) )
- {
- LLEnvManagerNew::instance().setUseSkyPreset(preset);
- setWL_Status(true);
- mWeChangedIt = true;
- }
- else
- {
- if (!LLEnvManagerNew::instance().getUseRegionSettings())
- {
- LLEnvManagerNew::instance().setUseRegionSettings(true);
- }
- setWL_Status(false);
- mWeChangedIt = false;
- }
-}
-
-void KCWindlightInterface::resetToRegion(bool force)
-{
- if (rlv_handler_t::isEnabled() && gRlvHandler.hasBehaviour(RLV_BHVR_SETENV))
- {
- return;
- }
-
- //TODO: clear per parcel
- if (mWeChangedIt || force) //dont reset anything if we didnt do it
- {
- applyWindlightPreset(PARCEL_WL_DEFAULT);
- }
-}
-
-//KC: Disabling this for now
-#if 0
-bool KCWindlightInterface::chatCommand(std::string message, std::string from_name, LLUUID source_id, LLUUID owner_id)
-{
- boost::cmatch match;
- const boost::regex prefix_exp("^\\)\\*\\((.*)");
- if(boost::regex_match(message.c_str(), match, prefix_exp))
- {
- std::string data(match[1].first, match[1].second);
-
- //TODO: expand these or good as is?
- /*const boost::regex setWLpreset_exp("^setWLpreset\\|(.*)");
- const boost::regex setWWpreset_exp("^setWWpreset\\|(.*)");
- if(boost::regex_match(data.c_str(), match, setWLpreset_exp))
- {
- LL_INFOS() << "got setWLpreset : " << match[1] << LL_ENDL;
- LLWLParamManager::instance()->mAnimator.mIsRunning = false;
- LLWLParamManager::instance()->mAnimator.mUseLindenTime = false;
- LLWLParamManager::instance()->loadPreset(match[1]);
- return true;
- }
- else if(boost::regex_match(data.c_str(), match, setWWpreset_exp))
- {
- LL_INFOS() << "got setWWpreset : " << match[1] << LL_ENDL;
- LLWaterParamManager::instance()->loadPreset(match[1], true);
- return true;
- }
- else
- {*/
-
- //TODO: add save settings for reuse instead of just clearing on parcel change
- //TODO: add support for region wide settings on non-mainland
- //TODO: add support for targeting specfic users
- //TODO: add support for custom settings via notecards or something
- //TODO: improved data processing, possibly just use LLSD as input instead
-
- boost::smatch match2;
- const boost::regex Parcel_exp("^(Parcel),WLPreset=\"([^\"\\r\\n]+)\"(,WWPreset=\"([^\"\\r\\n]+)\")?$");
- //([\\w]{8}-[\\w]{4}-[\\w]{4}-[\\w]{4}-[\\w]{12})
- if(boost::regex_search(data, match2, Parcel_exp))
- {
- if (SetDialogVisible) //TODO: handle this better
- return true;
-
- if (match2[1]=="Parcel")
- {
- LL_INFOS() << "Got Parcel WL : " << match[2] << LL_ENDL;
-
- LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- LLSD payload;
- payload["local_id"] = parcel->getLocalID();
- payload["land_owner"] = parcel->getOwnerID();
- payload["wlpreset"] = std::string(match2[2].first, match2[2].second);
- payload["wwpreset"] = std::string(match2[3].first, match2[3].second);
-
- LLSD args;
- args["PARCEL_NAME"] = parcel->getName();
-
- LLNotifications::instance().add("FSWL", args, payload, boost::bind(&KCWindlightInterface::callbackParcelWL, this, _1, _2));
- SetDialogVisible = true;
- }
- return true;
- }
- /*}*/
- }
- return false;
-}
-#endif
-
-bool KCWindlightInterface::loadFromParcel(LLParcel *parcel)
-{
- if (!parcel)
- {
- return false;
- }
-
- LLSD payload;
- if (parseParcelForWLSettings(parcel->getDesc(), payload))
- {
- const LLUUID owner_id = getOwnerID(parcel);
- //basic auth for now
- if (allowedLandOwners(owner_id))
- {
- applySettings(payload);
- }
- else
- {
- LLSD args;
- args["PARCEL_NAME"] = parcel->getName();
- args["OWNER_NAME"] = getOwnerName(parcel);
- payload["parcel_name"] = parcel->getName();
- payload["local_id"] = parcel->getLocalID();
- payload["land_owner"] = owner_id;
-
- mSetWLNotification = LLNotifications::instance().add("FSWL", args, payload, boost::bind(&KCWindlightInterface::callbackParcelWL, this, _1, _2));
- }
- return true;
- }
-
- //if nothing defined, reset to region settings
- resetToRegion();
-
- return false;
-}
-
-bool KCWindlightInterface::parseParcelForWLSettings(const std::string& desc, LLSD& settings)
-{
- bool found_settings = false;
- try
- {
- boost::smatch mat_block;
- //parcel desc /*[data goes here]*/
- const boost::regex Parcel_exp("(?i)\\/\\*(?:Windlight)?([\\s\\S]*?)\\*\\/");
- if (boost::regex_search(desc, mat_block, Parcel_exp))
- {
- //std::string data1(mat_block[1].first, mat_block[1].second);
- //LL_INFOS() << "found parcel flags block: " << mat_block[1] << LL_ENDL;
-
- S32 sky_index = 0;
- LLWLParamManager* wlprammgr = LLWLParamManager::getInstance();
- LLWaterParamManager* wwprammgr = LLWaterParamManager::getInstance();
- boost::smatch match;
- std::string::const_iterator start = mat_block[1].first;
- std::string::const_iterator end = mat_block[1].second;
- //Sky: "preset" Water: "preset"
- const boost::regex key_regex("(?i)(?:(?:(Sky)(?:\\s?@\\s?([\\d]+)m?\\s?(?:to|-)\\s?([\\d]+)m?)?)|(Water))\\s?:\\s?\"([^\"\\r\\n]+)\"|(RegionOverride)");
- while (boost::regex_search(start, end, match, key_regex, boost::match_default))
- {
- if (match[1].matched)
- {
- LL_DEBUGS() << "Sky Flags: type = " << match[1] << " from = " << match[2] << " to = " << match[3] << " preset = " << match[5] << LL_ENDL;
-
- std::string preset(match[5]);
- LLWLParamKey key(preset, LLEnvKey::SCOPE_LOCAL);
- if (wlprammgr->hasParamSet(key))
- {
- if (match[2].matched && match[3].matched)
- {
- S32 lower = (S32)atoi(std::string(match[2]).c_str());
- S32 upper = (S32)atoi(std::string(match[3]).c_str());
- if ( (upper > lower) && (lower >= 0) )
- {
- LLSD space;
- space["lower"] = lower;
- space["upper"] = upper;
- space["preset"] = preset;
- if (!settings.has("sky"))
- {
- settings["sky"] = LLSD();
- }
- settings["sky"][sky_index++] = space;
- found_settings = true;
- }
- }
- else
- {
- LL_DEBUGS() << "Sky Default = " << preset << LL_ENDL;
- settings["sky_default"] = preset;
- found_settings = true;
- }
- }
- else
- {
- LL_WARNS() << "Parcel Windlight contains unknown sky: " << preset << LL_ENDL;
- }
- }
- else if (match[4].matched)
- {
- std::string preset(match[5]);
- LL_DEBUGS() << "Got Water Preset: " << preset << LL_ENDL;
- if(wwprammgr->hasParamSet(preset))
- {
- settings["water"] = preset;
- found_settings = true;
- }
- }
- else if (match[6].matched)
- {
- LL_DEBUGS() << "Got Region Override Flag" << LL_ENDL;
- settings["region_override"] = true;
- }
-
- // update search position
- start = match[0].second;
- }
- }
- }
- catch(...)
- {
- found_settings = false;
- }
-
- return found_settings;
-}
-
-void KCWindlightInterface::onClickWLStatusButton()
-{
- //clear the last notification if its still open
- if (mClearWLNotification && !mClearWLNotification->isRespondedTo())
- {
- LLSD response = mClearWLNotification->getResponseTemplate();
- response["Ignore"] = true;
- mClearWLNotification->respond(response);
- }
-
- if (mWLset)
- {
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if (parcel)
- {
- //TODO: this could be better
- LLSD payload;
- payload["local_id"] = parcel->getLocalID();
- payload["land_owner"] = getOwnerID(parcel);
-
- LLSD args;
- args["PARCEL_NAME"] = parcel->getName();
-
- mClearWLNotification = LLNotifications::instance().add("FSWLClear", args, payload, boost::bind(&KCWindlightInterface::callbackParcelWLClear, this, _1, _2));
- }
- }
-}
-
-bool KCWindlightInterface::callbackParcelWL(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotification::getSelectedOption(notification, response);
- if (option == 0)
- {
- mAllowedLand.insert(notification["payload"]["land_owner"].asUUID());
-
- applySettings(notification["payload"]);
- }
- else
- {
- resetToRegion();
- }
- return false;
-}
-
-bool KCWindlightInterface::callbackParcelWLClear(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotification::getSelectedOption(notification, response);
- if (option == 0)
- {
- LLUUID owner_id = notification["payload"]["land_owner"].asUUID();
-
- mAllowedLand.erase(owner_id);
- resetToRegion();
- }
- return false;
-}
-
-bool KCWindlightInterface::allowedLandOwners(const LLUUID& owner_id)
-{
- if ( gSavedSettings.getBOOL("FSWLWhitelistAll") || // auto all
- (owner_id == gAgent.getID()) || // land is owned by agent
- (LLAvatarTracker::instance().isBuddy(owner_id) && gSavedSettings.getBOOL("FSWLWhitelistFriends")) || // is friend's land
- (gAgent.isInGroup(owner_id) && gSavedSettings.getBOOL("FSWLWhitelistGroups")) || // is member of land's group
- (mAllowedLand.find(owner_id) != mAllowedLand.end()) ) // already on whitelist
- {
- return true;
- }
- return false;
-}
-
-LLUUID KCWindlightInterface::getOwnerID(LLParcel* parcel)
-{
- if (parcel->getIsGroupOwned())
- {
- return parcel->getGroupID();
- }
- return parcel->getOwnerID();
-}
-
-std::string KCWindlightInterface::getOwnerName(LLParcel* parcel)
-{
- std::string owner = "";
- if (parcel->getIsGroupOwned())
- {
- owner = LLSLURL("group", parcel->getGroupID(), "inspect").getSLURLString();
- }
- else
- {
- owner = LLSLURL("agent", parcel->getOwnerID(), "inspect").getSLURLString();
- }
- return owner;
-}
-
-//KC: this is currently not used
-//TODO: merge this relay code in to bridge when more final, currently only supports "Parcel,WLPreset='[preset name]'"
-/*
-integer PHOE_WL_CH = -1346916165;
-default
-{
- state_entry()
- {
- llListen(PHOE_WL_CH, "", NULL_KEY, "");
- }
- listen( integer iChan, string sName, key kID, string sMsg )
- {
- if ( llGetOwnerKey(kID) == llGetLandOwnerAt(llGetPos()) )
- {
- llOwnerSay(")*(" + sMsg);
- }
- }
-}
-*/
-
-// Region settings are prefered for default parcel ones
-// But parcel height mapped skies always override region's
-// And parcels can use the "RegionOverride" in their config line
-bool KCWindlightInterface::haveParcelOverride(const LLEnvironmentSettings& new_settings)
-{
- // Since we cannot depend on the order in which the EnvironmentSettings cap and parcel info
- // will come in, we must check if the other has set something before this one for the current region.
- if (gAgent.getRegion() != mLastRegion)
- {
- mHasRegionOverride = false;
- mUsingParcelWLSkyDefault = false;
- mCurrentSettings.clear();
- mLastRegion = gAgent.getRegion();
- mCurrentSpace = NO_SETTINGS;
- }
-
- //*ASSUMPTION: if region day cycle is empty, its set to default
- mHaveRegionSettings = new_settings.getWLDayCycle().size() > 0;
-
- // If no parcel WL default sky is defined, we are going to use region defaults
- // (mCurrentSpace == NO_ZONES && mUsingParcelWLSkyDefault == false).
- // In that case, we do NOT override so we update the WL with what we received
- // from the region.
- bool has_override = (mCurrentSpace == NO_ZONES && mUsingParcelWLSkyDefault && mHasRegionOverride) || // Using a default parcel WL sky and "RegionOverride" parameter set
- (mCurrentSpace == NO_ZONES && mUsingParcelWLSkyDefault && !mHaveRegionSettings) || // Custom parcel WL default sky and region default WL (no custom region default WL!)
- (mCurrentSpace != NO_SETTINGS && mCurrentSpace != NO_ZONES); // Height-mapped parcel WL (always override region WL)
-
- LL_DEBUGS() << "mCurrentSpace == NO_ZONES && mUsingParcelWLSkyDefault && mHasRegionOverride = " << ((mCurrentSpace == NO_ZONES && mUsingParcelWLSkyDefault && mHasRegionOverride) ? "true" : "false") << " - "
- << "mCurrentSpace == NO_ZONES && mUsingParcelWLSkyDefault && !mHaveRegionSettings = " << ((mCurrentSpace == NO_ZONES && mUsingParcelWLSkyDefault && !mHaveRegionSettings) ? "true" : "false") << " - "
- << "mCurrentSpace != NO_SETTINGS && mCurrentSpace != NO_ZONES = " << ((mCurrentSpace != NO_SETTINGS && mCurrentSpace != NO_ZONES) ? "true" : "false")
- << LL_ENDL;
-
- if (!has_override)
- {
- LL_INFOS() << "Region environment settings received. Parcel WL settings will be overridden." << LL_ENDL;
- }
- else
- {
- LL_INFOS() << "Parcel WL override active" << LL_ENDL;
- }
-
- return has_override;
-}
-
-void KCWindlightInterface::setWL_Status(bool pwl_status)
-{
- mWLset = pwl_status;
- gStatusBar->updateParcelIcons();
-}
-
-bool KCWindlightInterface::checkSettings()
-{
- static LLCachedControl sFSWLParcelEnabled(gSavedSettings, "FSWLParcelEnabled");
- static LLCachedControl sUseEnvironmentFromRegionAlways(gSavedSettings, "UseEnvironmentFromRegionAlways");
- if (!sFSWLParcelEnabled || !sUseEnvironmentFromRegionAlways ||
- (rlv_handler_t::isEnabled() && gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)))
- {
- // The setting changed, clear everything
- if (!mDisabled)
- {
- mCurrentSettings.clear();
- mWeChangedIt = false;
- mCurrentSpace = NO_SETTINGS;
- mLastParcelID = -1;
- mHasRegionOverride = false;
- mHaveRegionSettings = false;
- mLastRegion = NULL;
- mEventTimer.stop();
- setWL_Status(false);
- mDisabled = true;
- mUsingParcelWLSkyDefault = false;
- }
- return true;
- }
- mDisabled = false;
- return false;
-}
diff --git a/indra/newview/kcwlinterface.h b/indra/newview/kcwlinterface.h
deleted file mode 100644
index 542e2172a1..0000000000
--- a/indra/newview/kcwlinterface.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * @file kcwlinterface.h
- * @brief Windlight Interface
- *
- * Copyright (C) 2010, Kadah Coba
- *
- * 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
- *
- * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
- * http://www.firestormviewer.org
- * $/LicenseInfo$
- */
-
-#ifndef KC_WLINTERFACE_H
-#define KC_WLINTERFACE_H
-
-#include "llsingleton.h"
-#include "lleventtimer.h"
-#include "llnotifications.h"
-
-class LLParcel;
-class LLViewerRegion;
-class LLEnvironmentSettings;
-
-class KCWindlightInterface : public LLSingleton, LLEventTimer
-{
- LOG_CLASS(KCWindlightInterface);
-
- LLSINGLETON(KCWindlightInterface);
- ~KCWindlightInterface();
-
-public:
-
- void parcelChange();
- /*virtual*/ BOOL tick(); // From LLEventTime
-
- void applySettings(const LLSD& settings);
- bool applySkySettings(const LLSD& settings);
- void applyWindlightPreset(const std::string& preset);
- void resetToRegion(bool force = false);
-
- //bool chatCommand(std::string message, std::string from_name, LLUUID source_id, LLUUID owner_id);
- bool loadFromParcel(LLParcel *parcel);
- bool parseParcelForWLSettings(const std::string& desc, LLSD& settings);
- void onClickWLStatusButton();
- void setTPing(bool value) { mTPing = value; }
- bool haveParcelOverride(const LLEnvironmentSettings& new_settings);
-
- bool getWLset() { return mWLset; }
-
-private:
- boost::signals2::connection mParcelMgrConnection;
-
- bool callbackParcelWL(const LLSD& notification, const LLSD& response);
- bool callbackParcelWLClear(const LLSD& notification, const LLSD& response);
- bool allowedLandOwners(const LLUUID& agent_id);
- LLUUID getOwnerID(LLParcel* parcel);
- std::string getOwnerName(LLParcel* parcel);
- void setWL_Status(bool pwl_status);
- bool checkSettings();
-
-protected:
- bool mWLset; //display the status bar icon?
- uuid_set_t mAllowedLand;
- LLNotificationPtr mSetWLNotification;
- LLNotificationPtr mClearWLNotification;
- S32 mLastParcelID;
- std::string mLastParcelDesc; //used to check if its changed
- S32 mCurrentSpace; //we use the lower bound of a space as its id
- LLSD mCurrentSettings;
- S32 mLastZ;
- bool mWeChangedIt; //dont reset anything if we didnt do it
- bool mTPing; //agent just TP'd (hack, might be better way)
- LLViewerRegion* mLastRegion;
- bool mHasRegionOverride;
- bool mHaveRegionSettings;
- bool mDisabled; // control bool to clear all states after being disabled
- bool mUsingParcelWLSkyDefault;
-};
-
-#endif // KC_WLINTERFACE_H
diff --git a/indra/newview/lggbeamcolormapfloater.cpp b/indra/newview/lggbeamcolormapfloater.cpp
index 6b2c891ca1..5b08eedbeb 100644
--- a/indra/newview/lggbeamcolormapfloater.cpp
+++ b/indra/newview/lggbeamcolormapfloater.cpp
@@ -24,6 +24,10 @@
#include "llviewercontrol.h"
#include "llviewermenufile.h"
+// Correction factors needed after porting from Phoenix
+const S32 CORRECTION_X = 0;
+const S32 CORRECTION_Y = -40;
+
F32 convertXToHue(S32 place)
{
return ((place - 6) / 396.0f) * 720.0f;
@@ -34,18 +38,35 @@ S32 convertHueToX(F32 place)
return ll_round((place / 720.0f) * 396.0f) + 6;
}
-
-const F32 CONTEXT_CONE_IN_ALPHA = 0.0f;
-const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
-const F32 CONTEXT_FADE_TIME = 0.08f;
-
-// Correction factors needed after porting from Phoenix
-const S32 CORRECTION_X = 0;
-const S32 CORRECTION_Y = -40;
-
-void lggBeamColorMapFloater::onClickSlider()
+lggBeamColorMapFloater::lggBeamColorMapFloater(const LLSD& seed) : LLFloater(seed),
+ mContextConeOpacity(0.f),
+ mContextConeInAlpha(0.f),
+ mContextConeOutAlpha(0.f),
+ mContextConeFadeTime(0.f)
{
+ mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
+ mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
+ mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
+}
+
+lggBeamColorMapFloater::~lggBeamColorMapFloater()
+{
+}
+
+BOOL lggBeamColorMapFloater::postBuild()
+{
+ getChild("BeamColor_Save")->setCommitCallback(boost::bind(&lggBeamColorMapFloater::onClickSave, this));
+ getChild("BeamColor_Load")->setCommitCallback(boost::bind(&lggBeamColorMapFloater::onClickLoad, this));
+ getChild("BeamColor_Cancel")->setCommitCallback(boost::bind(&lggBeamColorMapFloater::closeFloater, this, false));
+
+ mColorSlider = getChild("BeamColor_Speed");
+ mColorSlider->setCommitCallback(boost::bind(&lggBeamColorMapFloater::onClickSlider, this));
+
+ mBeamColorPreview = getChild("BeamColor_Preview");
+
fixOrder();
+
+ return TRUE;
}
void lggBeamColorMapFloater::draw()
@@ -56,45 +77,9 @@ void lggBeamColorMapFloater::draw()
//set the color of the preview thing
LLColor4 bColor = LLColor4(lggBeamMaps::beamColorFromData(mData));
mBeamColorPreview->set(bColor, TRUE);
-
- //Try draw rectangle attach beam
- LLRect swatch_rect;
- LLButton* createButton = mFSPanel->getChild("BeamColor_new");
-
- createButton->localRectToOtherView(createButton->getLocalRect(), &swatch_rect, this);
- LLRect local_rect = getLocalRect();
- if (gFocusMgr.childHasKeyboardFocus(this) && mFSPanel->isInVisibleChain() && mContextConeOpacity > 0.001f)
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLEnable(GL_CULL_FACE);
- gGL.begin(LLRender::TRIANGLE_STRIP);
- {
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
- gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
- gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
- gGL.vertex2i(local_rect.mRight, local_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
- gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
- gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
- gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
- gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
- }
- gGL.end();
- }
- static LLCachedControl opacity(gSavedSettings, "PickerContextOpacity");
- mContextConeOpacity = lerp(mContextConeOpacity, opacity(), LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME));
+ static LLCachedControl max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, mFSPanel->getChild("BeamColor_new"), mContextConeFadeTime, mContextConeInAlpha, mContextConeOutAlpha);
//Draw Base Stuff
LLFloater::draw();
@@ -169,33 +154,6 @@ void lggBeamColorMapFloater::draw()
gGL.popMatrix();
}
-lggBeamColorMapFloater::~lggBeamColorMapFloater()
-{
-}
-
-lggBeamColorMapFloater::lggBeamColorMapFloater(const LLSD& seed) : LLFloater(seed),
- mContextConeOpacity(0.0f)
-{
-}
-
-BOOL lggBeamColorMapFloater::postBuild()
-{
- setCanMinimize(FALSE);
-
- getChild("BeamColor_Save")->setCommitCallback(boost::bind(&lggBeamColorMapFloater::onClickSave, this));
- getChild("BeamColor_Load")->setCommitCallback(boost::bind(&lggBeamColorMapFloater::onClickLoad, this));
- getChild("BeamColor_Cancel")->setCommitCallback(boost::bind(&lggBeamColorMapFloater::onClickCancel, this));
-
- mColorSlider = getChild("BeamColor_Speed");
- mColorSlider->setCommitCallback(boost::bind(&lggBeamColorMapFloater::onClickSlider, this));
-
- mBeamColorPreview = getChild("BeamColor_Preview");
-
- fixOrder();
-
- return TRUE;
-}
-
BOOL lggBeamColorMapFloater::handleMouseDown(S32 x, S32 y, MASK mask)
{
F32 hue = getHueFromLocation(x, y);
@@ -224,6 +182,11 @@ BOOL lggBeamColorMapFloater::handleRightMouseDown(S32 x, S32 y, MASK mask)
return LLFloater::handleRightMouseDown(x, y, mask);
}
+void lggBeamColorMapFloater::onClickSlider()
+{
+ fixOrder();
+}
+
F32 lggBeamColorMapFloater::getHueFromLocation(S32 x, S32 y)
{
if (y > (201 + CORRECTION_Y) && y < (277 + CORRECTION_Y))
@@ -256,9 +219,9 @@ void lggBeamColorMapFloater::fixOrder()
}
}
-void lggBeamColorMapFloater::setData(void* data)
+void lggBeamColorMapFloater::setData(FSPanelPrefs* data)
{
- mFSPanel = (FSPanelPrefs*)data;
+ mFSPanel = data;
if (mFSPanel)
{
gFloaterView->getParentFloater(mFSPanel)->addDependentFloater(this);
@@ -296,11 +259,6 @@ void lggBeamColorMapFloater::onSaveCallback(const std::vector& file
closeFloater();
}
-void lggBeamColorMapFloater::onClickCancel()
-{
- closeFloater();
-}
-
void lggBeamColorMapFloater::onClickLoad()
{
(new LLFilePickerReplyThread(boost::bind(&lggBeamColorMapFloater::onLoadCallback, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
diff --git a/indra/newview/lggbeamcolormapfloater.h b/indra/newview/lggbeamcolormapfloater.h
index a3aa7f72fa..5e80a49cbf 100644
--- a/indra/newview/lggbeamcolormapfloater.h
+++ b/indra/newview/lggbeamcolormapfloater.h
@@ -34,7 +34,7 @@ public:
BOOL handleMouseDown(S32 x, S32 y, MASK mask);
BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
- void setData(void* data);
+ void setData(FSPanelPrefs* data);
void draw();
@@ -43,7 +43,6 @@ protected:
void onClickSlider();
void onClickSave();
void onClickLoad();
- void onClickCancel();
void onSaveCallback(const std::vector& filenames);
void onLoadCallback(const std::vector& filenames);
@@ -53,6 +52,9 @@ protected:
LLSD getDataSerialized();
F32 mContextConeOpacity;
+ F32 mContextConeInAlpha;
+ F32 mContextConeOutAlpha;
+ F32 mContextConeFadeTime;
FSPanelPrefs* mFSPanel;
lggBeamsColors mData;
LLSliderCtrl* mColorSlider;
diff --git a/indra/newview/lggbeammapfloater.cpp b/indra/newview/lggbeammapfloater.cpp
index 3207d45358..199440fb5e 100644
--- a/indra/newview/lggbeammapfloater.cpp
+++ b/indra/newview/lggbeammapfloater.cpp
@@ -23,55 +23,40 @@
#include "llviewercontrol.h"
#include "llviewermenufile.h"
-const F32 CONTEXT_CONE_IN_ALPHA = 0.0f;
-const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
-const F32 CONTEXT_FADE_TIME = 0.08f;
-
-
-void lggBeamMapFloater::clearPoints()
+lggBeamMapFloater::lggBeamMapFloater(const LLSD& seed) : LLFloater(seed),
+ mContextConeOpacity(0.f),
+ mContextConeInAlpha(0.f),
+ mContextConeOutAlpha(0.f),
+ mContextConeFadeTime(0.f)
{
- mDots.clear();
+ mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
+ mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
+ mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
+}
+
+lggBeamMapFloater::~lggBeamMapFloater()
+{
+}
+
+BOOL lggBeamMapFloater::postBuild()
+{
+ getChild("beamshape_save")->setCommitCallback(boost::bind(&lggBeamMapFloater::onClickSave, this));
+ getChild("beamshape_clear")->setCommitCallback(boost::bind(&lggBeamMapFloater::onClickClear, this));
+ getChild("beamshape_load")->setCommitCallback(boost::bind(&lggBeamMapFloater::onClickLoad, this));
+ getChild("cancel")->setCommitCallback(boost::bind(&lggBeamMapFloater::closeFloater, this, false));
+
+ getChild("back_color_swatch")->setCommitCallback(boost::bind(&lggBeamMapFloater::onBackgroundChange, this));
+ getChild("beam_color_swatch")->setColor(LLColor4::red);
+
+ mBeamshapePanel = getChild("beamshape_draw");
+
+ return TRUE;
}
void lggBeamMapFloater::draw()
{
- LLRect swatch_rect;
- LLButton* createButton = mFSPanel->getChild("custom_beam_btn");
-
- createButton->localRectToOtherView(createButton->getLocalRect(), &swatch_rect, this);
- LLRect local_rect = getLocalRect();
- if (gFocusMgr.childHasKeyboardFocus(this) && createButton->isInVisibleChain() && mContextConeOpacity > 0.001f)
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLEnable(GL_CULL_FACE);
- gGL.begin(LLRender::TRIANGLE_STRIP);
- {
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
- gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
- gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
- gGL.vertex2i(local_rect.mRight, local_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
- gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
- gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
- gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
- gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
- }
- gGL.end();
- }
-
- static LLCachedControl opacity(gSavedSettings, "PickerContextOpacity");
- mContextConeOpacity = lerp(mContextConeOpacity, opacity(), LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME));
+ static LLCachedControl max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, mFSPanel->getChild("custom_beam_btn"), mContextConeFadeTime, mContextConeInAlpha, mContextConeOutAlpha);
LLFloater::draw();
LLRect rec = mBeamshapePanel->getRect();
@@ -104,31 +89,6 @@ void lggBeamMapFloater::draw()
gGL.popMatrix();
}
-lggBeamMapFloater::~lggBeamMapFloater()
-{
-}
-
-lggBeamMapFloater::lggBeamMapFloater(const LLSD& seed) : LLFloater(seed),
- mContextConeOpacity(0.0f)
-{
-}
-
-BOOL lggBeamMapFloater::postBuild()
-{
- setCanMinimize(FALSE);
-
- getChild("beamshape_save")->setCommitCallback(boost::bind(&lggBeamMapFloater::onClickSave, this));
- getChild("beamshape_clear")->setCommitCallback(boost::bind(&lggBeamMapFloater::onClickClear, this));
- getChild("beamshape_load")->setCommitCallback(boost::bind(&lggBeamMapFloater::onClickLoad, this));
-
- getChild("back_color_swatch")->setCommitCallback(boost::bind(&lggBeamMapFloater::onBackgroundChange, this));
- getChild("beam_color_swatch")->setColor(LLColor4::red);
-
- mBeamshapePanel = getChild("beamshape_draw");
-
- return TRUE;
-}
-
BOOL lggBeamMapFloater::handleMouseDown(S32 x, S32 y, MASK mask)
{
if (y > 39 && x > 16 && x < 394 && y < 317)
@@ -143,15 +103,6 @@ BOOL lggBeamMapFloater::handleMouseDown(S32 x, S32 y, MASK mask)
return LLFloater::handleMouseDown(x, y, mask);
}
-void lggBeamMapFloater::setData(void* data)
-{
- mFSPanel = (FSPanelPrefs*)data;
- if (mFSPanel)
- {
- gFloaterView->getParentFloater(mFSPanel)->addDependentFloater(this);
- }
-}
-
BOOL lggBeamMapFloater::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
std::vector newDots;
@@ -174,7 +125,7 @@ void lggBeamMapFloater::onBackgroundChange()
mBeamshapePanel->setBackgroundColor(getChild("back_color_swatch")->get());
}
-LLSD lggBeamMapFloater::getMyDataSerialized()
+LLSD lggBeamMapFloater::getDataSerialized()
{
LLSD out;
LLRect r = mBeamshapePanel->getRect();
@@ -205,7 +156,7 @@ void lggBeamMapFloater::onSaveCallback(const std::vector& filenames
LLSD export_data;
export_data["scale"] = 8.0f / (mBeamshapePanel->getRect().getWidth());
- export_data["data"] = getMyDataSerialized();
+ export_data["data"] = getDataSerialized();
llofstream export_file;
export_file.open(filename.c_str());
@@ -254,3 +205,17 @@ void lggBeamMapFloater::onLoadCallback(const std::vector& filenames
mDots.push_back(p);
}
}
+
+void lggBeamMapFloater::setData(FSPanelPrefs* data)
+{
+ mFSPanel = data;
+ if (mFSPanel)
+ {
+ gFloaterView->getParentFloater(mFSPanel)->addDependentFloater(this);
+ }
+}
+
+void lggBeamMapFloater::clearPoints()
+{
+ mDots.clear();
+}
diff --git a/indra/newview/lggbeammapfloater.h b/indra/newview/lggbeammapfloater.h
index 09177f4e4a..730ae10b00 100644
--- a/indra/newview/lggbeammapfloater.h
+++ b/indra/newview/lggbeammapfloater.h
@@ -36,12 +36,12 @@ public:
virtual ~lggBeamMapFloater();
BOOL postBuild(void);
- BOOL handleMouseDown(S32 x,S32 y,MASK mask);
- BOOL handleRightMouseDown(S32 x,S32 y,MASK mask);
+ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
void draw();
- void setData(void* data);
+ void setData(FSPanelPrefs* data);
private:
// UI Handlers
@@ -55,10 +55,13 @@ private:
void clearPoints();
- LLSD getMyDataSerialized();
+ LLSD getDataSerialized();
std::vector mDots;
F32 mContextConeOpacity;
+ F32 mContextConeInAlpha;
+ F32 mContextConeOutAlpha;
+ F32 mContextConeFadeTime;
FSPanelPrefs* mFSPanel;
LLPanel* mBeamshapePanel;
};
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index bb4da6b0d7..00a835f990 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -45,7 +45,6 @@
#include "llchicletbar.h"
#include "llconsole.h"
#include "lldonotdisturbnotificationstorage.h"
-#include "llenvmanager.h"
#include "llfirstuse.h"
#include "llfloatercamera.h"
#include "llfloaterimcontainer.h"
@@ -112,7 +111,6 @@
// Firestorm includes
#include "fslslbridge.h"
-#include "kcwlinterface.h"
#include "llpresetsmanager.h"
#include "NACLantispam.h"
@@ -414,6 +412,7 @@ LLAgent::LLAgent() :
mAgentOriginGlobal(),
mPositionGlobal(),
+ mLastTestGlobal(),
mDistanceTraveled(0.F),
mLastPositionGlobal(LLVector3d::zero),
@@ -1268,6 +1267,13 @@ void LLAgent::setPositionAgent(const LLVector3 &pos_agent)
pos_agent_d.setVec(pos_agent);
mPositionGlobal = pos_agent_d + mAgentOriginGlobal;
}
+
+ if (((mLastTestGlobal - mPositionGlobal).lengthSquared() > 1.0) && !mOnPositionChanged.empty())
+ { // If the position has changed my more than 1 meter since the last time we triggered.
+ // filters out some noise.
+ mLastTestGlobal = mPositionGlobal;
+ mOnPositionChanged(mFrameAgent.getOrigin(), mPositionGlobal);
+ }
}
//-----------------------------------------------------------------------------
@@ -1308,6 +1314,12 @@ const LLVector3 &LLAgent::getPositionAgent()
return mFrameAgent.getOrigin();
}
+boost::signals2::connection LLAgent::whenPositionChanged(position_signal_t::slot_type fn)
+{
+ return mOnPositionChanged.connect(fn);
+}
+
+
//-----------------------------------------------------------------------------
// getRegionsVisited()
//-----------------------------------------------------------------------------
@@ -4584,9 +4596,6 @@ bool LLAgent::teleportCore(bool is_local)
gLastDrawDistanceStep = 32.0f;
}
//
-
- // bit of a hack
- KCWindlightInterface::instance().setTPing(true);
}
make_ui_sound("UISndTeleportOut");
@@ -5665,12 +5674,10 @@ LLTeleportRequestViaLocation::LLTeleportRequestViaLocation(const LLVector3d &pPo
: LLTeleportRequest(),
mPosGlobal(pPosGlobal)
{
- LL_INFOS("Teleport") << "LLTeleportRequestViaLocation created" << LL_ENDL;
}
LLTeleportRequestViaLocation::~LLTeleportRequestViaLocation()
{
- LL_INFOS("Teleport") << "~LLTeleportRequestViaLocation" << LL_ENDL;
}
bool LLTeleportRequestViaLocation::canRestartTeleport()
@@ -5710,7 +5717,6 @@ LLTeleportRequestViaLocationLookAt::LLTeleportRequestViaLocationLookAt(const LLV
LLTeleportRequestViaLocationLookAt::~LLTeleportRequestViaLocationLookAt()
{
- LL_INFOS("Teleport") << "~LLTeleportRequestViaLocationLookAt" << LL_ENDL;
}
bool LLTeleportRequestViaLocationLookAt::canRestartTeleport()
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index f58546bc88..58f2ed28eb 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -193,6 +193,8 @@ private:
// Position
//--------------------------------------------------------------------
public:
+ typedef boost::signals2::signal position_signal_t;
+
LLVector3 getPosAgentFromGlobal(const LLVector3d &pos_global) const;
LLVector3d getPosGlobalFromAgent(const LLVector3 &pos_agent) const;
const LLVector3d &getPositionGlobal() const;
@@ -200,11 +202,17 @@ public:
// Call once per frame to update position, angles (radians).
void updateAgentPosition(const F32 dt, const F32 yaw, const S32 mouse_x, const S32 mouse_y);
void setPositionAgent(const LLVector3 ¢er);
+
+ boost::signals2::connection whenPositionChanged(position_signal_t::slot_type fn);
+
protected:
void propagate(const F32 dt); // ! BUG ! Should roll into updateAgentPosition
private:
mutable LLVector3d mPositionGlobal;
+ position_signal_t mOnPositionChanged;
+ LLVector3d mLastTestGlobal;
+
//--------------------------------------------------------------------
// Velocity
//--------------------------------------------------------------------
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 07934ba528..c981e25016 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -905,14 +905,13 @@ void LLAgentWearables::createStandardWearables()
((OnWearableItemCreatedCB*)(&(*cb)))->addPendingWearable(wearable);
// no need to update here...
LLUUID category_id = LLUUID::null;
- create_inventory_item(gAgent.getID(),
+ create_inventory_wearable(gAgent.getID(),
gAgent.getSessionID(),
category_id,
wearable->getTransactionID(),
wearable->getName(),
wearable->getDescription(),
wearable->getAssetType(),
- LLInventoryType::IT_WEARABLE,
wearable->getType(),
wearable->getPermissions().getMaskNextOwner(),
cb);
@@ -974,14 +973,13 @@ void LLAgentWearables::addWearableToAgentInventory(LLPointergetTransactionID(),
wearable->getName(),
wearable->getDescription(),
wearable->getAssetType(),
- LLInventoryType::IT_WEARABLE,
wearable->getType(),
wearable->getPermissions().getMaskNextOwner(),
cb);
@@ -1719,7 +1717,6 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con
LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
LLAssetType::EType asset_type = wearable->getAssetType();
- LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE;
LLPointer cb;
if(wear)
{
@@ -1742,13 +1739,13 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con
folder_id = gInventory.findCategoryUUIDForType(folder_type);
}
- create_inventory_item(gAgent.getID(),
+ create_inventory_wearable(gAgent.getID(),
gAgent.getSessionID(),
folder_id,
wearable->getTransactionID(),
wearable->getName(),
wearable->getDescription(),
- asset_type, inv_type,
+ asset_type,
wearable->getType(),
LLFloaterPerms::getNextOwnerPerms("Wearables"),
cb);
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 8edc9e9048..16323056aa 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1053,14 +1053,13 @@ void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type
const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_cb,_1,type,wearable,this));
- create_inventory_item(gAgent.getID(),
+ create_inventory_wearable(gAgent.getID(),
gAgent.getSessionID(),
lost_and_found_id,
wearable->getTransactionID(),
wearable->getName(),
wearable->getDescription(),
wearable->getAssetType(),
- LLInventoryType::IT_WEARABLE,
wearable->getType(),
wearable->getPermissions().getMaskNextOwner(),
cb);
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 10e6207056..3f409ad562 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -33,6 +33,7 @@
#include "llfeaturemanager.h"
#include "lluictrlfactory.h"
#include "lltexteditor.h"
+#include "llenvironment.h"
#include "llerrorcontrol.h"
#include "lleventtimer.h"
#include "llviewertexturelist.h"
@@ -190,8 +191,6 @@
#include "llviewerparcelmgr.h"
#include "llworldmapview.h"
#include "llpostprocess.h"
-#include "llwlparammanager.h"
-#include "llwaterparammanager.h"
#include "lldebugview.h"
#include "llconsole.h"
@@ -227,6 +226,7 @@
#include "llfloateroutfitsnapshot.h"
#include "llfloatersnapshot.h"
#include "llsidepanelinventory.h"
+#include "llatmosphere.h"
// includes for idle() idleShutdown()
#include "llviewercontrol.h"
@@ -866,6 +866,9 @@ bool LLAppViewer::init()
// Memory will be cleaned up in ::cleanupClass()
LLWearableType::initParamSingleton(new LLUITranslationBridge());
+ LLTranslationBridge::ptr_t trans = std::make_shared();
+ LLSettingsType::initClass(trans);
+
// initialize SSE options
LLVector4a::initClass();
@@ -1327,31 +1330,33 @@ bool LLAppViewer::init()
gGLActive = FALSE;
- // Disable updater
-// LLProcess::Params updater;
-// updater.desc = "updater process";
-// // Because it's the updater, it MUST persist beyond the lifespan of the
-// // viewer itself.
-// updater.autokill = false;
+ // Disable updater
+// if (!gSavedSettings.getBOOL("CmdLineSkipUpdater"))
+// {
+// LLProcess::Params updater;
+// updater.desc = "updater process";
+// // Because it's the updater, it MUST persist beyond the lifespan of the
+// // viewer itself.
+// updater.autokill = false;
//#if LL_WINDOWS
-// updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker.exe");
+// updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker.exe");
//#elif LL_DARWIN
-// // explicitly run the system Python interpreter on SLVersionChecker.py
-// updater.executable = "python";
-// updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "SLVersionChecker.py"));
+// // explicitly run the system Python interpreter on SLVersionChecker.py
+// updater.executable = "python";
+// updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "SLVersionChecker.py"));
//#else
-// updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker");
+// updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker");
//#endif
-// // add LEAP mode command-line argument to whichever of these we selected
-// updater.args.add("leap");
-// // UpdaterServiceSettings
-// updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
-// // channel
-// updater.args.add(LLVersionInfo::getChannel());
-// // testok
-// updater.args.add(gSavedSettings.getString("UpdaterServiceURL"));
-// // ForceAddressSize
-// updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize")));
+// // add LEAP mode command-line argument to whichever of these we selected
+// updater.args.add("leap");
+// // UpdaterServiceSettings
+// updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
+// // channel
+// updater.args.add(LLVersionInfo::getChannel());
+// // testok
+// updater.args.add(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest")));
+// // ForceAddressSize
+// updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize")));
//#if LL_WINDOWS && !LL_RELEASE_FOR_DOWNLOAD && !LL_SEND_CRASH_REPORTS
// // This is neither a release package, nor crash-reporting enabled test build
// // try to run version updater, but don't bother if it fails (file might be missing)
@@ -1533,7 +1538,8 @@ static LLTrace::BlockTimerStatHandle FTM_YIELD("Yield");
static LLTrace::BlockTimerStatHandle FTM_TEXTURE_CACHE("Texture Cache");
static LLTrace::BlockTimerStatHandle FTM_DECODE("Image Decode");
-static LLTrace::BlockTimerStatHandle FTM_TEXTURE_FETCH("Texture Fetch");
+static LLTrace::BlockTimerStatHandle FTM_FETCH("Image Fetch");
+
static LLTrace::BlockTimerStatHandle FTM_VFS("VFS Thread");
static LLTrace::BlockTimerStatHandle FTM_LFS("LFS Thread");
static LLTrace::BlockTimerStatHandle FTM_PAUSE_THREADS("Pause Threads");
@@ -1727,9 +1733,11 @@ bool LLAppViewer::doFrame()
pingMainloopTimeout("Main:Display");
gGLActive = TRUE;
+ display();
+
// FIRE-22297: FPS limiter not working properly on Mac/Linux
//static U64 last_call = 0;
- //if (!gTeleportDisplay)
+ //if (!gTeleportDisplay || gGLManager.mIsIntel) // SL-10625...throttle early, throttle often with Intel
//{
// // Frame/draw throttling
// U64 elapsed_time = LLTimer::getTotalTime() - last_call;
@@ -1744,8 +1752,6 @@ bool LLAppViewer::doFrame()
//last_call = LLTimer::getTotalTime();
//
- display();
-
pingMainloopTimeout("Main:Snapshot");
LLFloaterSnapshot::update(); // take snapshots
LLFloaterOutfitSnapshot::update();
@@ -1909,7 +1915,7 @@ S32 LLAppViewer::updateTextureThreads(F32 max_time)
work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
}
{
- LL_RECORD_BLOCK_TIME(FTM_TEXTURE_FETCH);
+ LL_RECORD_BLOCK_TIME(FTM_FETCH);
work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
}
return work_pending;
@@ -1932,6 +1938,8 @@ void LLAppViewer::flushVFSIO()
bool LLAppViewer::cleanup()
{
+ LLAtmosphere::cleanupClass();
+
//ditch LLVOAvatarSelf instance
gAgentAvatarp = NULL;
@@ -2242,6 +2250,12 @@ bool LLAppViewer::cleanup()
// Store the time of our current logoff
gSavedPerAccountSettings.setU32("LastLogoff", time_corrected());
+ if (LLEnvironment::instanceExists())
+ {
+ //Store environment settings if nessesary
+ LLEnvironment::getInstance()->saveToSettings();
+ }
+
// Must do this after all panels have been deleted because panels that have persistent rects
// save their rects on delete.
if(mSaveSettingsOnExit) // Backup Settings
@@ -2612,14 +2626,9 @@ void errorCallback(const std::string &error_string)
// static info file.
LLAppViewer::instance()->writeDebugInfo();
-// LLError::crashAndLoop(error_string);
-// [SL:KB] - Patch: Viewer-Build | Checked: 2010-12-04 (Catznip-2.4)
-#if !LL_RELEASE_FOR_DOWNLOAD && LL_WINDOWS
- DebugBreak();
-#else
+#ifndef SHADER_CRASH_NONFATAL
LLError::crashAndLoop(error_string);
-#endif // LL_RELEASE_WITH_DEBUG_INFO && LL_WINDOWS
-// [/SL:KB]
+#endif
}
void LLAppViewer::initLoggingAndGetLastDuration()
@@ -5805,7 +5814,6 @@ void LLAppViewer::idle()
//
// Update weather effects
//
- gSky.propagateHeavenlyBodies(gFrameDTClamped); // moves sun, moon, and planets
// Update wind vector
LLVector3 wind_position_region;
@@ -6302,7 +6310,7 @@ bool LLAppViewer::onChangeFrameLimit(LLSD const & evt)
{
if (evt.asInteger() > 0)
{
- mMinMicroSecPerFrame = 1000000 / evt.asInteger();
+ mMinMicroSecPerFrame = (U64)(1000000.0f / F32(evt.asInteger()));
}
else
{
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index cb85fd3276..fe3c073e42 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -424,8 +424,6 @@ extern LLVector3 gRelativeWindVec;
extern U32 gPacketsIn;
extern BOOL gPrintMessagesThisFrame;
-extern LLUUID gSunTextureID;
-extern LLUUID gMoonTextureID;
extern LLUUID gBlackSquareID;
extern BOOL gRandomizeFramerate;
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index d1c4daf42b..98788a2cc8 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -828,13 +828,10 @@ namespace action_give_inventory
* Checks My Inventory visibility.
*/
-// static bool is_give_inventory_acceptable()
-// [SL:KB] - Patch: Inventory-ShareSelection | Checked: 2011-06-29 (Catznip-2.6.0e) | Added: Catznip-2.6.0e
- static bool is_give_inventory_acceptable(const uuid_set_t inventory_selected_uuids)
-// [/SL:KB]
+ static bool is_give_inventory_acceptable(LLInventoryPanel* panel = NULL)
{
-// // check selection in the panel
-// const std::set inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();
+ // check selection in the panel
+ const std::set inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs(panel);
if (inventory_selected_uuids.empty()) return false; // nothing selected
bool acceptable = false;
@@ -842,30 +839,29 @@ namespace action_give_inventory
const std::set::const_iterator it_end = inventory_selected_uuids.end();
for (; it != it_end; ++it)
{
- LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
- // any category can be offered.
- if (inv_cat)
- {
- acceptable = true;
- continue;
- }
+ LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
+ // any category can be offered.
+ if (inv_cat)
+ {
+ acceptable = true;
+ continue;
+ }
- LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
- // check if inventory item can be given
- if (LLGiveInventory::isInventoryGiveAcceptable(inv_item))
- {
- acceptable = true;
- continue;
- }
+ LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
+ // check if inventory item can be given
+ if (LLGiveInventory::isInventoryGiveAcceptable(inv_item))
+ {
+ acceptable = true;
+ continue;
+ }
- // there are neither item nor category in inventory
- acceptable = false;
- break;
+ // there are neither item nor category in inventory
+ acceptable = false;
+ break;
}
return acceptable;
}
-
static void build_items_string(const std::set& inventory_selected_uuids , std::string& items_string)
{
llassert(inventory_selected_uuids.size() > 0);
@@ -900,7 +896,7 @@ namespace action_give_inventory
uuid_vec_t mAvatarUuids;
};
- static void give_inventory_cb(const LLSD& notification, const LLSD& response)
+ static void give_inventory_cb(const LLSD& notification, const LLSD& response, std::set inventory_selected_uuids)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
// if Cancel pressed
@@ -909,18 +905,6 @@ namespace action_give_inventory
return;
}
-// LLInventoryPanel* active_panel = get_active_inventory_panel();
-// if (!active_panel) return;
-
-// const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList();
-// [SL:KB] - Patch: Inventory-ShareSelection | Checked: 2011-06-29 (Catznip-2.6.0e) | Added: Catznip-2.6.0e
- uuid_set_t inventory_selected_uuids;
- const LLSD& sdPayload = notification["payload"];
- for (LLSD::array_const_iterator itItem = sdPayload.beginArray(); itItem != sdPayload.endArray(); ++itItem)
- inventory_selected_uuids.insert(itItem->asUUID());
-// [/SL:KB]
- //const std::set inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();
-
if (inventory_selected_uuids.empty())
{
return;
@@ -1003,19 +987,11 @@ namespace action_give_inventory
* @param avatar_names - avatar names request to be sent.
* @param avatar_uuids - avatar names request to be sent.
*/
-// static void give_inventory(const uuid_vec_t& avatar_uuids, const std::vector avatar_names)
-// [SL:KB] - Patch: Inventory-ShareSelection | Checked: 2011-06-29 (Catznip-2.6.0e) | Added: Catznip-2.6.0e
- static void give_inventory(const uuid_vec_t& avatar_uuids, const std::vector avatar_names, const uuid_set_t inventory_selected_uuids)
-// [/SL:KB]
+ static void give_inventory(const uuid_vec_t& avatar_uuids, const std::vector avatar_names, LLInventoryPanel* panel = NULL)
{
llassert(avatar_names.size() == avatar_uuids.size());
-// LLInventoryPanel* active_panel = get_active_inventory_panel();
-// if (!active_panel) return;
-
-// const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList();
- //const std::set inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();
-
+ const std::set inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs(panel);
if (inventory_selected_uuids.empty())
{
return;
@@ -1047,17 +1023,9 @@ namespace action_give_inventory
LLSD substitutions;
substitutions["RESIDENTS"] = residents;
substitutions["ITEMS"] = items;
-// [SL:KB] - Patch: Inventory-ShareSelection | Checked: 2011-06-29 (Catznip-2.6.0e) | Added: Catznip-2.6.0e
- LLSD sdPayload;
- for (uuid_set_t::const_iterator itItem = inventory_selected_uuids.begin(); itItem != inventory_selected_uuids.end(); ++itItem)
- sdPayload.append(*itItem);
-// [/SL:KB]
LLShareInfo::instance().mAvatarNames = avatar_names;
LLShareInfo::instance().mAvatarUuids = avatar_uuids;
-// LLNotificationsUtil::add(notification, substitutions, LLSD(), &give_inventory_cb);
-// [SL:KB] - Patch: Inventory-ShareSelection | Checked: 2011-06-29 (Catznip-2.6.0e) | Added: Catznip-2.6.0e
- LLNotificationsUtil::add(notification, substitutions, sdPayload, &give_inventory_cb);
-// [/SL:KB]
+ LLNotificationsUtil::add(notification, substitutions, LLSD(), boost::bind(&give_inventory_cb, _1, _2, inventory_selected_uuids));
}
}
@@ -1113,11 +1081,14 @@ void LLAvatarActions::buildResidentsString(const uuid_vec_t& avatar_uuids, std::
}
//static
-std::set LLAvatarActions::getInventorySelectedUUIDs()
+std::set LLAvatarActions::getInventorySelectedUUIDs(LLInventoryPanel* active_panel)
{
std::set inventory_selected;
- LLInventoryPanel* active_panel = action_give_inventory::get_active_inventory_panel();
+ if (!active_panel)
+ {
+ active_panel = action_give_inventory::get_active_inventory_panel();
+ }
if (active_panel)
{
inventory_selected= active_panel->getRootFolder()->getSelectionList();
@@ -1147,20 +1118,16 @@ void LLAvatarActions::shareWithAvatars(LLView * panel)
{
using namespace action_give_inventory;
- LLFloater* root_floater = gFloaterView->getParentFloater(panel);
-// LLFloaterAvatarPicker* picker =
-// LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE, FALSE, root_floater->getName());
-// if (!picker)
-// {
-// return;
-// }
-//
-// picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable));
-// [SL:KB] - Patch: Inventory-ShareSelection | Checked: 2011-06-29 (Catznip-2.6.0e) | Added: Catznip-2.6.0e
- const uuid_set_t idItems = getInventorySelectedUUIDs();
- LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2, idItems), TRUE, FALSE);
- picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable, idItems));
-// [/SL:KB]
+ LLFloater* root_floater = gFloaterView->getParentFloater(panel);
+ LLInventoryPanel* inv_panel = dynamic_cast(panel);
+ LLFloaterAvatarPicker* picker =
+ LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2, inv_panel), TRUE, FALSE, FALSE, root_floater->getName());
+ if (!picker)
+ {
+ return;
+ }
+
+ picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable, inv_panel));
picker->openFriendsTab();
if (root_floater)
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 22cee1d53e..32126fcbed 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -318,7 +318,7 @@ public:
static void onDerenderAvatarNameLookup(const LLUUID& agent_id, const LLAvatarName& av_name, bool permanent);
// Derender
- static std::set getInventorySelectedUUIDs();
+ static std::set getInventorySelectedUUIDs(LLInventoryPanel* active_panel = NULL);
protected:
static bool callbackEstateKick(const LLSD& notification, const LLSD& response);
diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp
index c64d298f0c..24348f7da8 100644
--- a/indra/newview/llcontrolavatar.cpp
+++ b/indra/newview/llcontrolavatar.cpp
@@ -35,8 +35,6 @@
#include "llviewerregion.h"
#include "llskinningutil.h"
-//#pragma optimize("", off)
-
const F32 LLControlAvatar::MAX_LEGAL_OFFSET = 3.0f;
const F32 LLControlAvatar::MAX_LEGAL_SIZE = 64.0f;
@@ -263,7 +261,7 @@ void LLControlAvatar::recursiveScaleJoint(LLJoint* joint, F32 factor)
{
joint->setScale(factor * joint->getScale());
- for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
+ for (LLJoint::joints_t::iterator iter = joint->mChildren.begin();
iter != joint->mChildren.end(); ++iter)
{
LLJoint* child = *iter;
@@ -581,12 +579,12 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV
return NULL;
}
- LLViewerObject* hit = NULL;
+ LLViewerObject* hit = NULL;
- if (lineSegmentBoundingBox(start, end))
- {
- LLVector4a local_end = end;
- LLVector4a local_intersection;
+ if (lineSegmentBoundingBox(start, end))
+ {
+ LLVector4a local_end = end;
+ LLVector4a local_intersection;
if (mRootVolp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
{
local_end = local_intersection;
@@ -605,20 +603,20 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV
{
LLVOVolume *volp = *vol_it;
if (mRootVolp != volp && volp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
- {
- local_end = local_intersection;
- if (intersection)
- {
- *intersection = local_intersection;
- }
+ {
+ local_end = local_intersection;
+ if (intersection)
+ {
+ *intersection = local_intersection;
+ }
hit = volp;
break;
}
}
}
- }
-
- return hit;
+ }
+
+ return hit;
}
// virtual
diff --git a/indra/newview/lldaycyclemanager.cpp b/indra/newview/lldaycyclemanager.cpp
deleted file mode 100644
index b8d7b8ec3c..0000000000
--- a/indra/newview/lldaycyclemanager.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/**
- * @file lldaycyclemanager.cpp
- * @brief Implementation for the LLDayCycleManager class.
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "lldaycyclemanager.h"
-
-#include "lldiriterator.h"
-
-// [RLVa:KB] - Checked: 2011-09-04 (RLVa-1.4.1a) | Added: RLVa-1.4.1a
-#include
-// [/RLVa:KB]
-
-void LLDayCycleManager::getPresetNames(preset_name_list_t& names) const
-{
- names.clear();
-
- for (dc_map_t::const_iterator it = mDayCycleMap.begin(); it != mDayCycleMap.end(); ++it)
- {
- names.push_back(it->first);
- }
-}
-
-void LLDayCycleManager::getPresetNames(preset_name_list_t& user, preset_name_list_t& sys) const
-{
- user.clear();
- sys.clear();
-
- for (dc_map_t::const_iterator it = mDayCycleMap.begin(); it != mDayCycleMap.end(); ++it)
- {
- const std::string& name = it->first;
-
- if (isSystemPreset(name))
- {
- sys.push_back(name);
- }
- else
- {
- user.push_back(name);
- }
- }
-}
-
-// [RLVa:KB] - Checked: 2011-09-04 (RLVa-1.4.1a) | Added: RLVa-1.4.1a
-const std::string& LLDayCycleManager::findPreset(const std::string& strPresetName)
-{
- for (dc_map_t::const_iterator itCycle = mDayCycleMap.begin(); itCycle != mDayCycleMap.end(); ++itCycle)
- {
- if (boost::iequals(itCycle->first, strPresetName))
- return itCycle->first;
- }
- return LLStringUtil::null;
-}
-// [/RLVa:KB]
-
-void LLDayCycleManager::getUserPresetNames(preset_name_list_t& user) const
-{
- preset_name_list_t sys; // unused
- getPresetNames(user, sys);
-}
-
-bool LLDayCycleManager::getPreset(const std::string name, LLWLDayCycle& day_cycle) const
-{
- dc_map_t::const_iterator it = mDayCycleMap.find(name);
- if (it == mDayCycleMap.end())
- {
- return false;
- }
-
- day_cycle = it->second;
- return true;
-}
-
-bool LLDayCycleManager::getPreset(const std::string name, LLSD& day_cycle) const
-{
- LLWLDayCycle dc;
- if (!getPreset(name, dc))
- {
- return false;
- }
-
- day_cycle = dc.asLLSD();
- return true;
-}
-
-bool LLDayCycleManager::presetExists(const std::string name) const
-{
- LLWLDayCycle dummy;
- return getPreset(name, dummy);
-}
-
-bool LLDayCycleManager::isSystemPreset(const std::string& name) const
-{
- return gDirUtilp->fileExists(getSysDir() + LLURI::escape(name) + ".xml");
-}
-
-bool LLDayCycleManager::savePreset(const std::string& name, const LLSD& data)
-{
- // Save given preset.
- LLWLDayCycle day;
- day.loadDayCycle(data, LLEnvKey::SCOPE_LOCAL);
- day.save(getUserDir() + LLURI::escape(name) + ".xml");
-
- // Add it to our map.
- addPreset(name, data);
- mModifySignal();
- return true;
-}
-
-bool LLDayCycleManager::deletePreset(const std::string& name)
-{
- // Remove it from the map.
- dc_map_t::iterator it = mDayCycleMap.find(name);
- if (it == mDayCycleMap.end())
- {
- LL_WARNS("Windlight") << "No day cycle named " << name << LL_ENDL;
- return false;
- }
- mDayCycleMap.erase(it);
-
- // Remove from the filesystem.
- std::string filename = LLURI::escape(name) + ".xml";
- if (gDirUtilp->fileExists(getUserDir() + filename))
- {
- gDirUtilp->deleteFilesInDir(getUserDir(), filename);
- }
-
- // Signal interested parties.
- mModifySignal();
- return true;
-}
-
-bool LLDayCycleManager::isSkyPresetReferenced(const std::string& preset_name) const
-{
- // We're traversing local day cycles, they can only reference local skies.
- LLWLParamKey key(preset_name, LLEnvKey::SCOPE_LOCAL);
-
- for (dc_map_t::const_iterator it = mDayCycleMap.begin(); it != mDayCycleMap.end(); ++it)
- {
- if (it->second.hasReferencesTo(key))
- {
- return true;
- }
- }
-
- return false;
-}
-
-boost::signals2::connection LLDayCycleManager::setModifyCallback(const modify_signal_t::slot_type& cb)
-{
- return mModifySignal.connect(cb);
-}
-
-// virtual
-void LLDayCycleManager::initSingleton()
-{
- LL_DEBUGS("Windlight") << "Loading all day cycles" << LL_ENDL;
- loadAllPresets();
-}
-
-void LLDayCycleManager::loadAllPresets()
-{
- mDayCycleMap.clear();
-
- // First, load system (coming out of the box) day cycles.
- loadPresets(getSysDir());
-
- // Then load user presets. Note that user day cycles will modify any system ones already loaded.
- loadPresets(getUserDir());
-}
-
-void LLDayCycleManager::loadPresets(const std::string& dir)
-{
- LLDirIterator dir_iter(dir, "*.xml");
-
- while (1)
- {
- std::string file;
- if (!dir_iter.next(file)) break; // no more files
- loadPreset(gDirUtilp->add(dir, file));
- }
-}
-
-bool LLDayCycleManager::loadPreset(const std::string& path)
-{
- LLSD data = LLWLDayCycle::loadDayCycleFromPath(path);
- if (data.isUndefined())
- {
- LL_WARNS() << "Error loading day cycle from " << path << LL_ENDL;
- return false;
- }
-
- std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), /*strip_exten = */ true));
- addPreset(name, data);
-
- return true;
-}
-
-bool LLDayCycleManager::addPreset(const std::string& name, const LLSD& data)
-{
- if (name.empty())
- {
- //llassert(name.empty());
- return false;
- }
-
- LLWLDayCycle day;
- day.loadDayCycle(data, LLEnvKey::SCOPE_LOCAL);
- mDayCycleMap[name] = day;
- return true;
-}
-
-// static
-std::string LLDayCycleManager::getSysDir()
-{
- return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/days", "");
-}
-
-// static
-std::string LLDayCycleManager::getUserDir()
-{
- return gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS , "windlight/days", "");
-}
diff --git a/indra/newview/lldaycyclemanager.h b/indra/newview/lldaycyclemanager.h
deleted file mode 100644
index 73bbe05c4c..0000000000
--- a/indra/newview/lldaycyclemanager.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * @file lldaycyclemanager.h
- * @brief Implementation for the LLDayCycleManager class.
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLDAYCYCLEMANAGER_H
-#define LL_LLDAYCYCLEMANAGER_H
-
-#include
-#include
-
-#include "llwldaycycle.h"
-#include "llwlparammanager.h"
-
-/**
- * WindLight day cycles manager class
- *
- * Provides interface for accessing, loading and saving day cycles.
- */
-class LLDayCycleManager : public LLSingleton
-{
- LLSINGLETON_EMPTY_CTOR(LLDayCycleManager);
- LOG_CLASS(LLDayCycleManager);
-
-public:
- typedef std::list preset_name_list_t;
-
- typedef std::map dc_map_t;
- typedef boost::signals2::signal modify_signal_t;
-
- void getPresetNames(preset_name_list_t& names) const;
- void getPresetNames(preset_name_list_t& user, preset_name_list_t& sys) const;
- void getUserPresetNames(preset_name_list_t& user) const;
-// [RLVa:KB] - Checked: 2011-09-04 (RLVa-1.4.1a) | Added: RLVa-1.4.1a
- const std::string& findPreset(const std::string& strPresetName);
-// [/RLVa:KB]
-
- bool getPreset(const std::string name, LLWLDayCycle& day_cycle) const;
- bool getPreset(const std::string name, LLSD& day_cycle) const;
- bool presetExists(const std::string name) const;
- bool isSystemPreset(const std::string& name) const;
- bool savePreset(const std::string& name, const LLSD& data);
- bool deletePreset(const std::string& name);
-
- /// @return true if there is a day cycle that refers to the sky preset.
- bool isSkyPresetReferenced(const std::string& preset_name) const;
-
- /// Emitted when a preset gets added or deleted.
- boost::signals2::connection setModifyCallback(const modify_signal_t::slot_type& cb);
-
-private:
- /*virtual*/ void initSingleton();
-
- void loadAllPresets();
- void loadPresets(const std::string& dir);
- bool loadPreset(const std::string& path);
- bool addPreset(const std::string& name, const LLSD& data);
-
- static std::string getSysDir();
- static std::string getUserDir();
-
- dc_map_t mDayCycleMap;
- modify_signal_t mModifySignal;
-};
-
-#endif // LL_LLDAYCYCLEMANAGER_H
diff --git a/indra/newview/lldensityctrl.cpp b/indra/newview/lldensityctrl.cpp
new file mode 100644
index 0000000000..298a309e7c
--- /dev/null
+++ b/indra/newview/lldensityctrl.cpp
@@ -0,0 +1,225 @@
+/**
+* @file lldensityctrl.cpp
+* @brief Control for specifying density over a height range for sky settings.
+*
+* $LicenseInfo:firstyear=2011&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2011, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lldensityctrl.h"
+
+#include "llslider.h"
+#include "llsliderctrl.h"
+#include "llsettingssky.h"
+
+static LLDefaultChildRegistry::Register register_density_control("densityctrl");
+
+const std::string LLDensityCtrl::DENSITY_RAYLEIGH("density_rayleigh");
+const std::string LLDensityCtrl::DENSITY_MIE("density_mie");
+const std::string LLDensityCtrl::DENSITY_ABSORPTION("density_absorption");
+
+namespace
+{
+ const std::string FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL("level_exponential");
+ const std::string FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL_SCALE("exponential_scale");
+ const std::string FIELD_SKY_DENSITY_PROFILE_LINEAR("level_linear");
+ const std::string FIELD_SKY_DENSITY_PROFILE_CONSTANT("level_constant");
+ const std::string FIELD_SKY_DENSITY_MAX_ALTITUDE("max_altitude");
+ const std::string FIELD_SKY_DENSITY_ANISO_FACTOR("aniso_factor");
+ const std::string FIELD_SKY_DENSITY_ANISO_FACTOR_LABEL("aniso_factor_label");
+}
+
+const std::string& LLDensityCtrl::NameForDensityProfileType(DensityProfileType t)
+{
+ switch (t)
+ {
+ case Rayleigh: return DENSITY_RAYLEIGH;
+ case Mie: return DENSITY_MIE;
+ case Absorption: return DENSITY_ABSORPTION;
+ default:
+ break;
+ }
+
+ llassert(false);
+ return DENSITY_RAYLEIGH;
+}
+
+LLDensityCtrl::Params::Params()
+: image_density_feedback("image_density_feedback")
+, lbl_exponential("label_exponential")
+, lbl_exponential_scale("label_exponential_scale")
+, lbl_linear("label_linear")
+, lbl_constant("label_constant")
+, lbl_max_altitude("label_max_altitude")
+, lbl_aniso_factor("label_aniso_factor")
+, profile_type(LLDensityCtrl::Rayleigh)
+{
+}
+
+LLDensityCtrl::LLDensityCtrl(const Params& params)
+: mProfileType(params.profile_type)
+, mImgDensityFeedback(params.image_density_feedback)
+{
+
+}
+
+LLSD LLDensityCtrl::getProfileConfig()
+{
+ LLSD config;
+ switch (mProfileType)
+ {
+ case Rayleigh: return mSkySettings->getRayleighConfigs();
+ case Mie: return mSkySettings->getMieConfigs();
+ case Absorption: return mSkySettings->getAbsorptionConfigs();
+ default:
+ break;
+ }
+ llassert(false);
+ return config;
+}
+
+BOOL LLDensityCtrl::postBuild()
+{
+ getChild(FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onExponentialChanged(); });
+ getChild(FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onExponentialScaleFactorChanged(); });
+ getChild(FIELD_SKY_DENSITY_PROFILE_LINEAR)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onLinearChanged(); });
+ getChild(FIELD_SKY_DENSITY_PROFILE_CONSTANT)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onConstantChanged(); });
+ getChild(FIELD_SKY_DENSITY_MAX_ALTITUDE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMaxAltitudeChanged(); });
+ getChild(FIELD_SKY_DENSITY_ANISO_FACTOR)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onAnisoFactorChanged(); });
+
+ if (mProfileType != Mie)
+ {
+ getChild(FIELD_SKY_DENSITY_ANISO_FACTOR_LABEL)->setValue(false);
+ getChild(FIELD_SKY_DENSITY_ANISO_FACTOR)->setVisible(false);
+ }
+
+ return TRUE;
+}
+
+void LLDensityCtrl::setEnabled(BOOL enabled)
+{
+ getChild(FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL)->setEnabled(enabled);
+ getChild(FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL_SCALE)->setEnabled(enabled);
+ getChild(FIELD_SKY_DENSITY_PROFILE_LINEAR)->setEnabled(enabled);
+ getChild(FIELD_SKY_DENSITY_PROFILE_CONSTANT)->setEnabled(enabled);
+ getChild(FIELD_SKY_DENSITY_MAX_ALTITUDE)->setEnabled(enabled);
+
+ if (mProfileType == Mie)
+ {
+ getChild(FIELD_SKY_DENSITY_ANISO_FACTOR)->setEnabled(enabled);
+ }
+}
+
+void LLDensityCtrl::refresh()
+{
+ if (!mSkySettings)
+ {
+ setAllChildrenEnabled(FALSE);
+ setEnabled(FALSE);
+ return;
+ }
+
+ setEnabled(TRUE);
+ setAllChildrenEnabled(TRUE);
+
+ LLSD config = getProfileConfig();
+
+ getChild(FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL)->setValue(config[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM]);
+ getChild(FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL_SCALE)->setValue(config[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR]);
+ getChild(FIELD_SKY_DENSITY_PROFILE_LINEAR)->setValue(config[LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM]);
+ getChild(FIELD_SKY_DENSITY_PROFILE_CONSTANT)->setValue(config[LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM]);
+ getChild(FIELD_SKY_DENSITY_MAX_ALTITUDE)->setValue(config[LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH]);
+
+ if (mProfileType == Mie)
+ {
+ getChild(FIELD_SKY_DENSITY_ANISO_FACTOR)->setValue(config[LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR]);
+ }
+}
+
+void LLDensityCtrl::updateProfile()
+{
+ F32 exponential_term = getChild(FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL)->getValueF32();
+ F32 exponential_scale = getChild(FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL_SCALE)->getValueF32();
+ F32 linear_term = getChild(FIELD_SKY_DENSITY_PROFILE_LINEAR)->getValueF32();
+ F32 constant_term = getChild(FIELD_SKY_DENSITY_PROFILE_CONSTANT)->getValueF32();
+ F32 max_alt = getChild(FIELD_SKY_DENSITY_MAX_ALTITUDE)->getValueF32();
+ F32 aniso_factor = 0.0f;
+
+ if (mProfileType == Mie)
+ {
+ aniso_factor = getChild(FIELD_SKY_DENSITY_ANISO_FACTOR)->getValueF32();
+ }
+
+ LLSD profile = LLSettingsSky::createSingleLayerDensityProfile(max_alt, exponential_term, exponential_scale, linear_term, constant_term, aniso_factor);
+
+ switch (mProfileType)
+ {
+ case Rayleigh: mSkySettings->setRayleighConfigs(profile); break;
+ case Mie: mSkySettings->setMieConfigs(profile); break;
+ case Absorption: mSkySettings->setAbsorptionConfigs(profile); break;
+ default:
+ break;
+ }
+}
+
+void LLDensityCtrl::onExponentialChanged()
+{
+ updateProfile();
+ updatePreview();
+}
+
+void LLDensityCtrl::onExponentialScaleFactorChanged()
+{
+ updateProfile();
+ updatePreview();
+}
+
+void LLDensityCtrl::onLinearChanged()
+{
+ updateProfile();
+ updatePreview();
+}
+
+void LLDensityCtrl::onConstantChanged()
+{
+ updateProfile();
+ updatePreview();
+}
+
+void LLDensityCtrl::onMaxAltitudeChanged()
+{
+ updateProfile();
+ updatePreview();
+}
+
+void LLDensityCtrl::onAnisoFactorChanged()
+{
+ updateProfile();
+}
+
+void LLDensityCtrl::updatePreview()
+{
+ // AdvancedAtmospherics TODO
+ // Generate image according to current density profile
+}
+
diff --git a/indra/newview/lldensityctrl.h b/indra/newview/lldensityctrl.h
new file mode 100644
index 0000000000..789022803c
--- /dev/null
+++ b/indra/newview/lldensityctrl.h
@@ -0,0 +1,104 @@
+/**
+* @file lldensityctrl.h
+* @brief Control for specifying density over a height range for sky settings.
+*
+* $LicenseInfo:firstyear=2011&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2011, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#ifndef LLDENSITY_CTRL_H
+#define LLDENSITY_CTRL_H
+
+#include "lluictrl.h"
+#include "llsettingssky.h"
+#include "lltextbox.h"
+#include "llsliderctrl.h"
+
+class LLDensityCtrl : public LLUICtrl
+{
+public:
+ static const std::string DENSITY_RAYLEIGH;
+ static const std::string DENSITY_MIE;
+ static const std::string DENSITY_ABSORPTION;
+
+ // Type of density profile this tab is updating
+ enum DensityProfileType
+ {
+ Rayleigh,
+ Mie,
+ Absorption
+ };
+
+ static const std::string& NameForDensityProfileType(DensityProfileType t);
+
+ struct Params : public LLInitParam::Block
+ {
+ Optional lbl_exponential,
+ lbl_exponential_scale,
+ lbl_linear,
+ lbl_constant,
+ lbl_max_altitude,
+ lbl_aniso_factor;
+
+ Optional exponential_slider,
+ exponential_scale_slider,
+ linear_slider,
+ constant_slider,
+ aniso_factor_slider;
+
+ Optional image_density_feedback;
+
+ DensityProfileType profile_type;
+ Params();
+ };
+
+ virtual BOOL postBuild() override;
+ virtual void setEnabled(BOOL enabled) override;
+
+ void setProfileType(DensityProfileType t) { mProfileType = t; }
+
+ void refresh();
+ void updateProfile();
+
+ LLSettingsSky::ptr_t getSky() const { return mSkySettings; }
+ void setSky(const LLSettingsSky::ptr_t &sky) { mSkySettings = sky; refresh(); }
+
+protected:
+ friend class LLUICtrlFactory;
+ LLDensityCtrl(const Params&);
+
+ LLSD getProfileConfig();
+ void updatePreview();
+
+private:
+ void onExponentialChanged();
+ void onExponentialScaleFactorChanged();
+ void onLinearChanged();
+ void onConstantChanged();
+ void onMaxAltitudeChanged();
+ void onAnisoFactorChanged();
+
+ DensityProfileType mProfileType = Rayleigh;
+ LLUIImage* mImgDensityFeedback = nullptr;
+ LLSettingsSky::ptr_t mSkySettings;
+};
+
+#endif LLDENSITY_CTRL_H
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 82888b2df6..2aee7b450a 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -127,7 +127,7 @@ LLDrawPool::LLDrawPool(const U32 type)
mType = type;
sNumDrawPools++;
mId = sNumDrawPools;
- mVertexShaderLevel = 0;
+ mShaderLevel = 0;
mSkipRender = false;
}
@@ -141,7 +141,7 @@ LLViewerTexture *LLDrawPool::getDebugTexture()
return NULL;
}
-//virtuals
+//virtual
void LLDrawPool::beginRenderPass( S32 pass )
{
}
@@ -406,9 +406,9 @@ void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL t
}
}
-void LLRenderPass::renderTexture(U32 type, U32 mask)
+void LLRenderPass::renderTexture(U32 type, U32 mask, BOOL batch_textures)
{
- pushBatches(type, mask, TRUE);
+ pushBatches(type, mask, true, batch_textures);
}
void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
@@ -449,10 +449,10 @@ void LLRenderPass::applyModelMatrix(const LLDrawInfo& params)
if (params.mModelMatrix != gGLLastMatrix)
{
gGLLastMatrix = params.mModelMatrix;
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.loadMatrix(gGLModelView);
if (params.mModelMatrix)
{
- llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW);
gGL.multMatrix((GLfloat*) params.mModelMatrix->mMatrix);
}
gPipeline.mMatrixOpCount++;
@@ -461,6 +461,11 @@ void LLRenderPass::applyModelMatrix(const LLDrawInfo& params)
void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
{
+ if (!params.mCount)
+ {
+ return;
+ }
+
applyModelMatrix(params);
bool tex_setup = false;
@@ -515,6 +520,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
if (tex_setup)
{
+ gGL.matrixMode(LLRender::MM_TEXTURE0);
gGL.loadIdentity();
gGL.matrixMode(LLRender::MM_MODELVIEW);
}
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index bc299cc89f..4eb9a4151d 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -107,7 +107,7 @@ public:
virtual void prerender() = 0;
virtual U32 getVertexDataMask() = 0;
virtual BOOL verify() const { return TRUE; } // Verify that all data in the draw pool is correct!
- virtual S32 getVertexShaderLevel() const { return mVertexShaderLevel; }
+ 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.
@@ -116,7 +116,7 @@ public:
virtual void resetDrawOrders() = 0;
protected:
- S32 mVertexShaderLevel;
+ S32 mShaderLevel;
S32 mId;
U32 mType; // Type of draw pool
BOOL mSkipRender;
@@ -174,7 +174,7 @@ public:
virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);
virtual void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
virtual void renderGroups(U32 type, U32 mask, BOOL texture = TRUE);
- virtual void renderTexture(U32 type, U32 mask);
+ virtual void renderTexture(U32 type, U32 mask, BOOL batch_textures = TRUE);
};
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 846edf8bae..536eaffe0c 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -53,6 +53,22 @@ BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
static BOOL deferred_render = FALSE;
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SETUP("Alpha Setup");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_GROUP_LOOP("Alpha Group");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_PUSH("Alpha Push Verts");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED("Alpha Deferred");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SETBUFFER("Alpha SetBuffer");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DRAW("Alpha Draw");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_TEX_BINDS("Alpha Tex Binds");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MATS("Alpha Mat Tex Binds");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_GLOW("Alpha Glow Binds");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SHADER_BINDS("Alpha Shader Binds");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS("Alpha Def Binds");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS("Alpha Def Tex Binds");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MESH_REBUILD("Alpha Mesh Rebuild");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_EMISSIVE("Alpha Emissive");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_LIGHT_SETUP("Alpha Light Setup");
+
LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) :
LLRenderPass(type), current_shader(NULL), target_shader(NULL),
simple_shader(NULL), fullbright_shader(NULL), emissive_shader(NULL),
@@ -69,7 +85,7 @@ LLDrawPoolAlpha::~LLDrawPoolAlpha()
void LLDrawPoolAlpha::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
@@ -94,38 +110,38 @@ S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED);
+
+ //F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+ static LLCachedControl gamma(gSavedSettings, "RenderDeferredDisplayGamma");
+
+ emissive_shader = (LLPipeline::sRenderDeferred) ? &gDeferredEmissiveProgram :
+ (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
+
+ emissive_shader->bind();
+ emissive_shader->uniform1i(LLShaderMgr::NO_ATMO, (LLPipeline::sRenderingHUDs) ? 1 : 0);
+ emissive_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ emissive_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
if (pass == 0)
{
- if (LLPipeline::sImpostorRender)
- {
- simple_shader = &gDeferredAlphaImpostorProgram;
- fullbright_shader = &gDeferredFullbrightProgram;
- }
- else if (LLPipeline::sUnderWaterRender)
- {
- simple_shader = &gDeferredAlphaWaterProgram;
- fullbright_shader = &gDeferredFullbrightWaterProgram;
- }
- else
- {
- simple_shader = &gDeferredAlphaProgram;
- fullbright_shader = &gDeferredFullbrightProgram;
- }
-
- //F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
- static LLCachedControl gamma(gSavedSettings, "RenderDeferredDisplayGamma");
+ fullbright_shader = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightProgram :
+ (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightProgram;
fullbright_shader->bind();
fullbright_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
fullbright_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+ fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
fullbright_shader->unbind();
+ simple_shader = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
+ (LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram;
+
//prime simple shader (loads shadow relevant uniforms)
gPipeline.bindDeferredShader(*simple_shader);
simple_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
}
else if (!LLPipeline::sImpostorRender)
{
@@ -139,25 +155,8 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
gObjectFullbrightAlphaMaskProgram.setMinimumAlpha(0.33f);
}
-
- if (LLPipeline::sRenderDeferred)
- {
- emissive_shader = &gDeferredEmissiveProgram;
- }
- else
- {
- if (LLPipeline::sUnderWaterRender)
- {
- emissive_shader = &gObjectEmissiveWaterProgram;
- }
- else
- {
- emissive_shader = &gObjectEmissiveProgram;
- }
- }
-
deferred_render = TRUE;
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
// Start out with no shaders.
current_shader = target_shader = NULL;
@@ -167,6 +166,8 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)
{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED);
+
if (pass == 1 && !LLPipeline::sImpostorRender)
{
gPipeline.mDeferredDepth.flush();
@@ -180,44 +181,64 @@ void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)
void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED);
render(pass);
}
void LLDrawPoolAlpha::beginRenderPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_SETUP);
- if (LLPipeline::sImpostorRender)
- {
- simple_shader = &gObjectSimpleImpostorProgram;
- fullbright_shader = &gObjectFullbrightProgram;
- emissive_shader = &gObjectEmissiveProgram;
- }
- else if (LLPipeline::sUnderWaterRender)
- {
- simple_shader = &gObjectSimpleWaterProgram;
- fullbright_shader = &gObjectFullbrightWaterProgram;
- emissive_shader = &gObjectEmissiveWaterProgram;
- }
- else
- {
- simple_shader = &gObjectSimpleProgram;
- fullbright_shader = &gObjectFullbrightProgram;
- emissive_shader = &gObjectEmissiveProgram;
- }
+ simple_shader = (LLPipeline::sImpostorRender) ? &gObjectSimpleImpostorProgram :
+ (LLPipeline::sUnderWaterRender) ? &gObjectSimpleWaterProgram : &gObjectSimpleProgram;
- if (mVertexShaderLevel > 0)
+ fullbright_shader = (LLPipeline::sImpostorRender) ? &gObjectFullbrightProgram :
+ (LLPipeline::sUnderWaterRender) ? &gObjectFullbrightWaterProgram : &gObjectFullbrightProgram;
+
+ emissive_shader = (LLPipeline::sImpostorRender) ? &gObjectEmissiveProgram :
+ (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
+
+ if (LLPipeline::sImpostorRender)
{
- // Start out with no shaders.
- current_shader = target_shader = NULL;
- LLGLSLShader::bindNoShader();
+ if (mShaderLevel > 0)
+ {
+ fullbright_shader->bind();
+ fullbright_shader->setMinimumAlpha(0.5f);
+ fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
+ simple_shader->bind();
+ simple_shader->setMinimumAlpha(0.5f);
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
+ }
+ else
+ {
+ gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); //OK
+ }
}
+ else
+ {
+ if (mShaderLevel > 0)
+ {
+ fullbright_shader->bind();
+ fullbright_shader->setMinimumAlpha(0.f);
+ fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
+ simple_shader->bind();
+ simple_shader->setMinimumAlpha(0.f);
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
+ }
+ else
+ {
+ gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
+ }
+ }
gPipeline.enableLightsDynamic();
+
+ LLGLSLShader::bindNoShader();
+ current_shader = NULL;
}
void LLDrawPoolAlpha::endRenderPass( S32 pass )
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_SETUP);
LLRenderPass::endRenderPass(pass);
if(gPipeline.canUseWindLightShaders())
@@ -260,38 +281,9 @@ void LLDrawPoolAlpha::render(S32 pass)
mAlphaSFactor = LLRender::BF_ZERO; // } glow suppression
mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
-
- if (mVertexShaderLevel > 0)
- {
- if (LLPipeline::sImpostorRender)
- {
- fullbright_shader->bind();
- fullbright_shader->setMinimumAlpha(0.5f);
- simple_shader->bind();
- simple_shader->setMinimumAlpha(0.5f);
- }
- else
- {
- fullbright_shader->bind();
- fullbright_shader->setMinimumAlpha(0.f);
- simple_shader->bind();
- simple_shader->setMinimumAlpha(0.f);
- }
- }
- else
- {
- if (LLPipeline::sImpostorRender)
- {
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); //OK
- }
- else
- {
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
- }
- }
}
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, pass);
}
@@ -316,7 +308,7 @@ void LLDrawPoolAlpha::render(S32 pass)
}
else
{
- gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
+ gPipeline.enableLightsFullbright();
}
gGL.diffuseColor4f(1,0,0,1);
@@ -375,13 +367,257 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
}
}
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_GROUP_LOOP("Alpha Group");
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_PUSH("Alpha Push Verts");
-// LL materials support merge error
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_GLOW("Alpha Glow");
+inline bool IsFullbright(LLDrawInfo& params)
+{
+ return params.mFullbright;
+}
+
+inline bool IsMaterial(LLDrawInfo& params)
+{
+ return params.mMaterial != nullptr;
+}
+
+inline bool IsEmissive(LLDrawInfo& params)
+{
+ return params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE);
+}
+
+inline void Draw(LLDrawInfo* draw, U32 mask)
+{
+ draw->mVertexBuffer->setBuffer(mask);
+ LLRenderPass::applyModelMatrix(*draw);
+ draw->mVertexBuffer->drawRange(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
+ gPipeline.addTrianglesDrawn(draw->mCount, draw->mDrawMode);
+}
+
+bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_material, LLGLSLShader* current_shader)
+{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_TEX_BINDS);
+
+ bool tex_setup = false;
+
+ if (deferred_render && use_material && current_shader)
+ {
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS);
+ if (draw->mNormalMap)
+ {
+ draw->mNormalMap->addTextureStats(draw->mVSize);
+ current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap);
+ }
+
+ if (draw->mSpecularMap)
+ {
+ draw->mSpecularMap->addTextureStats(draw->mVSize);
+ current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap);
+ }
+ }
+ else if (current_shader == simple_shader)
+ {
+ LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(draw->mVSize);
+ LLViewerFetchedTexture::sWhiteImagep->addTextureStats(draw->mVSize);
+ current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
+ current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
+ }
+ if (use_shaders && draw->mTextureList.size() > 1)
+ {
+ for (U32 i = 0; i < draw->mTextureList.size(); ++i)
+ {
+ if (draw->mTextureList[i].notNull())
+ {
+ gGL.getTexUnit(i)->bind(draw->mTextureList[i], TRUE);
+ }
+ }
+ }
+ else
+ { //not batching textures or batch has only 1 texture -- might need a texture matrix
+ if (draw->mTexture.notNull())
+ {
+ draw->mTexture->addTextureStats(draw->mVSize);
+ if (use_shaders && use_material)
+ {
+ current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, draw->mTexture);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->bind(draw->mTexture, TRUE) ;
+ }
+
+ if (draw->mTextureMatrix)
+ {
+ tex_setup = true;
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadMatrix((GLfloat*) draw->mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+ }
+ }
+ else
+ {
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+ }
+
+ return tex_setup;
+}
+
+void LLDrawPoolAlpha::RestoreTexSetup(bool tex_setup)
+{
+ if (tex_setup)
+ {
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
+}
+
+void LLDrawPoolAlpha::renderSimples(U32 mask, std::vector& simples)
+{
+ gPipeline.enableLightsDynamic();
+ simple_shader->bind();
+ simple_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
+ simple_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
+ simple_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);
+ simple_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f);
+ simple_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 0.0f);
+ bool use_shaders = gPipeline.canUseVertexShaders();
+ for (LLDrawInfo* draw : simples)
+ {
+ bool tex_setup = TexSetup(draw, use_shaders, false, simple_shader);
+ LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test);
+ gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
+
+ Draw(draw, mask);
+ RestoreTexSetup(tex_setup);
+ }
+ simple_shader->unbind();
+}
+
+void LLDrawPoolAlpha::renderFullbrights(U32 mask, std::vector& fullbrights)
+{
+ gPipeline.enableLightsFullbright();
+ fullbright_shader->bind();
+ fullbright_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.0f);
+ bool use_shaders = gPipeline.canUseVertexShaders();
+ for (LLDrawInfo* draw : fullbrights)
+ {
+ bool tex_setup = TexSetup(draw, use_shaders, false, fullbright_shader);
+
+ LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test);
+ gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
+
+ Draw(draw, mask & ~(LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2));
+ RestoreTexSetup(tex_setup);
+ }
+ fullbright_shader->unbind();
+}
+
+void LLDrawPoolAlpha::renderMaterials(U32 mask, std::vector& materials)
+{
+ LLGLSLShader::bindNoShader();
+ current_shader = NULL;
+
+ gPipeline.enableLightsDynamic();
+ bool use_shaders = gPipeline.canUseVertexShaders();
+ for (LLDrawInfo* draw : materials)
+ {
+ U32 mask = draw->mShaderMask;
+
+ llassert(mask < LLMaterial::SHADER_COUNT);
+ target_shader = (LLPipeline::sUnderWaterRender) ? &(gDeferredMaterialWaterProgram[mask]) : &(gDeferredMaterialProgram[mask]);
+
+ if (current_shader != target_shader)
+ {
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS);
+ if (current_shader)
+ {
+ gPipeline.unbindDeferredShader(*current_shader);
+ }
+ gPipeline.bindDeferredShader(*target_shader);
+ current_shader = target_shader;
+ }
+
+ bool tex_setup = TexSetup(draw, use_shaders, true, current_shader);
+
+ current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, draw->mSpecColor.mV[0], draw->mSpecColor.mV[1], draw->mSpecColor.mV[2], draw->mSpecColor.mV[3]);
+ current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, draw->mEnvIntensity);
+ current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, draw->mFullbright ? 1.f : 0.f);
+
+ {
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS);
+ if (draw->mNormalMap)
+ {
+ draw->mNormalMap->addTextureStats(draw->mVSize);
+ current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap);
+ }
+
+ if (draw->mSpecularMap)
+ {
+ draw->mSpecularMap->addTextureStats(draw->mVSize);
+ current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap);
+ }
+ }
+
+ LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test);
+ gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
+
+ Draw(draw, mask);
+ RestoreTexSetup(tex_setup);
+ }
+}
+
+void LLDrawPoolAlpha::drawEmissive(U32 mask, LLDrawInfo* draw)
+{
+ draw->mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);
+ draw->mVertexBuffer->drawRange(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
+ gPipeline.addTrianglesDrawn(draw->mCount, draw->mDrawMode);
+}
+
+void LLDrawPoolAlpha::drawEmissiveInline(U32 mask, LLDrawInfo* draw)
+{
+ // install glow-accumulating blend mode
+ gGL.blendFunc(
+ LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color
+ LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow)
+
+ emissive_shader->bind();
+
+ drawEmissive(mask, draw);
+
+ // restore our alpha blend mode
+ gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
+
+ current_shader->bind();
+}
+
+void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector& emissives)
+{
+ emissive_shader->bind();
+ emissive_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f);
+
+ gPipeline.enableLightsDynamic();
+
+ // install glow-accumulating blend mode
+ // don't touch color, add to alpha (glow)
+ gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE);
+ bool use_shaders = gPipeline.canUseVertexShaders();
+ for (LLDrawInfo* draw : emissives)
+ {
+ bool tex_setup = TexSetup(draw, use_shaders, false, emissive_shader);
+ drawEmissive(mask, draw);
+ RestoreTexSetup(tex_setup);
+ }
+
+ // restore our alpha blend mode
+ gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
+
+ emissive_shader->unbind();
+}
void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
{
+ BOOL batch_fullbrights = gSavedSettings.getBOOL("RenderAlphaBatchFullbrights");
+ BOOL batch_emissives = gSavedSettings.getBOOL("RenderAlphaBatchEmissives");
BOOL initialized_lighting = FALSE;
BOOL light_enabled = TRUE;
@@ -396,9 +632,13 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
if (group->getSpatialPartition()->mRenderByGroup &&
!group->isDead())
{
+ std::vector emissives;
+ std::vector fullbrights;
+
bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE
|| group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE;
+ bool draw_glow_for_this_partition = mShaderLevel > 0; // no shaders = no glow.
// Dont suspend partical processing while particles are hidden, just skip over drawing them
if(!(gPipeline.sRenderParticles) && (
@@ -408,10 +648,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
continue;
}
//
-
-
- bool draw_glow_for_this_partition = mVertexShaderLevel > 0; // no shaders = no glow.
-
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_GROUP_LOOP);
@@ -423,11 +659,11 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo& params = **k;
-
- if ((params.mVertexBuffer->getTypeMask() & mask) != mask)
+ U32 have_mask = params.mVertexBuffer->getTypeMask() & mask;
+ if (have_mask != mask)
{ //FIXME!
LL_WARNS_ONCE() << "Missing required components, expected mask: " << mask
- << " present: " << (params.mVertexBuffer->getTypeMask() & mask)
+ << " present: " << have_mask
<< ". Skipping render batch." << LL_ENDL;
continue;
}
@@ -449,6 +685,12 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
}
}
+ if (params.mFullbright && batch_fullbrights)
+ {
+ fullbrights.push_back(¶ms);
+ continue;
+ }
+
LLRenderPass::applyModelMatrix(params);
LLMaterial* mat = NULL;
@@ -463,6 +705,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
// Turn off lighting if it hasn't already been so.
if (light_enabled || !initialized_lighting)
{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_LIGHT_SETUP);
+
initialized_lighting = TRUE;
if (use_shaders)
{
@@ -470,7 +714,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
}
else
{
- gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
+ gPipeline.enableLightsFullbright();
}
light_enabled = FALSE;
}
@@ -478,6 +722,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
// Turn on lighting if it isn't already.
else if (!light_enabled || !initialized_lighting)
{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_LIGHT_SETUP);
+
initialized_lighting = TRUE;
if (use_shaders)
{
@@ -504,7 +750,9 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
if (current_shader != target_shader)
{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS);
gPipeline.bindDeferredShader(*target_shader);
+ current_shader = target_shader;
}
}
else if (!params.mFullbright)
@@ -519,6 +767,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
if(use_shaders && (current_shader != target_shader))
{// If we need shaders, and we're not ALREADY using the proper shader, then bind it
// (this way we won't rebind shaders unnecessarily).
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_SHADER_BINDS);
current_shader = target_shader;
current_shader->bind();
}
@@ -528,83 +777,31 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
current_shader = NULL;
}
- if (use_shaders && mat)
- {
- // We have a material. Supply the appropriate data here.
- if (LLPipeline::sRenderDeferred)
- {
- current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);
- current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity);
- current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f);
+ LLVector4 spec_color(1, 1, 1, 1);
+ F32 env_intensity = 0.0f;
+ F32 brightness = 1.0f;
- if (params.mNormalMap)
- {
- params.mNormalMap->addTextureStats(params.mVSize);
- current_shader->bindTexture(LLShaderMgr::BUMP_MAP, params.mNormalMap);
- }
-
- if (params.mSpecularMap)
- {
- params.mSpecularMap->addTextureStats(params.mVSize);
- current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap);
- }
- }
-
- } else if (LLPipeline::sRenderDeferred && current_shader && (current_shader == simple_shader))
+ // We have a material. Supply the appropriate data here.
+ if (use_shaders && mat && deferred_render)
{
- current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);
- current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f);
- LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(params.mVSize);
- current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
- LLViewerFetchedTexture::sWhiteImagep->addTextureStats(params.mVSize);
- current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
- }
+ spec_color = params.mSpecColor;
+ env_intensity = params.mEnvIntensity;
+ brightness = params.mFullbright ? 1.f : 0.f;
+ }
+
+ if (current_shader)
+ {
+ current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, spec_color.mV[0], spec_color.mV[1], spec_color.mV[2], spec_color.mV[3]);
+ current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env_intensity);
+ current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, brightness);
+ }
if (params.mGroup)
{
params.mGroup->rebuildMesh();
}
- bool tex_setup = false;
-
- if (use_shaders && params.mTextureList.size() > 1)
- {
- for (U32 i = 0; i < params.mTextureList.size(); ++i)
- {
- if (params.mTextureList[i].notNull())
- {
- gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE);
- }
- }
- }
- else
- { //not batching textures or batch has only 1 texture -- might need a texture matrix
- if (params.mTexture.notNull())
- {
- params.mTexture->addTextureStats(params.mVSize);
- if (use_shaders && mat)
- {
- current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, params.mTexture);
- }
- else
- {
- gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;
- }
-
- if (params.mTextureMatrix)
- {
- tex_setup = true;
- gGL.getTexUnit(0)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
- gPipeline.mTextureMatrixOps++;
- }
- }
- else
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- }
- }
+ bool tex_setup = TexSetup(¶ms, use_shaders, use_shaders && (mat != nullptr), current_shader);
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_PUSH);
@@ -614,62 +811,56 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0));
- params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
- gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
+ {
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DRAW);
+ params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+ gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
+ }
}
-
- // If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha.
+
+ // If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls is expensive, but glow must be drawn Z-sorted with alpha.
if (current_shader &&
draw_glow_for_this_partition &&
- // Re-add particle rendering optimization
- //params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE))
- params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE) &&
- (!params.mParticle || params.mHasGlow))
- //
+ params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE))
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_GLOW);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_EMISSIVE);
- // install glow-accumulating blend mode
- gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color
- LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow)
-
- // Performance fix when not using OpenGL core profile
- if (LLRender::sGLCoreProfile)
- {
- //
- emissive_shader->bind();
-
- params.mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);
-
- // do the actual drawing, again
- params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
- gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
-
- // restore our alpha blend mode
- gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
-
- current_shader->bind();
- // Performance fix when not using OpenGL core profile
- }
- else
- {
- params.mVertexBuffer->setBuffer(mask | LLVertexBuffer::MAP_EMISSIVE);
-
- // do the actual drawing, again
- params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
- gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
- }
- //
+ if (batch_emissives)
+ {
+ emissives.push_back(¶ms);
+ }
+ else
+ {
+ drawEmissiveInline(mask, ¶ms);
+ }
}
if (tex_setup)
{
gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadIdentity();
gGL.matrixMode(LLRender::MM_MODELVIEW);
}
}
- }
+
+ if (batch_fullbrights)
+ {
+ light_enabled = false;
+ renderFullbrights(mask, fullbrights);
+ }
+
+ if (batch_emissives)
+ {
+ light_enabled = true;
+ renderEmissives(mask, emissives);
+ }
+
+ if (current_shader)
+ {
+ current_shader->bind();
+ }
+ }
}
gGL.setSceneBlendType(LLRender::BT_ALPHA);
diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h
index d064a3a324..a069f805e8 100644
--- a/indra/newview/lldrawpoolalpha.h
+++ b/indra/newview/lldrawpoolalpha.h
@@ -75,6 +75,17 @@ private:
LLGLSLShader* fullbright_shader;
LLGLSLShader* emissive_shader;
+ void renderSimples(U32 mask, std::vector& simples);
+ void renderFullbrights(U32 mask, std::vector& fullbrights);
+ void renderMaterials(U32 mask, std::vector& fullbrights);
+ void renderEmissives(U32 mask, std::vector& emissives);
+
+ void drawEmissive(U32 mask, LLDrawInfo* draw);
+ void drawEmissiveInline(U32 mask, LLDrawInfo* draw);
+
+ bool TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_material, LLGLSLShader* current_shader);
+ void RestoreTexSetup(bool tex_setup);
+
// our 'normal' alpha blend function for this pass
LLRender::eBlendFactor mColorSFactor;
LLRender::eBlendFactor mColorDFactor;
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 10cb5268a6..ec5bf91b8b 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -38,6 +38,7 @@
#include "lldrawable.h"
#include "lldrawpoolbump.h"
#include "llface.h"
+#include "llvolume.h"
#include "llmeshrepository.h"
#include "llsky.h"
#include "llviewercamera.h"
@@ -152,16 +153,16 @@ LLDrawPool *LLDrawPoolAvatar::instancePool()
}
-S32 LLDrawPoolAvatar::getVertexShaderLevel() const
+S32 LLDrawPoolAvatar::getShaderLevel() const
{
- return (S32) LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);
+ return (S32) LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);
}
void LLDrawPoolAvatar::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
if (sShaderLevel > 0)
{
@@ -312,7 +313,7 @@ void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass)
void LLDrawPoolAvatar::beginPostDeferredAlpha()
{
sSkipOpaque = TRUE;
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
sVertexProgram = &gDeferredAvatarAlphaProgram;
sRenderingSkinned = TRUE;
@@ -403,7 +404,7 @@ void LLDrawPoolAvatar::endPostDeferredAlpha()
gPipeline.unbindDeferredShader(*sVertexProgram);
sDiffuseChannel = 0;
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
}
void LLDrawPoolAvatar::renderPostDeferred(S32 pass)
@@ -462,7 +463,12 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
sVertexProgram = &gDeferredAvatarAlphaShadowProgram;
// bind diffuse tex so we can reference the alpha channel...
- sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
+ sDiffuseChannel = 0;
+ if (loc != -1)
+ {
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ }
if ((sShaderLevel > 0)) // for hardware blending
{
@@ -477,7 +483,12 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
sVertexProgram = &gDeferredAvatarAlphaMaskShadowProgram;
// bind diffuse tex so we can reference the alpha channel...
- sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
+ sDiffuseChannel = 0;
+ if (loc != -1)
+ {
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ }
if ((sShaderLevel > 0)) // for hardware blending
{
@@ -492,7 +503,12 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
sVertexProgram = &gDeferredAttachmentAlphaShadowProgram;
// bind diffuse tex so we can reference the alpha channel...
- sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
+ sDiffuseChannel = 0;
+ if (loc != -1)
+ {
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ }
if ((sShaderLevel > 0)) // for hardware blending
{
@@ -507,7 +523,12 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
sVertexProgram = &gDeferredAttachmentAlphaMaskShadowProgram;
// bind diffuse tex so we can reference the alpha channel...
- sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
+ sDiffuseChannel = 0;
+ if (loc != -1)
+ {
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ }
if ((sShaderLevel > 0)) // for hardware blending
{
@@ -520,7 +541,12 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
else // SHADOW_PASS_ATTACHMENT_OPAQUE
{
sVertexProgram = &gDeferredAttachmentShadowProgram;
- sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
+ sDiffuseChannel = 0;
+ if (loc != -1)
+ {
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ }
sVertexProgram->bind();
}
}
@@ -786,7 +812,7 @@ void LLDrawPoolAvatar::beginImpostor()
gImpostorProgram.setMinimumAlpha(0.01f);
}
- gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
+ gPipeline.enableLightsFullbright();
sDiffuseChannel = 0;
}
@@ -816,6 +842,14 @@ void LLDrawPoolAvatar::beginRigid()
{ //eyeballs render with the specular shader
sVertexProgram->bind();
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
}
else
@@ -826,7 +860,7 @@ void LLDrawPoolAvatar::beginRigid()
void LLDrawPoolAvatar::endRigid()
{
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
if (sVertexProgram != NULL)
{
sVertexProgram->unbind();
@@ -851,7 +885,7 @@ void LLDrawPoolAvatar::beginDeferredImpostor()
void LLDrawPoolAvatar::endDeferredImpostor()
{
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL);
sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP);
sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
@@ -866,11 +900,19 @@ void LLDrawPoolAvatar::beginDeferredRigid()
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
sVertexProgram->bind();
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
void LLDrawPoolAvatar::endDeferredRigid()
{
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
sVertexProgram->unbind();
gGL.getTexUnit(0)->activate();
@@ -909,6 +951,14 @@ void LLDrawPoolAvatar::beginSkinned()
sVertexProgram->bind();
sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
gGL.getTexUnit(0)->activate();
}
else
@@ -918,6 +968,14 @@ void LLDrawPoolAvatar::beginSkinned()
// software skinning, use a basic shader for windlight.
// TODO: find a better fallback method for software skinning.
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
}
@@ -936,7 +994,7 @@ void LLDrawPoolAvatar::endSkinned()
sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP);
gGL.getTexUnit(0)->activate();
sVertexProgram->unbind();
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
}
else
{
@@ -980,6 +1038,14 @@ void LLDrawPoolAvatar::beginRiggedSimple()
{
sDiffuseChannel = 0;
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
}
@@ -1045,6 +1111,16 @@ void LLDrawPoolAvatar::beginRiggedGlow()
sVertexProgram->bind();
sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, LLPipeline::sRenderDeferred ? 2.2f : 1.1f);
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
//F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
static LLCachedControl gamma(gSavedSettings, "RenderDeferredDisplayGamma");
sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
@@ -1093,17 +1169,23 @@ void LLDrawPoolAvatar::beginRiggedFullbright()
sDiffuseChannel = 0;
sVertexProgram->bind();
- if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else if (LLPipeline::sRenderDeferred)
{
- sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
- }
- else
- {
- sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
-
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
//F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
static LLCachedControl gamma(gSavedSettings, "RenderDeferredDisplayGamma");
sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+ }
+ else
+ {
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
}
}
}
@@ -1146,6 +1228,14 @@ void LLDrawPoolAvatar::beginRiggedShinySimple()
if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
{
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false);
}
}
@@ -1196,18 +1286,33 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()
if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
{
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false);
- if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
+ if (LLPipeline::sRenderingHUDs)
{
sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
- }
- else
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else if (LLPipeline::sRenderDeferred)
{
- sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
//F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
static LLCachedControl gamma(gSavedSettings, "RenderDeferredDisplayGamma");
sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+ else
+ {
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
}
}
}
@@ -1229,6 +1334,14 @@ void LLDrawPoolAvatar::beginDeferredRiggedSimple()
sVertexProgram = &gDeferredSkinnedDiffuseProgram;
sDiffuseChannel = 0;
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
void LLDrawPoolAvatar::endDeferredRiggedSimple()
@@ -1242,6 +1355,14 @@ void LLDrawPoolAvatar::beginDeferredRiggedBump()
{
sVertexProgram = &gDeferredSkinnedBumpProgram;
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
}
@@ -1274,6 +1395,14 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass)
}
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
@@ -1301,13 +1430,21 @@ void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass)
void LLDrawPoolAvatar::beginDeferredSkinned()
{
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
sVertexProgram = &gDeferredAvatarProgram;
sRenderingSkinned = TRUE;
sVertexProgram->bind();
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
-
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
gGL.getTexUnit(0)->activate();
}
@@ -1320,7 +1457,7 @@ void LLDrawPoolAvatar::endDeferredSkinned()
sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
gGL.getTexUnit(0)->activate();
}
@@ -1854,7 +1991,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
LLFace* face,
const LLMeshSkinInfo* skin,
LLVolume* volume,
- const LLVolumeFace& vol_face)
+ LLVolumeFace& vol_face)
{
LLVector4a* weights = vol_face.mWeights;
if (!weights)
@@ -1869,8 +2006,6 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
}
//
- // FIXME ugly const cast
- LLSkinningUtil::scrubInvalidJoints(avatar, const_cast(skin));
LLPointer buffer = face->getVertexBuffer();
LLDrawable* drawable = face->getDrawable();
@@ -1880,6 +2015,48 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
return;
}
+ const U32 max_joints = LLSkinningUtil::getMaxJointCount();
+
+#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
+ #define CONDITION_WEIGHT(f) ((U8)llclamp((S32)f, (S32)0, (S32)max_joints-1))
+ LLVector4a* just_weights = vol_face.mJustWeights;
+ // we need to calculate the separated indices and store just the matrix weights for this vol...
+ if (!vol_face.mJointIndices)
+ {
+ // not very consty after all...
+ vol_face.allocateJointIndices(vol_face.mNumVertices);
+ just_weights = vol_face.mJustWeights;
+
+ U8* joint_indices_cursor = vol_face.mJointIndices;
+ for (int i = 0; i < vol_face.mNumVertices; i++)
+ {
+ F32* w = weights[i].getF32ptr();
+ F32* w_ = just_weights[i].getF32ptr();
+
+ F32 w0 = floorf(w[0]);
+ F32 w1 = floorf(w[1]);
+ F32 w2 = floorf(w[2]);
+ F32 w3 = floorf(w[3]);
+
+ joint_indices_cursor[0] = CONDITION_WEIGHT(w0);
+ joint_indices_cursor[1] = CONDITION_WEIGHT(w1);
+ joint_indices_cursor[2] = CONDITION_WEIGHT(w2);
+ joint_indices_cursor[3] = CONDITION_WEIGHT(w3);
+
+ // remove joint portion of combined weight
+ w_[0] = w[0] - w0;
+ w_[1] = w[1] - w1;
+ w_[2] = w[2] - w2;
+ w_[3] = w[3] - w3;
+
+ joint_indices_cursor += 4;
+ }
+ }
+#endif
+
+ // FIXME ugly const cast
+ LLSkinningUtil::scrubInvalidJoints(avatar, const_cast(skin));
+
U32 data_mask = face->getRiggedVertexBufferDataMask();
if (!vol_face.mWeightsScrubbed)
@@ -1972,33 +2149,70 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
LLMatrix4a bind_shape_matrix;
bind_shape_matrix.loadu(skin->mBindShapeMatrix);
- const U32 max_joints = LLSkinningUtil::getMaxJointCount();
- for (U32 j = 0; j < buffer->getNumVerts(); ++j)
- {
- LLMatrix4a final_mat;
+#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
+ U8* joint_indices_cursor = vol_face.mJointIndices;
+ // fast path with joint indices separate from weights
+ if (joint_indices_cursor)
+ {
+ LLMatrix4a src[4];
+ for (U32 j = 0; j < buffer->getNumVerts(); ++j)
+ {
+ LLMatrix4a final_mat;
+ //LLMatrix4a final_mat_correct;
- // Use the SSE2 version
- // LLSkinningUtil::getPerVertexSkinMatrix( weights[ j ].getF32ptr(), mat, false, final_mat, max_joints );
- FSSkinningUtil::getPerVertexSkinMatrixSSE( weights[ j ], mat, false, final_mat, max_joints );
- //
+ F32* jw = just_weights[j].getF32ptr();
- LLVector4a& v = vol_face.mPositions[j];
+ LLSkinningUtil::getPerVertexSkinMatrixWithIndices(jw, joint_indices_cursor, mat, final_mat, src);
- LLVector4a t;
- LLVector4a dst;
- bind_shape_matrix.affineTransform(v, t);
- final_mat.affineTransform(t, dst);
- pos[j] = dst;
+ joint_indices_cursor += 4;
- if (norm)
- {
- LLVector4a& n = vol_face.mNormals[j];
- bind_shape_matrix.rotate(n, t);
- final_mat.rotate(t, dst);
- dst.normalize3fast();
- norm[j] = dst;
- }
- }
+ LLVector4a& v = vol_face.mPositions[j];
+
+ LLVector4a t;
+ LLVector4a dst;
+ bind_shape_matrix.affineTransform(v, t);
+ final_mat.affineTransform(t, dst);
+ pos[j] = dst;
+
+ if (norm)
+ {
+ LLVector4a& n = vol_face.mNormals[j];
+ bind_shape_matrix.rotate(n, t);
+ final_mat.rotate(t, dst);
+ dst.normalize3fast();
+ norm[j] = dst;
+ }
+ }
+ }
+ // slow path with joint indices calculated from weights
+ else
+#endif
+ {
+ for (U32 j = 0; j < buffer->getNumVerts(); ++j)
+ {
+ LLMatrix4a final_mat;
+ // Use the SSE2 version
+ LLSkinningUtil::getPerVertexSkinMatrix(weights[j].getF32ptr(), mat, false, final_mat, max_joints);
+ FSSkinningUtil::getPerVertexSkinMatrixSSE(weights[j], mat, false, final_mat, max_joints);
+ //
+
+ LLVector4a& v = vol_face.mPositions[j];
+ LLVector4a t;
+ LLVector4a dst;
+ bind_shape_matrix.affineTransform(v, t);
+ final_mat.affineTransform(t, dst);
+ pos[j] = dst;
+
+ if (norm)
+ {
+ LLVector4a& n = vol_face.mNormals[j];
+ bind_shape_matrix.rotate(n, t);
+ final_mat.rotate(t, dst);
+ //dst.normalize3fast();
+ norm[j] = dst;
+ }
+ }
+ }
}
}
@@ -2303,12 +2517,24 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
if (face->mTextureMatrix && vobj->mTexAnimMode)
{
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadMatrix((F32*) face->mTextureMatrix->mMatrix);
+ U32 tex_index = gGL.getCurrentTexUnitIndex();
+
+ if (tex_index <= 1)
+ {
+ gGL.matrixMode(LLRender::eMatrixMode(LLRender::MM_TEXTURE0 + tex_index));
+ gGL.pushMatrix();
+ gGL.loadMatrix((F32*) face->mTextureMatrix->mMatrix);
+ }
+
buff->setBuffer(data_mask);
buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+
+ if (tex_index <= 1)
+ {
+ gGL.matrixMode(LLRender::eMatrixMode(LLRender::MM_TEXTURE0 + tex_index));
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
}
else
{
@@ -2377,7 +2603,7 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
stop_glerror();
- const LLVolumeFace& vol_face = volume->getVolumeFace(te);
+ LLVolumeFace& vol_face = volume->getVolumeFace(te);
updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face);
}
}
diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h
index 5de97fd747..133a95d9eb 100644
--- a/indra/newview/lldrawpoolavatar.h
+++ b/indra/newview/lldrawpoolavatar.h
@@ -176,7 +176,7 @@ typedef enum
virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
- virtual S32 getVertexShaderLevel() const;
+ virtual S32 getShaderLevel() const;
LLDrawPoolAvatar();
@@ -265,7 +265,7 @@ typedef enum
LLFace* facep,
const LLMeshSkinInfo* skin,
LLVolume* volume,
- const LLVolumeFace& vol_face);
+ LLVolumeFace& vol_face);
void updateRiggedVertexBuffers(LLVOAvatar* avatar);
void renderRigged(LLVOAvatar* avatar, U32 type, bool glow = false);
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index aeabb0fd6b..c7cb6567b5 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -196,7 +196,7 @@ LLDrawPoolBump::LLDrawPoolBump()
void LLDrawPoolBump::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
// static
@@ -208,7 +208,7 @@ S32 LLDrawPoolBump::numBumpPasses()
if (renderObjectBump)
//
{
- if (mVertexShaderLevel > 1)
+ if (mShaderLevel > 1)
{
if (LLPipeline::sImpostorRender)
{
@@ -248,7 +248,7 @@ void LLDrawPoolBump::beginRenderPass(S32 pass)
beginShiny();
break;
case 1:
- if (mVertexShaderLevel > 1)
+ if (mShaderLevel > 1)
{
beginFullbrightShiny();
}
@@ -281,7 +281,7 @@ void LLDrawPoolBump::render(S32 pass)
renderShiny();
break;
case 1:
- if (mVertexShaderLevel > 1)
+ if (mShaderLevel > 1)
{
renderFullbrightShiny();
}
@@ -308,7 +308,7 @@ void LLDrawPoolBump::endRenderPass(S32 pass)
endShiny();
break;
case 1:
- if (mVertexShaderLevel > 1)
+ if (mShaderLevel > 1)
{
endFullbrightShiny();
}
@@ -342,12 +342,12 @@ void LLDrawPoolBump::beginShiny(bool invisible)
mShiny = TRUE;
sVertexMask = VERTEX_MASK_SHINY;
// Second pass: environment map
- if (!invisible && mVertexShaderLevel > 1)
+ if (!invisible && mShaderLevel > 1)
{
sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0;
}
- if (getVertexShaderLevel() > 0)
+ if (getShaderLevel() > 0)
{
if (LLPipeline::sUnderWaterRender)
{
@@ -358,15 +358,23 @@ void LLDrawPoolBump::beginShiny(bool invisible)
shader = &gObjectShinyProgram;
}
shader->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
else
{
shader = NULL;
}
- bindCubeMap(shader, mVertexShaderLevel, diffuse_channel, cube_channel, invisible);
+ bindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel, invisible);
- if (mVertexShaderLevel > 1)
+ if (mShaderLevel > 1)
{ //indexed texture rendering, channel 0 is always diffuse
diffuse_channel = 0;
}
@@ -435,7 +443,7 @@ void LLDrawPoolBump::renderShiny(bool invisible)
if( gSky.mVOSkyp->getCubeMap() )
{
LLGLEnable blend_enable(GL_BLEND);
- if (!invisible && mVertexShaderLevel > 1)
+ if (!invisible && mShaderLevel > 1)
{
LLRenderPass::pushBatches(LLRenderPass::PASS_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
}
@@ -460,7 +468,7 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&
{
shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
- if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0)
+ if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0)
{
if (diffuse_channel != 0)
{
@@ -493,7 +501,7 @@ void LLDrawPoolBump::endShiny(bool invisible)
return;
}
- unbindCubeMap(shader, mVertexShaderLevel, diffuse_channel, cube_channel, invisible);
+ unbindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel, invisible);
if (shader)
{
shader->unbind();
@@ -541,6 +549,15 @@ void LLDrawPoolBump::beginFullbrightShiny()
LLVector4(gGLModelView+8),
LLVector4(gGLModelView+12));
shader->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
LLVector3 vec = LLVector3(gShinyOrigin) * mat;
LLVector4 vec4(vec, gShinyOrigin.mV[3]);
shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);
@@ -558,7 +575,7 @@ void LLDrawPoolBump::beginFullbrightShiny()
gGL.getTexUnit(0)->activate();
}
- if (mVertexShaderLevel > 1)
+ if (mShaderLevel > 1)
{ //indexed texture rendering, channel 0 is always diffuse
diffuse_channel = 0;
}
@@ -578,7 +595,7 @@ void LLDrawPoolBump::renderFullbrightShiny()
{
LLGLEnable blend_enable(GL_BLEND);
- if (mVertexShaderLevel > 1)
+ if (mShaderLevel > 1)
{
LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
}
@@ -1539,7 +1556,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
tex_setup = true;
}
- if (mShiny && mVertexShaderLevel > 1 && texture)
+ if (mShiny && mShaderLevel > 1 && texture)
{
if (params.mTexture.notNull())
{
diff --git a/indra/newview/lldrawpoolground.cpp b/indra/newview/lldrawpoolground.cpp
index 0ebbaf0810..a1c032954e 100644
--- a/indra/newview/lldrawpoolground.cpp
+++ b/indra/newview/lldrawpoolground.cpp
@@ -53,7 +53,7 @@ LLDrawPool *LLDrawPoolGround::instancePool()
void LLDrawPoolGround::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
}
void LLDrawPoolGround::render(S32 pass)
@@ -67,13 +67,9 @@ void LLDrawPoolGround::render(S32 pass)
return;
}
- LLGLSPipelineSkyBox gls_skybox;
+ LLGLSPipelineDepthTestSkyBox gls_skybox(true, false);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-
- LLGLSquashToFarClip far_clip(glh_get_current_projection());
-
F32 water_height = gAgent.getRegion()->getWaterHeight();
gGL.pushMatrix();
LLVector3 origin = LLViewerCamera::getInstance()->getOrigin();
@@ -81,8 +77,6 @@ void LLDrawPoolGround::render(S32 pass)
LLFace *facep = mDrawFace[0];
- gPipeline.disableLights();
-
LLOverrideFaceColor col(this, gSky.mVOSkyp->getGLFogColor());
facep->renderIndexed();
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
index 63e96a93b5..05b0c1f1a9 100644
--- a/indra/newview/lldrawpoolmaterials.cpp
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -42,7 +42,7 @@ LLDrawPoolMaterials::LLDrawPoolMaterials()
void LLDrawPoolMaterials::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
S32 LLDrawPoolMaterials::getNumDeferredPasses()
@@ -81,6 +81,15 @@ void LLDrawPoolMaterials::beginDeferredPass(S32 pass)
mShader->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ mShader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ mShader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
diffuse_channel = mShader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
LL_RECORD_BLOCK_TIME(FTM_RENDER_MATERIALS);
@@ -194,7 +203,7 @@ void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture,
tex_setup = true;
}
- if (mVertexShaderLevel > 1 && texture)
+ if (mShaderLevel > 1 && texture)
{
if (params.mTexture.notNull())
{
diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp
index bd180de6c6..f211cf6e27 100644
--- a/indra/newview/lldrawpoolsimple.cpp
+++ b/indra/newview/lldrawpoolsimple.cpp
@@ -47,6 +47,14 @@ void LLDrawPoolGlow::beginPostDeferredPass(S32 pass)
{
gDeferredEmissiveProgram.bind();
gDeferredEmissiveProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ gDeferredEmissiveProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ gDeferredEmissiveProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
static LLTrace::BlockTimerStatHandle FTM_RENDER_GLOW_PUSH("Glow Push");
@@ -82,7 +90,7 @@ void LLDrawPoolGlow::endPostDeferredPass(S32 pass)
S32 LLDrawPoolGlow::getNumPasses()
{
- if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0)
+ if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0)
{
return 1;
}
@@ -103,7 +111,7 @@ void LLDrawPoolGlow::render(S32 pass)
glPolygonOffset(-1.0f, -1.0f);
gGL.setSceneBlendType(LLRender::BT_ADD);
- U32 shader_level = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ U32 shader_level = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
//should never get here without basic shaders enabled
llassert(shader_level > 0);
@@ -119,6 +127,15 @@ void LLDrawPoolGlow::render(S32 pass)
shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f);
}
+ if (LLPipeline::sRenderingHUDs)
+ {
+ shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
gGL.setColorMask(false, true);
@@ -147,7 +164,7 @@ LLDrawPoolSimple::LLDrawPoolSimple() :
void LLDrawPoolSimple::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
void LLDrawPoolSimple::beginRenderPass(S32 pass)
@@ -167,9 +184,18 @@ void LLDrawPoolSimple::beginRenderPass(S32 pass)
simple_shader = &gObjectSimpleProgram;
}
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
simple_shader->bind();
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
else
{
@@ -187,7 +213,7 @@ void LLDrawPoolSimple::endRenderPass(S32 pass)
stop_glerror();
LLRenderPass::endRenderPass(pass);
stop_glerror();
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
simple_shader->unbind();
}
@@ -201,7 +227,7 @@ void LLDrawPoolSimple::render(S32 pass)
LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE);
gPipeline.enableLightsDynamic();
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
U32 mask = getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX;
@@ -244,7 +270,7 @@ LLDrawPoolAlphaMask::LLDrawPoolAlphaMask() :
void LLDrawPoolAlphaMask::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
void LLDrawPoolAlphaMask::beginRenderPass(S32 pass)
@@ -260,9 +286,18 @@ void LLDrawPoolAlphaMask::beginRenderPass(S32 pass)
simple_shader = &gObjectSimpleAlphaMaskProgram;
}
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
simple_shader->bind();
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
else
{
@@ -280,7 +315,7 @@ void LLDrawPoolAlphaMask::endRenderPass(S32 pass)
stop_glerror();
LLRenderPass::endRenderPass(pass);
stop_glerror();
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
simple_shader->unbind();
}
@@ -291,11 +326,20 @@ void LLDrawPoolAlphaMask::render(S32 pass)
LLGLDisable blend(GL_BLEND);
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK);
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
simple_shader->bind();
simple_shader->setMinimumAlpha(0.33f);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
@@ -317,7 +361,7 @@ LLDrawPoolFullbrightAlphaMask::LLDrawPoolFullbrightAlphaMask() :
void LLDrawPoolFullbrightAlphaMask::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass)
@@ -333,9 +377,18 @@ void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass)
simple_shader = &gObjectFullbrightAlphaMaskProgram;
}
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
simple_shader->bind();
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
else
{
@@ -353,7 +406,7 @@ void LLDrawPoolFullbrightAlphaMask::endRenderPass(S32 pass)
stop_glerror();
LLRenderPass::endRenderPass(pass);
stop_glerror();
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
simple_shader->unbind();
}
@@ -363,18 +416,30 @@ void LLDrawPoolFullbrightAlphaMask::render(S32 pass)
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK);
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
if (simple_shader)
{
simple_shader->bind();
simple_shader->setMinimumAlpha(0.33f);
- if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
- {
- simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
- } else {
- simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
- }
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ }
+ else
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ if (LLPipeline::sRenderDeferred)
+ {
+ simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ }
+ else
+ {
+ simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ }
+ }
}
pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
//LLGLSLShader::bindNoShader();
@@ -382,7 +447,7 @@ void LLDrawPoolFullbrightAlphaMask::render(S32 pass)
else
{
LLGLEnable test(GL_ALPHA_TEST);
- gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
+ gPipeline.enableLightsFullbright();
pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE);
gPipeline.enableLightsDynamic();
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
@@ -397,6 +462,15 @@ void LLDrawPoolSimple::beginDeferredPass(S32 pass)
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED);
gDeferredDiffuseProgram.bind();
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ gDeferredDiffuseProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ gDeferredDiffuseProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
void LLDrawPoolSimple::endDeferredPass(S32 pass)
@@ -435,6 +509,16 @@ void LLDrawPoolAlphaMask::renderDeferred(S32 pass)
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK_DEFERRED);
gDeferredDiffuseAlphaMaskProgram.bind();
gDeferredDiffuseAlphaMaskProgram.setMinimumAlpha(0.33f);
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ gDeferredDiffuseAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ gDeferredDiffuseAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
gDeferredDiffuseAlphaMaskProgram.unbind();
}
@@ -449,7 +533,7 @@ LLDrawPoolGrass::LLDrawPoolGrass() :
void LLDrawPoolGrass::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
@@ -467,10 +551,18 @@ void LLDrawPoolGrass::beginRenderPass(S32 pass)
simple_shader = &gObjectAlphaMaskNonIndexedProgram;
}
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
simple_shader->bind();
simple_shader->setMinimumAlpha(0.5f);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
else
{
@@ -488,7 +580,7 @@ void LLDrawPoolGrass::endRenderPass(S32 pass)
LL_RECORD_BLOCK_TIME(FTM_RENDER_GRASS);
LLRenderPass::endRenderPass(pass);
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
simple_shader->unbind();
}
@@ -527,6 +619,16 @@ void LLDrawPoolGrass::renderDeferred(S32 pass)
LL_RECORD_BLOCK_TIME(FTM_RENDER_GRASS_DEFERRED);
gDeferredNonIndexedDiffuseAlphaMaskProgram.bind();
gDeferredNonIndexedDiffuseAlphaMaskProgram.setMinimumAlpha(0.5f);
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
//render grass
LLRenderPass::renderTexture(LLRenderPass::PASS_GRASS, getVertexDataMask());
}
@@ -541,7 +643,7 @@ LLDrawPoolFullbright::LLDrawPoolFullbright() :
void LLDrawPoolFullbright::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass)
@@ -553,6 +655,15 @@ void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass)
else
{
gDeferredFullbrightProgram.bind();
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ gDeferredFullbrightProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ gDeferredFullbrightProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
}
@@ -600,7 +711,7 @@ void LLDrawPoolFullbright::endRenderPass(S32 pass)
stop_glerror();
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
fullbright_shader->unbind();
}
@@ -615,12 +726,21 @@ void LLDrawPoolFullbright::render(S32 pass)
stop_glerror();
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
fullbright_shader->bind();
fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f);
fullbright_shader->uniform1f(LLViewerShaderMgr::TEXTURE_GAMMA, 1.f);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE);
pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask, TRUE, TRUE);
@@ -630,7 +750,7 @@ void LLDrawPoolFullbright::render(S32 pass)
}
else
{
- gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
+ gPipeline.enableLightsFullbright();
U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR;
renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask);
pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask);
@@ -651,23 +771,32 @@ S32 LLDrawPoolFullbright::getNumPasses()
void LLDrawPoolFullbrightAlphaMask::beginPostDeferredPass(S32 pass)
{
- if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
- {
- gObjectFullbrightAlphaMaskProgram.bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ gObjectFullbrightAlphaMaskProgram.bind();
gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
- }
- else
- {
- if (LLPipeline::sUnderWaterRender)
+ gObjectFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else if (LLPipeline::sRenderDeferred)
+ {
+ if (LLPipeline::sUnderWaterRender)
{
gDeferredFullbrightAlphaMaskWaterProgram.bind();
gDeferredFullbrightAlphaMaskWaterProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ gDeferredFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
}
else
{
gDeferredFullbrightAlphaMaskProgram.bind();
gDeferredFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ gDeferredFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
}
+ }
+ else
+ {
+ gObjectFullbrightAlphaMaskProgram.bind();
+ gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ gObjectFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
}
}
diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp
index bdb16abc78..dbe8724088 100644
--- a/indra/newview/lldrawpoolsky.cpp
+++ b/indra/newview/lldrawpoolsky.cpp
@@ -55,7 +55,7 @@ LLDrawPool *LLDrawPoolSky::instancePool()
void LLDrawPoolSky::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable);
}
@@ -75,7 +75,7 @@ void LLDrawPoolSky::render(S32 pass)
}
// don't render sky under water (background just gets cleared to fog color)
- if(mVertexShaderLevel > 0 && LLPipeline::sUnderWaterRender)
+ if(mShaderLevel > 0 && LLPipeline::sUnderWaterRender)
{
return;
}
@@ -98,18 +98,10 @@ void LLDrawPoolSky::render(S32 pass)
}
- LLGLSPipelineSkyBox gls_skybox;
+ LLGLSPipelineDepthTestSkyBox gls_skybox(true, false);
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-
- LLGLSquashToFarClip far_clip(glh_get_current_projection());
-
- LLGLEnable fog_enable( (mVertexShaderLevel < 1 && LLViewerCamera::getInstance()->cameraUnderWater()) ? GL_FOG : 0);
-
- gPipeline.disableLights();
+ LLGLEnable fog_enable( (mShaderLevel < 1 && LLViewerCamera::getInstance()->cameraUnderWater()) ? GL_FOG : 0);
- LLGLDisable clip(GL_CLIP_PLANE0);
-
gGL.pushMatrix();
LLVector3 origin = LLViewerCamera::getInstance()->getOrigin();
gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
@@ -119,35 +111,52 @@ void LLDrawPoolSky::render(S32 pass)
LLVertexBuffer::unbind();
gGL.diffuseColor4f(1,1,1,1);
- for (S32 i = 0; i < llmin(6, face_count); ++i)
+ for (S32 i = 0; i < face_count; ++i)
{
- renderSkyCubeFace(i);
+ renderSkyFace(i);
}
gGL.popMatrix();
}
-void LLDrawPoolSky::renderSkyCubeFace(U8 side)
+void LLDrawPoolSky::renderSkyFace(U8 index)
{
- LLFace &face = *mDrawFace[LLVOSky::FACE_SIDE0 + side];
- if (!face.getGeomCount())
+ LLFace* face = mDrawFace[index];
+
+ if (!face || !face->getGeomCount())
{
return;
}
- llassert(mSkyTex);
- mSkyTex[side].bindTexture(TRUE);
-
- face.renderIndexed();
+ F32 interp_val = gSky.mVOSkyp ? gSky.mVOSkyp->getInterpVal() : 0.0f;
- if (LLSkyTex::doInterpolate())
- {
-
- LLGLEnable blend(GL_BLEND);
- mSkyTex[side].bindTexture(FALSE);
- gGL.diffuseColor4f(1, 1, 1, LLSkyTex::getInterpVal()); // lighting is disabled
- face.renderIndexed();
- }
+ 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...
+ {
+ LLGLEnable blend(GL_BLEND);
+
+ LLViewerTexture* tex = face->getTexture(LLRender::DIFFUSE_MAP);
+ if (tex)
+ {
+ gGL.getTexUnit(0)->bind(tex, true);
+ face->renderIndexed();
+ }
+ }
}
void LLDrawPoolSky::endRenderPass( S32 pass )
diff --git a/indra/newview/lldrawpoolsky.h b/indra/newview/lldrawpoolsky.h
index 098bd2134a..916d8c1cbe 100644
--- a/indra/newview/lldrawpoolsky.h
+++ b/indra/newview/lldrawpoolsky.h
@@ -61,7 +61,7 @@ public:
/*virtual*/ void endRenderPass(S32 pass);
void setSkyTex(LLSkyTex* const st) { mSkyTex = st; }
- void renderSkyCubeFace(U8 side);
+ void renderSkyFace(U8 index);
void renderHeavenlyBody(U8 hb, LLFace* face);
void renderSunHalo(LLFace* face);
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 6521681033..323e92371f 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -48,6 +48,8 @@
#include "pipeline.h"
#include "llviewershadermgr.h"
#include "llrender.h"
+#include "llenvironment.h"
+#include "llsettingsvo.h"
const F32 DETAIL_SCALE = 1.f/16.f;
int DebugDetailMap = 0;
@@ -118,7 +120,7 @@ U32 LLDrawPoolTerrain::getVertexDataMask()
void LLDrawPoolTerrain::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
// Use faster LLCachedControls for frequently visited locations
//sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");
static LLCachedControl renderTerrainDetail(gSavedSettings, "RenderTerrainDetail");
@@ -135,7 +137,7 @@ void LLDrawPoolTerrain::beginRenderPass( S32 pass )
&gTerrainWaterProgram :
&gTerrainProgram;
- if (mVertexShaderLevel > 1 && sShader->mShaderLevel > 0)
+ if (mShaderLevel > 1 && sShader->mShaderLevel > 0)
{
sShader->bind();
}
@@ -146,7 +148,7 @@ void LLDrawPoolTerrain::endRenderPass( S32 pass )
LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN);
//LLFacePool::endRenderPass(pass);
- if (mVertexShaderLevel > 1 && sShader->mShaderLevel > 0) {
+ if (mShaderLevel > 1 && sShader->mShaderLevel > 0) {
sShader->unbind();
}
}
@@ -157,6 +159,18 @@ S32 LLDrawPoolTerrain::getDetailMode()
return sDetailMode;
}
+void LLDrawPoolTerrain::boostTerrainDetailTextures()
+{
+ // Hack! Get the region that this draw pool is rendering from!
+ LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
+ LLVLComposition *compp = regionp->getComposition();
+ for (S32 i = 0; i < 4; i++)
+ {
+ compp->mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
+ compp->mDetailTextures[i]->addTextureStats(1024.f*1024.f); // assume large pixel area
+ }
+}
+
void LLDrawPoolTerrain::render(S32 pass)
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN);
@@ -166,14 +180,7 @@ void LLDrawPoolTerrain::render(S32 pass)
return;
}
- // Hack! Get the region that this draw pool is rendering from!
- LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
- LLVLComposition *compp = regionp->getComposition();
- for (S32 i = 0; i < 4; i++)
- {
- compp->mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
- compp->mDetailTextures[i]->addTextureStats(1024.f*1024.f); // assume large pixel area
- }
+ boostTerrainDetailTextures();
LLOverrideFaceColor override(this, 1.f, 1.f, 1.f, 1.f);
@@ -192,7 +199,7 @@ void LLDrawPoolTerrain::render(S32 pass)
LLGLSPipeline gls;
- if (mVertexShaderLevel > 1 && sShader->mShaderLevel > 0)
+ if (mShaderLevel > 1 && sShader->mShaderLevel > 0)
{
gPipeline.enableLightsDynamic();
@@ -232,7 +239,7 @@ void LLDrawPoolTerrain::beginDeferredPass(S32 pass)
LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN);
LLFacePool::beginRenderPass(pass);
- sShader = &gDeferredTerrainProgram;
+ sShader = LLPipeline::sUnderWaterRender ? &gDeferredTerrainWaterProgram : &gDeferredTerrainProgram;
sShader->bind();
}
@@ -252,10 +259,16 @@ void LLDrawPoolTerrain::renderDeferred(S32 pass)
return;
}
+ boostTerrainDetailTextures();
+
renderFullShader();
// Special-case for land ownership feedback
- if (gSavedSettings.getBOOL("ShowParcelOwners"))
+ // Use faster LLCachedControls for frequently visited locations
+ //if (gSavedSettings.getBOOL("ShowParcelOwners"))
+ static LLCachedControl showParcelOwners(gSavedSettings, "ShowParcelOwners");
+ if (showParcelOwners)
+ //
{
hilightParcelOwners(true);
}
@@ -268,6 +281,9 @@ void LLDrawPoolTerrain::beginShadowPass(S32 pass)
LLFacePool::beginRenderPass(pass);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gDeferredShadowProgram.bind();
+
+ LLEnvironment& environment = LLEnvironment::instance();
+ gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
}
void LLDrawPoolTerrain::endShadowPass(S32 pass)
@@ -349,7 +365,8 @@ void LLDrawPoolTerrain::renderFullShader()
//
S32 detail0 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0);
gGL.getTexUnit(detail0)->bind(detail_texture0p);
- gGL.getTexUnit(0)->activate();
+ gGL.getTexUnit(detail0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail0)->activate();
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
llassert(shader);
@@ -357,54 +374,40 @@ void LLDrawPoolTerrain::renderFullShader()
shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV);
shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV);
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
+
+ ((LLSettingsVOWater*)pwater.get())->updateShader(shader);
//
// detail texture 1
//
S32 detail1 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL1);
gGL.getTexUnit(detail1)->bind(detail_texture1p);
-
- /// ALPHA TEXTURE COORDS 0:
- gGL.getTexUnit(1)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.getTexUnit(detail1)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail1)->activate();
// detail texture 2
//
S32 detail2 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2);
gGL.getTexUnit(detail2)->bind(detail_texture2p);
-
- gGL.getTexUnit(2)->activate();
+ gGL.getTexUnit(detail2)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail2)->activate();
- /// ALPHA TEXTURE COORDS 1:
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.translatef(-2.f, 0.f, 0.f);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- //
// detail texture 3
//
S32 detail3 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3);
gGL.getTexUnit(detail3)->bind(detail_texture3p);
-
- /// ALPHA TEXTURE COORDS 2:
- gGL.getTexUnit(3)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.translatef(-1.f, 0.f, 0.f);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.getTexUnit(detail3)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail3)->activate();
//
// Alpha Ramp
//
S32 alpha_ramp = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP);
gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep);
-
+ gGL.getTexUnit(alpha_ramp)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+
// GL_BLEND disabled by default
drawLoop();
@@ -416,47 +419,32 @@ void LLDrawPoolTerrain::renderFullShader()
sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3);
gGL.getTexUnit(alpha_ramp)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(4)->disable();
- gGL.getTexUnit(4)->activate();
+ gGL.getTexUnit(alpha_ramp)->disable();
+ gGL.getTexUnit(alpha_ramp)->activate();
gGL.getTexUnit(detail3)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(3)->disable();
- gGL.getTexUnit(3)->activate();
-
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.getTexUnit(detail3)->disable();
+ gGL.getTexUnit(detail3)->activate();
gGL.getTexUnit(detail2)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(2)->disable();
- gGL.getTexUnit(2)->activate();
-
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.getTexUnit(detail2)->disable();
+ gGL.getTexUnit(detail2)->activate();
gGL.getTexUnit(detail1)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->disable();
- gGL.getTexUnit(1)->activate();
-
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.getTexUnit(detail1)->disable();
+ gGL.getTexUnit(detail1)->activate();
//----------------------------------------------------------------------------
// Restore Texture Unit 0 defaults
gGL.getTexUnit(detail0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(0)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.getTexUnit(detail0)->enable(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail0)->activate();
}
void LLDrawPoolTerrain::hilightParcelOwners(bool deferred)
{
- if (mVertexShaderLevel > 1)
+ if (mShaderLevel > 1)
{ //use fullbright shader for highlighting
LLGLSLShader* old_shader = sShader;
sShader->unbind();
diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h
index 484820491a..04e27d9370 100644
--- a/indra/newview/lldrawpoolterrain.h
+++ b/indra/newview/lldrawpoolterrain.h
@@ -78,6 +78,8 @@ public:
static F32 sDetailScale; // meters per texture
protected:
+ void boostTerrainDetailTextures();
+
void renderSimple();
void renderOwnership();
diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp
index 06d8547f12..b491ca7aad 100644
--- a/indra/newview/lldrawpooltree.cpp
+++ b/indra/newview/lldrawpooltree.cpp
@@ -38,6 +38,7 @@
#include "llrender.h"
#include "llviewercontrol.h"
#include "llviewerregion.h"
+#include "llenvironment.h"
S32 LLDrawPoolTree::sDiffTex = 0;
static LLGLSLShader* shader = NULL;
@@ -57,7 +58,7 @@ LLDrawPool *LLDrawPoolTree::instancePool()
void LLDrawPoolTree::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
void LLDrawPoolTree::beginRenderPass(S32 pass)
@@ -96,7 +97,6 @@ void LLDrawPoolTree::render(S32 pass)
}
LLGLState test(GL_ALPHA_TEST, LLGLSLShader::sNoFixedFunction ? 0 : 1);
- LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f);
// [SL:KB] - Patch: Render-TextureToggle (Catznip-4.0)
if( (LLPipeline::sRenderTextures) )
@@ -144,7 +144,7 @@ void LLDrawPoolTree::endRenderPass(S32 pass)
shader->unbind();
}
- if (mVertexShaderLevel <= 0)
+ if (mShaderLevel <= 0)
{
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}
@@ -189,7 +189,10 @@ void LLDrawPoolTree::beginShadowPass(S32 pass)
glPolygonOffset(RenderDeferredTreeShadowOffset, RenderDeferredTreeShadowBias);
//
+ LLEnvironment& environment = LLEnvironment::instance();
+
gDeferredTreeShadowProgram.bind();
+ gDeferredTreeShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
gDeferredTreeShadowProgram.setMinimumAlpha(0.5f);
}
diff --git a/indra/newview/lldrawpooltree.h b/indra/newview/lldrawpooltree.h
index e7e25453cf..9c1e60f5eb 100644
--- a/indra/newview/lldrawpooltree.h
+++ b/indra/newview/lldrawpooltree.h
@@ -37,7 +37,8 @@ public:
{
VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_NORMAL |
- LLVertexBuffer::MAP_TEXCOORD0
+ LLVertexBuffer::MAP_COLOR |
+ LLVertexBuffer::MAP_TEXCOORD0
};
virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 4c85d02b79..ae93910ab1 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -46,10 +46,9 @@
#include "llworld.h"
#include "pipeline.h"
#include "llviewershadermgr.h"
-#include "llwaterparammanager.h"
-
-const LLUUID TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004");
-const LLUUID OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055");
+#include "llenvironment.h"
+#include "llsettingssky.h"
+#include "llsettingswater.h"
static float sTime;
@@ -58,31 +57,10 @@ BOOL deferred_render = FALSE;
BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE;
BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE;
BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE;
-LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f);
F32 LLDrawPoolWater::sWaterFogEnd = 0.f;
-LLVector3 LLDrawPoolWater::sLightDir;
-
-LLDrawPoolWater::LLDrawPoolWater() :
- LLFacePool(POOL_WATER)
+LLDrawPoolWater::LLDrawPoolWater() : LLFacePool(POOL_WATER)
{
- mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
- gGL.getTexUnit(0)->bind(mHBTex[0]) ;
- mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
-
- mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
- gGL.getTexUnit(0)->bind(mHBTex[1]);
- mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
-
-
- mWaterImagep = LLViewerTextureManager::getFetchedTexture(TRANSPARENT_WATER_TEXTURE);
- llassert(mWaterImagep);
- mWaterImagep->setNoDelete();
- mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(OPAQUE_WATER_TEXTURE);
- llassert(mOpaqueWaterImagep);
- mWaterNormp = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL);
- mWaterNormp->setNoDelete();
-
// Render speedup for water parameters
gSavedSettings.getControl("RenderTransparentWater")->getCommitSignal()->connect(boost::bind(&LLDrawPoolWater::onRenderTransparentWaterChanged, this));
onRenderTransparentWaterChanged();
@@ -90,18 +68,47 @@ LLDrawPoolWater::LLDrawPoolWater() :
gSavedSettings.getControl("RenderWaterMipNormal")->getCommitSignal()->connect(boost::bind(&LLDrawPoolWater::onRenderWaterMipNormalChanged, this));
onRenderWaterMipNormalChanged();
//
-
- restoreGL();
}
LLDrawPoolWater::~LLDrawPoolWater()
{
}
+void LLDrawPoolWater::setTransparentTextures(const LLUUID& transparentTextureId, const LLUUID& nextTransparentTextureId)
+{
+ LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
+ mWaterImagep[0] = LLViewerTextureManager::getFetchedTexture(!transparentTextureId.isNull() ? transparentTextureId : pwater->GetDefaultTransparentTextureAssetId());
+ mWaterImagep[1] = LLViewerTextureManager::getFetchedTexture(!nextTransparentTextureId.isNull() ? nextTransparentTextureId : (!transparentTextureId.isNull() ? transparentTextureId : pwater->GetDefaultTransparentTextureAssetId()));
+ mWaterImagep[0]->addTextureStats(1024.f*1024.f);
+ mWaterImagep[1]->addTextureStats(1024.f*1024.f);
+}
+
+void LLDrawPoolWater::setOpaqueTexture(const LLUUID& opaqueTextureId)
+{
+ LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
+ mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(opaqueTextureId);
+ mOpaqueWaterImagep->addTextureStats(1024.f*1024.f);
+}
+
+void LLDrawPoolWater::setNormalMaps(const LLUUID& normalMapId, const LLUUID& nextNormalMapId)
+{
+ LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
+ mWaterNormp[0] = LLViewerTextureManager::getFetchedTexture(!normalMapId.isNull() ? normalMapId : pwater->GetDefaultWaterNormalAssetId());
+ mWaterNormp[1] = LLViewerTextureManager::getFetchedTexture(!nextNormalMapId.isNull() ? nextNormalMapId : (!normalMapId.isNull() ? normalMapId : pwater->GetDefaultWaterNormalAssetId()));
+ mWaterNormp[0]->addTextureStats(1024.f*1024.f);
+ mWaterNormp[1]->addTextureStats(1024.f*1024.f);
+}
+
//static
void LLDrawPoolWater::restoreGL()
{
-
+ /*LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
+ if (pwater)
+ {
+ setTransparentTextures(pwater->getTransparentTextureID(), pwater->getNextTransparentTextureID());
+ setOpaqueTexture(pwater->GetDefaultOpaqueTextureAssetId());
+ setNormalMaps(pwater->getNormalMapID(), pwater->getNextNormalMapID());
+ }*/
}
LLDrawPool *LLDrawPoolWater::instancePool()
@@ -113,14 +120,7 @@ LLDrawPool *LLDrawPoolWater::instancePool()
void LLDrawPoolWater::prerender()
{
- mVertexShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ?
- LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
-
- // got rid of modulation by light color since it got a little too
- // green at sunset and sl-57047 (underwater turns black at 8:00)
- sWaterFogColor = LLWaterParamManager::instance().getFogColor();
- sWaterFogColor.mV[3] = 0;
-
+ mShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
}
S32 LLDrawPoolWater::getNumPasses()
@@ -189,7 +189,7 @@ void LLDrawPoolWater::render(S32 pass)
LLGLEnable blend(GL_BLEND);
- if ((mVertexShaderLevel > 0) && !sSkipScreenCopy)
+ if ((mShaderLevel > 0) && !sSkipScreenCopy)
{
shade();
return;
@@ -214,10 +214,13 @@ void LLDrawPoolWater::render(S32 pass)
LLGLDisable cullFace(GL_CULL_FACE);
// Set up second pass first
- mWaterImagep->addTextureStats(1024.f*1024.f);
gGL.getTexUnit(1)->activate();
gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->bind(mWaterImagep) ;
+ gGL.getTexUnit(1)->bind(mWaterImagep[0]) ;
+
+ gGL.getTexUnit(2)->activate();
+ gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(2)->bind(mWaterImagep[1]) ;
LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
F32 up_dot = camera_up * LLVector3::z_axis;
@@ -274,6 +277,14 @@ void LLDrawPoolWater::render(S32 pass)
gGL.getTexUnit(1)->activate();
gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(1)->disable();
+
+ glDisable(GL_TEXTURE_GEN_S); //texture unit 1
+ glDisable(GL_TEXTURE_GEN_T); //texture unit 1
+
+ gGL.getTexUnit(2)->activate();
+ gGL.getTexUnit(2)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(2)->disable();
+
glDisable(GL_TEXTURE_GEN_S); //texture unit 1
glDisable(GL_TEXTURE_GEN_T); //texture unit 1
@@ -373,8 +384,6 @@ void LLDrawPoolWater::renderOpaqueLegacyWater()
gPipeline.disableLights();
- mOpaqueWaterImagep->addTextureStats(1024.f*1024.f);
-
// Activate the texture binding and bind one
// texture since all images will have the same texture
gGL.getTexUnit(0)->activate();
@@ -472,12 +481,220 @@ void LLDrawPoolWater::renderReflection(LLFace* face)
LLGLSNoFog noFog;
- gGL.getTexUnit(0)->bind(mHBTex[dr]);
+ gGL.getTexUnit(0)->bind((dr == 0) ? voskyp->getSunTex() : voskyp->getMoonTex());
LLOverrideFaceColor override(this, LLColor4(face->getFaceColor().mV));
face->renderIndexed();
}
+void LLDrawPoolWater::shade2(bool edge, LLGLSLShader* shader, const LLColor3& light_diffuse, const LLVector3& light_dir, F32 light_exp)
+{
+ F32 water_height = LLEnvironment::instance().getWaterHeight();
+ F32 camera_height = LLViewerCamera::getInstance()->getOrigin().mV[2];
+ F32 eyedepth = camera_height - water_height;
+ bool underwater = eyedepth <= 0.0f;
+
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsWater::ptr_t pwater = environment.getCurrentWater();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+
+ shader->bind();
+
+// bind textures for water rendering
+ if (deferred_render)
+ {
+ if (shader->getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0)
+ {
+ glh::matrix4f norm_mat = get_current_modelview().inverse().transpose();
+ shader->uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m);
+ }
+ }
+
+ LLColor4 specular(psky->getIsSunUp() ? psky->getSunlightColor() : psky->getMoonlightColor());
+ shader->uniform4fv(LLShaderMgr::SPECULAR_COLOR, 1, specular.mV);
+
+ sTime = (F32)LLFrameTimer::getElapsedSeconds() * 0.5f;
+
+ S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX);
+
+ if (reftex > -1)
+ {
+ gGL.getTexUnit(reftex)->activate();
+ gGL.getTexUnit(reftex)->bind(&gPipeline.mWaterRef);
+ gGL.getTexUnit(0)->activate();
+ }
+
+ //bind normal map
+ S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
+ S32 bumpTex2 = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2);
+
+ LLViewerTexture* tex_a = mWaterNormp[0];
+ LLViewerTexture* tex_b = mWaterNormp[1];
+
+ F32 blend_factor = LLEnvironment::instance().getCurrentWater()->getBlendFactor();
+
+ gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
+
+ if (tex_a && (!tex_b || (tex_a == tex_b)))
+ {
+ gGL.getTexUnit(bumpTex)->bind(tex_a);
+ blend_factor = 0; // only one tex provided, no blending
+ }
+ else if (tex_b && !tex_a)
+ {
+ gGL.getTexUnit(bumpTex)->bind(tex_b);
+ blend_factor = 0; // only one tex provided, no blending
+ }
+ else if (tex_b != tex_a)
+ {
+ gGL.getTexUnit(bumpTex)->bind(tex_a);
+ gGL.getTexUnit(bumpTex2)->bind(tex_b);
+ }
+
+ // bind reflection texture from RenderTarget
+ S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
+ F32 screenRes[] =
+ {
+ 1.f/gGLViewport[2],
+ 1.f/gGLViewport[3]
+ };
+
+ S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
+ stop_glerror();
+
+// set uniforms for water rendering
+ shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes);
+ shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+
+ LLColor4 fog_color(pwater->getWaterFogColor(), 0.0f);
+ F32 fog_density = pwater->getModifiedWaterFogDensity(underwater);
+
+ if (screentex > -1)
+ {
+ shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, fog_density);
+ gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
+ }
+
+ if (mShaderLevel == 1)
+ {
+ //F32 fog_density_slider_value = param_mgr->mDensitySliderValue;
+ //sWaterFogColor.mV[3] = fog_density_slider_value;
+ fog_color.mV[VW] = log(fog_density) / log(2);
+ }
+
+ shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV);
+
+ //shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix);
+ shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, eyedepth);
+ shader->uniform1f(LLShaderMgr::WATER_TIME, sTime);
+ shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
+ shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
+ shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
+ if (LLEnvironment::instance().isCloudScrollPaused())
+ {
+ static const std::array zerowave{ {0.0f, 0.0f} };
+
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, zerowave.data());
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, zerowave.data());
+ }
+ else
+ {
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV);
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV);
+ }
+ shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
+
+ shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV);
+ shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale());
+ shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset());
+ shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, pwater->getBlurMultiplier());
+
+ F32 sunAngle = llmax(0.f, light_dir.mV[1]);
+ F32 scaledAngle = 1.f - sunAngle;
+
+ shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
+ shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle);
+ shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle);
+ shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f*sunAngle);
+ shader->uniform1i(LLShaderMgr::WATER_EDGE_FACTOR, edge ? 1 : 0);
+
+ LLVector4 rotated_light_direction = LLEnvironment::instance().getRotatedLightNorm();
+ shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
+ shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
+
+ if (LLViewerCamera::getInstance()->cameraUnderWater())
+ {
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow());
+ }
+ else
+ {
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove());
+ }
+
+ {
+ LLGLDisable cullface(GL_CULL_FACE);
+
+ if (edge)
+ {
+ for (std::vector::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++)
+ {
+ LLFace *face = *iter;
+ if (face)
+ {
+ LLVOWater* water = (LLVOWater*) face->getViewerObject();
+ gGL.getTexUnit(diffTex)->bind(face->getTexture());
+
+ if (water)
+ {
+ bool edge_patch = water->getIsEdgePatch();
+ if (edge_patch)
+ {
+ //sNeedsReflectionUpdate = TRUE;
+ face->renderIndexed();
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ for (std::vector::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++)
+ {
+ LLFace *face = *iter;
+ if (face)
+ {
+ LLVOWater* water = (LLVOWater*) face->getViewerObject();
+ gGL.getTexUnit(diffTex)->bind(face->getTexture());
+
+ if (water)
+ {
+ bool edge_patch = water->getIsEdgePatch();
+ if (!edge_patch)
+ {
+ sNeedsReflectionUpdate = TRUE;
+ sNeedsDistortionUpdate = TRUE;
+ face->renderIndexed();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
+
+ shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
+ shader->disableTexture(LLShaderMgr::WATER_SCREENTEX);
+ shader->disableTexture(LLShaderMgr::BUMP_MAP);
+ shader->disableTexture(LLShaderMgr::DIFFUSE_MAP);
+ shader->disableTexture(LLShaderMgr::WATER_REFTEX);
+ shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH);
+
+ shader->unbind();
+}
+
void LLDrawPoolWater::shade()
{
if (!deferred_render)
@@ -497,30 +714,32 @@ void LLDrawPoolWater::shade()
LLColor3 light_diffuse(0,0,0);
F32 light_exp = 0.0f;
LLVector3 light_dir;
- LLColor3 light_color;
- if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS)
- {
- light_dir = gSky.getSunDirection();
- light_dir.normVec();
- light_color = gSky.getSunDiffuseColor();
- if(gSky.mVOSkyp) {
- light_diffuse = gSky.mVOSkyp->getSun().getColorCached();
- light_diffuse.normVec();
- }
- light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0);
- light_diffuse *= light_exp + 0.25f;
- }
- else
- {
- light_dir = gSky.getMoonDirection();
- light_dir.normVec();
- light_color = gSky.getMoonDiffuseColor();
- light_diffuse = gSky.mVOSkyp->getMoon().getColorCached();
- light_diffuse.normVec();
- light_diffuse *= 0.5f;
- light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0);
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsWater::ptr_t pwater = environment.getCurrentWater();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+
+ light_dir = environment.getLightDirection();
+ light_dir.normalize();
+
+ bool sun_up = environment.getIsSunUp();
+ bool moon_up = environment.getIsMoonUp();
+
+ if (sun_up)
+ {
+ light_diffuse += voskyp->getSun().getColorCached();
}
+ // moonlight is several orders of magnitude less bright than sunlight,
+ // so only use this color when the moon alone is showing
+ else if (moon_up)
+ {
+ light_diffuse += psky->getMoonDiffuse();
+ }
+
+ light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0.f);
+
+ light_diffuse.normalize();
+ light_diffuse *= (light_exp + 0.25f);
light_exp *= light_exp;
light_exp *= light_exp;
@@ -529,202 +748,67 @@ void LLDrawPoolWater::shade()
light_exp *= 256.f;
light_exp = light_exp > 32.f ? light_exp : 32.f;
- LLGLSLShader* shader;
+ light_diffuse *= 6.f;
- F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight();
+ LLGLSLShader* shader = nullptr;
+ LLGLSLShader* edge_shader = nullptr;
+
+ F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - LLEnvironment::instance().getWaterHeight();
if (eyedepth < 0.f && LLPipeline::sWaterReflections)
{
- if (deferred_render)
- {
- shader = &gDeferredUnderWaterProgram;
- }
+ if (deferred_render)
+ {
+ shader = &gDeferredUnderWaterProgram;
+ }
else
- {
- shader = &gUnderWaterProgram;
- }
+ {
+ shader = &gUnderWaterProgram;
+ }
}
else if (deferred_render)
{
shader = &gDeferredWaterProgram;
+ edge_shader = nullptr;
}
else
{
shader = &gWaterProgram;
+ edge_shader = &gWaterEdgeProgram;
}
- if (deferred_render)
- {
- gPipeline.bindDeferredShader(*shader);
- }
- else
- {
- shader->bind();
+ if (mWaterNormp[0])
+ {
+ // Render speedup for water parameters
+ //if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
+ if (mRenderWaterMipNormal)
+ //
+ {
+ mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+ }
+ else
+ {
+ mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_POINT);
+ }
}
- sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f;
-
- S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX);
-
- if (reftex > -1)
- {
- gGL.getTexUnit(reftex)->activate();
- gGL.getTexUnit(reftex)->bind(&gPipeline.mWaterRef);
- gGL.getTexUnit(0)->activate();
- }
-
- //bind normal map
- S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
-
- LLWaterParamManager * param_mgr = &LLWaterParamManager::instance();
-
- // change mWaterNormp if needed
- if (mWaterNormp->getID() != param_mgr->getNormalMapID())
- {
- mWaterNormp = LLViewerTextureManager::getFetchedTexture(param_mgr->getNormalMapID());
+ if (mWaterNormp[1])
+ {
+ // Render speedup for water parameters
+ //if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
+ if (mRenderWaterMipNormal)
+ //
+ {
+ mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+ }
+ else
+ {
+ mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_POINT);
+ }
}
- mWaterNormp->addTextureStats(1024.f*1024.f);
- gGL.getTexUnit(bumpTex)->bind(mWaterNormp) ;
- // Render speedup for water parameters
- // if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
- if (mRenderWaterMipNormal)
- //
- {
- mWaterNormp->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
- }
- else
- {
- mWaterNormp->setFilteringOption(LLTexUnit::TFO_POINT);
- }
-
- S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
-
- if (screentex > -1)
- {
- shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
- shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY,
- param_mgr->getFogDensity());
- gPipeline.mWaterDis.bindTexture(0, screentex);
- }
-
- stop_glerror();
-
- gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
-
- if (mVertexShaderLevel == 1)
- {
- sWaterFogColor.mV[3] = param_mgr->mDensitySliderValue;
- shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
- }
-
- F32 screenRes[] =
- {
- 1.f/gGLViewport[2],
- 1.f/gGLViewport[3]
- };
- shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes);
- stop_glerror();
-
- S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
- stop_glerror();
-
- light_dir.normVec();
- sLightDir = light_dir;
-
- light_diffuse *= 6.f;
-
- //shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix);
- shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, eyedepth);
- shader->uniform1f(LLShaderMgr::WATER_TIME, sTime);
- shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
- shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
- shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV);
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV);
- shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
-
- shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, param_mgr->getNormalScale().mV);
- shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, param_mgr->getFresnelScale());
- shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, param_mgr->getFresnelOffset());
- shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, param_mgr->getBlurMultiplier());
-
- F32 sunAngle = llmax(0.f, light_dir.mV[2]);
- F32 scaledAngle = 1.f - sunAngle;
-
- shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle);
- shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle);
- shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f*sunAngle);
-
- LLColor4 water_color;
- LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
- F32 up_dot = camera_up * LLVector3::z_axis;
- if (LLViewerCamera::getInstance()->cameraUnderWater())
- {
- water_color.setVec(1.f, 1.f, 1.f, 0.4f);
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow());
- }
- else
- {
- water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove());
- }
-
- if (water_color.mV[3] > 0.9f)
- {
- water_color.mV[3] = 0.9f;
- }
-
- {
- LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
- LLGLDisable cullface(GL_CULL_FACE);
- for (std::vector::iterator iter = mDrawFace.begin();
- iter != mDrawFace.end(); iter++)
- {
- LLFace *face = *iter;
-
- if (voskyp->isReflFace(face))
- {
- continue;
- }
-
- LLVOWater* water = (LLVOWater*) face->getViewerObject();
- gGL.getTexUnit(diffTex)->bind(face->getTexture());
-
- sNeedsReflectionUpdate = TRUE;
-
- if (water->getUseTexture() || !water->getIsEdgePatch())
- {
- sNeedsDistortionUpdate = TRUE;
- face->renderIndexed();
- }
- else if (gGLManager.mHasDepthClamp || deferred_render)
- {
- face->renderIndexed();
- }
- else
- {
- LLGLSquashToFarClip far_clip(glh_get_current_projection());
- face->renderIndexed();
- }
- }
- }
-
- shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
- shader->disableTexture(LLShaderMgr::WATER_SCREENTEX);
- shader->disableTexture(LLShaderMgr::BUMP_MAP);
- shader->disableTexture(LLShaderMgr::DIFFUSE_MAP);
- shader->disableTexture(LLShaderMgr::WATER_REFTEX);
- shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH);
-
- if (deferred_render)
- {
- gPipeline.unbindDeferredShader(*shader);
- }
- else
- {
- shader->unbind();
- }
+ shade2(false, shader, light_diffuse, light_dir, light_exp);
+ shade2(true, edge_shader ? edge_shader : shader, light_diffuse, light_dir, light_exp);
gGL.getTexUnit(0)->activate();
gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h
index 5117649a99..bdd0a372e0 100644
--- a/indra/newview/lldrawpoolwater.h
+++ b/indra/newview/lldrawpoolwater.h
@@ -33,22 +33,20 @@
class LLFace;
class LLHeavenBody;
class LLWaterSurface;
+class LLGLSLShader;
class LLDrawPoolWater: public LLFacePool
{
protected:
- LLPointer mHBTex[2];
- LLPointer mWaterImagep;
- LLPointer mOpaqueWaterImagep;
- LLPointer mWaterNormp;
+ LLPointer mWaterImagep[2];
+ LLPointer mWaterNormp[2];
+
+ LLPointer mOpaqueWaterImagep;
public:
static BOOL sSkipScreenCopy;
static BOOL sNeedsReflectionUpdate;
static BOOL sNeedsDistortionUpdate;
- static LLVector3 sLightDir;
-
- static LLColor4 sWaterFogColor;
static F32 sWaterFogEnd;
enum
@@ -82,6 +80,11 @@ public:
void renderReflection(LLFace* face);
void shade();
+ void shade2(bool edge, LLGLSLShader* shader, const LLColor3& light_diffuse, const LLVector3& light_dir, F32 light_exp);
+
+ void setTransparentTextures(const LLUUID& transparentTextureId, const LLUUID& nextTransparentTextureId);
+ void setOpaqueTexture(const LLUUID& opaqueTextureId);
+ void setNormalMaps(const LLUUID& normalMapId, const LLUUID& nextNormalMapId);
protected:
void renderOpaqueLegacyWater();
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index a57f03fc69..961d72c62e 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -29,71 +29,39 @@
#include "lldrawpoolwlsky.h"
#include "llerror.h"
-#include "llgl.h"
-#include "pipeline.h"
-#include "llviewercamera.h"
+#include "llface.h"
#include "llimage.h"
-#include "llwlparammanager.h"
-#include "llviewershadermgr.h"
+#include "llrender.h"
+#include "llatmosphere.h"
+#include "llenvironment.h"
#include "llglslshader.h"
+#include "llgl.h"
+
+#include "llviewerregion.h"
+#include "llviewershadermgr.h"
+#include "llviewercamera.h"
+#include "pipeline.h"
#include "llsky.h"
#include "llvowlsky.h"
-#include "llviewerregion.h"
-#include "llface.h"
-#include "llrender.h"
-#include "llviewercontrol.h" // Cloud noise selection
+#include "llsettingsvo.h"
-LLPointer LLDrawPoolWLSky::sCloudNoiseTexture = NULL;
-
-LLPointer LLDrawPoolWLSky::sCloudNoiseRawImage = NULL;
+static LLStaticHashedString sCamPosLocal("camPosLocal");
+static LLStaticHashedString sCustomAlpha("custom_alpha");
static LLGLSLShader* cloud_shader = NULL;
-static LLGLSLShader* sky_shader = NULL;
+static LLGLSLShader* sky_shader = NULL;
+static LLGLSLShader* sun_shader = NULL;
+static LLGLSLShader* moon_shader = NULL;
+static float sStarTime;
LLDrawPoolWLSky::LLDrawPoolWLSky(void) :
LLDrawPool(POOL_WL_SKY)
{
-// Cloud noise selection
- //const std::string cloudNoiseFilename(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", "clouds2.tga"));
- static LLCachedControl cloud_texture(gSavedSettings, "FSCloudTexture", "Default.tga");
- const std::string cloudNoiseFilename(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight" + gDirUtilp->getDirDelimiter() + "clouds", cloud_texture));
-//
- LL_INFOS() << "loading WindLight cloud noise from " << cloudNoiseFilename << LL_ENDL;
-
- LLPointer cloudNoiseFile(LLImageFormatted::createFromExtension(cloudNoiseFilename));
-
- if(cloudNoiseFile.isNull()) {
- LL_ERRS() << "Error: Failed to load cloud noise image " << cloudNoiseFilename << LL_ENDL;
- }
-
- if(cloudNoiseFile->load(cloudNoiseFilename))
- {
- sCloudNoiseRawImage = new LLImageRaw();
-
- if(cloudNoiseFile->decode(sCloudNoiseRawImage, 0.0f))
- {
- //debug use
- LL_DEBUGS() << "cloud noise raw image width: " << sCloudNoiseRawImage->getWidth() << " : height: " << sCloudNoiseRawImage->getHeight() << " : components: " <<
- (S32)sCloudNoiseRawImage->getComponents() << " : data size: " << sCloudNoiseRawImage->getDataSize() << LL_ENDL ;
- llassert_always(sCloudNoiseRawImage->getData()) ;
-
- sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE);
- }
- else
- {
- sCloudNoiseRawImage = NULL ;
- }
- }
-
- LLWLParamManager::getInstance()->propagateParameters();
}
LLDrawPoolWLSky::~LLDrawPoolWLSky()
{
- //LL_INFOS() << "destructing wlsky draw pool." << LL_ENDL;
- sCloudNoiseTexture = NULL;
- sCloudNoiseRawImage = NULL;
}
LLViewerTexture *LLDrawPoolWLSky::getDebugTexture()
@@ -112,39 +80,70 @@ void LLDrawPoolWLSky::beginRenderPass( S32 pass )
LLPipeline::sUnderWaterRender ?
&gObjectFullbrightNoColorWaterProgram :
&gWLCloudProgram;
+
+ sun_shader =
+ LLPipeline::sUnderWaterRender ?
+ &gObjectFullbrightNoColorWaterProgram :
+ &gWLSunProgram;
+
+ moon_shader =
+ LLPipeline::sUnderWaterRender ?
+ &gObjectFullbrightNoColorWaterProgram :
+ &gWLMoonProgram;
}
void LLDrawPoolWLSky::endRenderPass( S32 pass )
{
+ sky_shader = nullptr;
+ cloud_shader = nullptr;
+ sun_shader = nullptr;
+ moon_shader = nullptr;
}
void LLDrawPoolWLSky::beginDeferredPass(S32 pass)
{
sky_shader = &gDeferredWLSkyProgram;
cloud_shader = &gDeferredWLCloudProgram;
+
+ sun_shader =
+ LLPipeline::sUnderWaterRender ?
+ &gObjectFullbrightNoColorWaterProgram :
+ &gDeferredWLSunProgram;
+
+ moon_shader =
+ LLPipeline::sUnderWaterRender ?
+ &gObjectFullbrightNoColorWaterProgram :
+ &gDeferredWLMoonProgram;
}
void LLDrawPoolWLSky::endDeferredPass(S32 pass)
{
-
+ sky_shader = nullptr;
+ cloud_shader = nullptr;
+ sun_shader = nullptr;
+ moon_shader = nullptr;
}
-void LLDrawPoolWLSky::renderDome(F32 camHeightLocal, LLGLSLShader * shader) const
+void LLDrawPoolWLSky::renderFsSky(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const
{
- LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
+ gSky.mVOWLSkyp->drawFsSky();
+}
- llassert_always(NULL != shader);
+void LLDrawPoolWLSky::renderDome(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const
+{
+ llassert_always(NULL != shader);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.pushMatrix();
//chop off translation
- if (LLPipeline::sReflectionRender && origin.mV[2] > 256.f)
+ if (LLPipeline::sReflectionRender && camPosLocal.mV[2] > 256.f)
{
- gGL.translatef(origin.mV[0], origin.mV[1], 256.f-origin.mV[2]*0.5f);
+ gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], 256.f-camPosLocal.mV[2]*0.5f);
}
else
{
- gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
+ gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
}
@@ -156,64 +155,120 @@ void LLDrawPoolWLSky::renderDome(F32 camHeightLocal, LLGLSLShader * shader) cons
gGL.translatef(0.f,-camHeightLocal, 0.f);
- // Draw WL Sky
- static LLStaticHashedString sCamPosLocal("camPosLocal");
+ // Draw WL Sky
shader->uniform3f(sCamPosLocal, 0.f, camHeightLocal, 0.f);
- gSky.mVOWLSkyp->drawDome();
+ gSky.mVOWLSkyp->drawDome();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.popMatrix();
}
-void LLDrawPoolWLSky::renderSkyHaze(F32 camHeightLocal) const
+void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const
{
+ LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
+
if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
{
- LLGLDisable blend(GL_BLEND);
+ LLGLSPipelineDepthTestSkyBox sky(true, true);
- sky_shader->bind();
+ sky_shader->bind();
- /// Render the skydome
- renderDome(camHeightLocal, sky_shader);
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+ LLViewerTexture* rainbow_tex = gSky.mVOSkyp->getRainbowTex();
+ LLViewerTexture* halo_tex = gSky.mVOSkyp->getHaloTex();
+
+ sky_shader->bindTexture(LLShaderMgr::RAINBOW_MAP, rainbow_tex);
+ sky_shader->bindTexture(LLShaderMgr::HALO_MAP, halo_tex);
+
+ ((LLSettingsVOSky*)psky.get())->updateShader(sky_shader);
+
+ F32 moisture_level = (float)psky->getSkyMoistureLevel();
+ F32 droplet_radius = (float)psky->getSkyDropletRadius();
+ F32 ice_level = (float)psky->getSkyIceLevel();
+
+ // hobble halos and rainbows when there's no light source to generate them
+ if (!psky->getIsSunUp() && !psky->getIsMoonUp())
+ {
+ moisture_level = 0.0f;
+ ice_level = 0.0f;
+ }
+
+ sky_shader->uniform1f(LLShaderMgr::MOISTURE_LEVEL, moisture_level);
+ sky_shader->uniform1f(LLShaderMgr::DROPLET_RADIUS, droplet_radius);
+ sky_shader->uniform1f(LLShaderMgr::ICE_LEVEL, ice_level);
+
+ sky_shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor());
+
+ sky_shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, psky->getIsSunUp() ? 1 : 0);
+
+ /// Render the skydome
+ renderDome(origin, camHeightLocal, sky_shader);
sky_shader->unbind();
- }
+ }
+}
+
+void LLDrawPoolWLSky::renderSkyHaze(const LLVector3& camPosLocal, F32 camHeightLocal) const
+{
+ LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
+
+ if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
+ {
+ 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);
+ renderDome(origin, camHeightLocal, sky_shader);
+ sky_shader->unbind();
+ }
}
void LLDrawPoolWLSky::renderStars(void) const
{
- LLGLSPipelineSkyBox gls_sky;
- LLGLEnable blend(GL_BLEND);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ LLGLSPipelineBlendSkyBox gls_skybox(true, false);
// *NOTE: have to have bound the cloud noise texture already since register
// combiners blending below requires something to be bound
// and we might as well only bind once.
gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
- gPipeline.disableLights();
-
// *NOTE: we divide by two here and GL_ALPHA_SCALE by two below to avoid
// clamping and allow the star_alpha param to brighten the stars.
- bool error;
LLColor4 star_alpha(LLColor4::black);
- star_alpha.mV[3] = LLWLParamManager::getInstance()->mCurParams.getFloat("star_brightness", error) / 2.f;
- // If start_brightness is not set, exit
- if( error )
+ star_alpha.mV[3] = LLEnvironment::instance().getCurrentSky()->getStarBrightness() / 512.f;
+
+ // If star brightness is not set, exit
+ if( star_alpha.mV[3] < 0.001 )
{
- LL_WARNS() << "star_brightness missing in mCurParams" << LL_ENDL;
+ LL_DEBUGS("SKY") << "star_brightness below threshold." << LL_ENDL;
return;
}
- gGL.getTexUnit(0)->bind(gSky.mVOSkyp->getBloomTex());
+ LLViewerTexture* tex_a = gSky.mVOSkyp->getBloomTex();
+ LLViewerTexture* tex_b = gSky.mVOSkyp->getBloomTexNext();
+
+ if (tex_a && (!tex_b || (tex_a == tex_b)))
+ {
+ // Bind current and next sun textures
+ gGL.getTexUnit(0)->bind(tex_a);
+ }
+ else if (tex_b && !tex_a)
+ {
+ gGL.getTexUnit(0)->bind(tex_b);
+ }
+ else if (tex_b != tex_a)
+ {
+ gGL.getTexUnit(0)->bind(tex_a);
+ }
gGL.pushMatrix();
gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f);
if (LLGLSLShader::sNoFixedFunction)
{
gCustomAlphaProgram.bind();
- static LLStaticHashedString sCustomAlpha("custom_alpha");
gCustomAlphaProgram.uniform1f(sCustomAlpha, star_alpha.mV[3]);
}
else
@@ -225,6 +280,8 @@ void LLDrawPoolWLSky::renderStars(void) const
gSky.mVOWLSkyp->drawStars();
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
gGL.popMatrix();
if (LLGLSLShader::sNoFixedFunction)
@@ -238,73 +295,293 @@ void LLDrawPoolWLSky::renderStars(void) const
}
}
-void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const
+void LLDrawPoolWLSky::renderStarsDeferred(void) const
{
- if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && sCloudNoiseTexture.notNull())
- {
- LLGLEnable blend(GL_BLEND);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
-
- gGL.getTexUnit(0)->bind(sCloudNoiseTexture);
+ LLGLSPipelineBlendSkyBox gls_sky(true, false);
- cloud_shader->bind();
+ gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
+
+ F32 star_alpha = LLEnvironment::instance().getCurrentSky()->getStarBrightness() / 500.0f;
+
+ // If start_brightness is not set, exit
+ if(star_alpha < 0.001f)
+ {
+ LL_DEBUGS("SKY") << "star_brightness below threshold." << LL_ENDL;
+ return;
+ }
+
+ gDeferredStarProgram.bind();
+
+ LLViewerTexture* tex_a = gSky.mVOSkyp->getBloomTex();
+ LLViewerTexture* tex_b = gSky.mVOSkyp->getBloomTexNext();
+
+ F32 blend_factor = LLEnvironment::instance().getCurrentSky()->getBlendFactor();
+
+ if (tex_a && (!tex_b || (tex_a == tex_b)))
+ {
+ // Bind current and next sun textures
+ gGL.getTexUnit(0)->bind(tex_a);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+ blend_factor = 0;
+ }
+ else if (tex_b && !tex_a)
+ {
+ gGL.getTexUnit(0)->bind(tex_b);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+ blend_factor = 0;
+ }
+ else if (tex_b != tex_a)
+ {
+ gGL.getTexUnit(0)->bind(tex_a);
+ gGL.getTexUnit(1)->bind(tex_b);
+ }
+
+ gDeferredStarProgram.uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+
+ if (LLPipeline::sReflectionRender)
+ {
+ star_alpha = 1.0f;
+ }
+ gDeferredStarProgram.uniform1f(sCustomAlpha, star_alpha);
+
+ sStarTime = (F32)LLFrameTimer::getElapsedSeconds() * 0.5f;
+
+ gDeferredStarProgram.uniform1f(LLShaderMgr::WATER_TIME, sStarTime);
+
+ gSky.mVOWLSkyp->drawStars();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+
+ gDeferredStarProgram.unbind();
+}
+
+void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const
+{
+ if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp->getCloudNoiseTex())
+ {
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+ LLGLSPipelineBlendSkyBox pipeline(true, true);
+
+ cloudshader->bind();
+
+ LLPointer cloud_noise = gSky.mVOSkyp->getCloudNoiseTex();
+ LLPointer cloud_noise_next = gSky.mVOSkyp->getCloudNoiseTexNext();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+
+ F32 cloud_variance = psky ? psky->getCloudVariance() : 0.0f;
+ F32 blend_factor = psky ? psky->getBlendFactor() : 0.0f;
+
+ // if we even have sun disc textures to work with...
+ if (cloud_noise || cloud_noise_next)
+ {
+ if (cloud_noise && (!cloud_noise_next || (cloud_noise == cloud_noise_next)))
+ {
+ // Bind current and next sun textures
+ cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise, LLTexUnit::TT_TEXTURE);
+ blend_factor = 0;
+ }
+ else if (cloud_noise_next && !cloud_noise)
+ {
+ cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise_next, LLTexUnit::TT_TEXTURE);
+ blend_factor = 0;
+ }
+ else if (cloud_noise_next != cloud_noise)
+ {
+ cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise, LLTexUnit::TT_TEXTURE);
+ cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP_NEXT, cloud_noise_next, LLTexUnit::TT_TEXTURE);
+ }
+ }
+
+ cloudshader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+ cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance);
+ cloudshader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor());
+
+ ((LLSettingsVOSky*)psky.get())->updateShader(cloudshader);
/// Render the skydome
- renderDome(camHeightLocal, cloud_shader);
+ renderDome(camPosLocal, camHeightLocal, cloudshader);
- cloud_shader->unbind();
+ cloudshader->unbind();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+}
+
+void LLDrawPoolWLSky::renderSkyClouds(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const
+{
+ if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp->getCloudNoiseTex())
+ {
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+ LLGLSPipelineBlendSkyBox pipeline(true, true);
+
+ cloudshader->bind();
+
+ LLPointer cloud_noise = gSky.mVOSkyp->getCloudNoiseTex();
+ LLPointer cloud_noise_next = gSky.mVOSkyp->getCloudNoiseTexNext();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+
+ F32 cloud_variance = psky ? psky->getCloudVariance() : 0.0f;
+ F32 blend_factor = psky ? psky->getBlendFactor() : 0.0f;
+
+ // if we even have sun disc textures to work with...
+ if (cloud_noise || cloud_noise_next)
+ {
+ if (cloud_noise && (!cloud_noise_next || (cloud_noise == cloud_noise_next)))
+ {
+ // Bind current and next sun textures
+ cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise, LLTexUnit::TT_TEXTURE);
+ blend_factor = 0;
+ }
+ else if (cloud_noise_next && !cloud_noise)
+ {
+ cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise_next, LLTexUnit::TT_TEXTURE);
+ blend_factor = 0;
+ }
+ else if (cloud_noise_next != cloud_noise)
+ {
+ cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise, LLTexUnit::TT_TEXTURE);
+ cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP_NEXT, cloud_noise_next, LLTexUnit::TT_TEXTURE);
+ }
+ }
+
+ cloudshader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+ cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance);
+ cloudshader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor());
+
+ ((LLSettingsVOSky*)psky.get())->updateShader(cloudshader);
+
+ /// Render the skydome
+ renderDome(camPosLocal, camHeightLocal, cloudshader);
+
+ cloudshader->unbind();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
}
}
void LLDrawPoolWLSky::renderHeavenlyBodies()
{
- LLGLSPipelineSkyBox gls_skybox;
- LLGLEnable blend_on(GL_BLEND);
- gPipeline.disableLights();
+ LLGLSPipelineBlendSkyBox gls_skybox(true, false);
+
+ LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
+ gGL.pushMatrix();
+ gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
-#if 0 // when we want to re-add a texture sun disc, here's where to do it.
LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_SUN];
- if (gSky.mVOSkyp->getSun().getDraw() && face->getGeomCount())
+
+ F32 blend_factor = LLEnvironment::instance().getCurrentSky()->getBlendFactor();
+ bool can_use_vertex_shaders = gPipeline.canUseVertexShaders();
+ bool can_use_windlight_shaders = gPipeline.canUseWindLightShaders();
+
+
+ if (gSky.mVOSkyp->getSun().getDraw() && face && face->getGeomCount())
{
- LLViewerTexture * tex = face->getTexture();
- gGL.getTexUnit(0)->bind(tex);
- LLColor4 color(gSky.mVOSkyp->getSun().getInterpColor());
- LLFacePool::LLOverrideFaceColor color_override(this, color);
- face->renderIndexed();
+ LLPointer tex_a = face->getTexture(LLRender::DIFFUSE_MAP);
+ LLPointer tex_b = face->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP);
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+
+ // if we even have sun disc textures to work with...
+ if (tex_a || tex_b)
+ {
+ // if and only if we have a texture defined, render the sun disc
+ if (can_use_vertex_shaders && can_use_windlight_shaders)
+ {
+ sun_shader->bind();
+
+ if (tex_a && (!tex_b || (tex_a == tex_b)))
+ {
+ // Bind current and next sun textures
+ sun_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, tex_a, LLTexUnit::TT_TEXTURE);
+ blend_factor = 0;
+ }
+ else if (tex_b && !tex_a)
+ {
+ sun_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, tex_b, LLTexUnit::TT_TEXTURE);
+ blend_factor = 0;
+ }
+ else if (tex_b != tex_a)
+ {
+ sun_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, tex_a, LLTexUnit::TT_TEXTURE);
+ sun_shader->bindTexture(LLShaderMgr::ALTERNATE_DIFFUSE_MAP, tex_b, LLTexUnit::TT_TEXTURE);
+ }
+
+ LLColor4 color(gSky.mVOSkyp->getSun().getInterpColor());
+
+ sun_shader->uniform4fv(LLShaderMgr::DIFFUSE_COLOR, 1, color.mV);
+ sun_shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+
+ face->renderIndexed();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+
+ sun_shader->unbind();
+ }
+ }
}
-#endif
- LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON];
+ 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)
+ {
+ LLViewerTexture* tex_a = face->getTexture(LLRender::DIFFUSE_MAP);
+ LLViewerTexture* tex_b = face->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP);
- if (gSky.mVOSkyp->getMoon().getDraw() && face->getGeomCount())
- {
- // *NOTE: even though we already bound this texture above for the
- // stars register combiners, we bind again here for defensive reasons,
- // since LLImageGL::bind detects that it's a noop, and optimizes it out.
- gGL.getTexUnit(0)->bind(face->getTexture());
LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor());
- F32 a = gSky.mVOSkyp->getMoon().getDirection().mV[2];
- if (a > 0.f)
- {
- a = a*a*4.f;
- }
-
- color.mV[3] = llclamp(a, 0.f, 1.f);
- if (gPipeline.canUseVertexShaders())
- {
- gHighlightProgram.bind();
- }
+ if (can_use_vertex_shaders && can_use_windlight_shaders && (tex_a || tex_b))
+ {
+ moon_shader->bind();
- LLFacePool::LLOverrideFaceColor color_override(this, color);
-
- face->renderIndexed();
+ if (tex_a && (!tex_b || (tex_a == tex_b)))
+ {
+ // Bind current and next sun textures
+ moon_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, tex_a, LLTexUnit::TT_TEXTURE);
+ blend_factor = 0;
+ }
+ else if (tex_b && !tex_a)
+ {
+ moon_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, tex_b, LLTexUnit::TT_TEXTURE);
+ 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);
+ }
- if (gPipeline.canUseVertexShaders())
- {
- gHighlightProgram.unbind();
- }
- }
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+ F32 moon_brightness = (float)psky->getMoonBrightness();
+
+ 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);
+
+ face->renderIndexed();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+
+ moon_shader->unbind();
+ }
+ }
+
+ gGL.popMatrix();
}
void LLDrawPoolWLSky::renderDeferred(S32 pass)
@@ -315,43 +592,20 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass)
}
LL_RECORD_BLOCK_TIME(FTM_RENDER_WL_SKY);
- const F32 camHeightLocal = LLWLParamManager::getInstance()->getDomeOffset() * LLWLParamManager::getInstance()->getDomeRadius();
-
- LLGLSNoFog disableFog;
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- LLGLDisable clip(GL_CLIP_PLANE0);
+ const F32 camHeightLocal = LLEnvironment::instance().getCamHeight();
gGL.setColorMask(true, false);
- LLGLSquashToFarClip far_clip(glh_get_current_projection());
-
- renderSkyHaze(camHeightLocal);
-
- LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
- gGL.pushMatrix();
-
-
- gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
-
- gDeferredStarProgram.bind();
- // *NOTE: have to bind a texture here since register combiners blending in
- // renderStars() requires something to be bound and we might as well only
- // bind the moon's texture once.
- gGL.getTexUnit(0)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture());
-
- renderHeavenlyBodies();
-
- renderStars();
-
- gDeferredStarProgram.unbind();
-
- gGL.popMatrix();
-
- renderSkyClouds(camHeightLocal);
-
- gGL.setColorMask(true, true);
- //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
+ if (gPipeline.canUseWindLightShaders())
+ {
+ renderSkyHazeDeferred(origin, camHeightLocal);
+ renderStarsDeferred();
+ renderHeavenlyBodies();
+ renderSkyCloudsDeferred(origin, camHeightLocal, cloud_shader);
+ }
+ gGL.setColorMask(true, true);
}
void LLDrawPoolWLSky::render(S32 pass)
@@ -362,34 +616,13 @@ void LLDrawPoolWLSky::render(S32 pass)
}
LL_RECORD_BLOCK_TIME(FTM_RENDER_WL_SKY);
- const F32 camHeightLocal = LLWLParamManager::getInstance()->getDomeOffset() * LLWLParamManager::getInstance()->getDomeRadius();
-
- LLGLSNoFog disableFog;
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- LLGLDisable clip(GL_CLIP_PLANE0);
-
- LLGLSquashToFarClip far_clip(glh_get_current_projection());
-
- renderSkyHaze(camHeightLocal);
-
- LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
- gGL.pushMatrix();
-
- gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
-
- // *NOTE: have to bind a texture here since register combiners blending in
- // renderStars() requires something to be bound and we might as well only
- // bind the moon's texture once.
- gGL.getTexUnit(0)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture());
-
- renderHeavenlyBodies();
-
- renderStars();
-
-
- gGL.popMatrix();
-
- renderSkyClouds(camHeightLocal);
+ const F32 camHeightLocal = LLEnvironment::instance().getCamHeight();
+ LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
+
+ renderSkyHaze(origin, camHeightLocal);
+ renderStars();
+ renderHeavenlyBodies();
+ renderSkyClouds(origin, camHeightLocal, cloud_shader);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
@@ -416,15 +649,9 @@ void LLDrawPoolWLSky::resetDrawOrders()
//static
void LLDrawPoolWLSky::cleanupGL()
{
- sCloudNoiseTexture = NULL;
}
//static
void LLDrawPoolWLSky::restoreGL()
{
- if(sCloudNoiseRawImage.notNull())
- {
- sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE);
- }
}
-
diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h
index cd15c991ee..3acfda4eee 100644
--- a/indra/newview/lldrawpoolwlsky.h
+++ b/indra/newview/lldrawpoolwlsky.h
@@ -38,7 +38,8 @@ public:
LLVertexBuffer::MAP_TEXCOORD0;
static const U32 STAR_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0;
-
+ static const U32 ADV_ATMO_SKY_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX
+ | LLVertexBuffer::MAP_TEXCOORD0;
LLDrawPoolWLSky(void);
/*virtual*/ ~LLDrawPoolWLSky();
@@ -57,7 +58,7 @@ public:
/*virtual*/ void prerender();
/*virtual*/ U32 getVertexDataMask() { return SKY_VERTEX_DATA_MASK; }
/*virtual*/ BOOL verify() const { return TRUE; } // Verify that all data in the draw pool is correct!
- /*virtual*/ S32 getVertexShaderLevel() const { return mVertexShaderLevel; }
+ /*virtual*/ S32 getShaderLevel() const { return mShaderLevel; }
//static LLDrawPool* createPool(const U32 type, LLViewerTexture *tex0 = NULL);
@@ -70,15 +71,18 @@ public:
static void cleanupGL();
static void restoreGL();
private:
- void renderDome(F32 camHeightLocal, LLGLSLShader * shader) const;
- void renderSkyHaze(F32 camHeightLocal) const;
- void renderStars(void) const;
- void renderSkyClouds(F32 camHeightLocal) const;
- void renderHeavenlyBodies();
+ void renderFsSky(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const;
+ void renderDome(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const;
-private:
- static LLPointer sCloudNoiseTexture;
- static LLPointer sCloudNoiseRawImage;
+ void renderSkyHaze(const LLVector3& camPosLocal, F32 camHeightLocal) const;
+ void renderSkyClouds(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const;
+
+ void renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const;
+ void renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const;
+
+ void renderStarsDeferred(void) const;
+ void renderStars(void) const;
+ void renderHeavenlyBodies();
};
#endif // LL_DRAWPOOLWLSKY_H
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index 2e5b77a895..a292c21556 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -129,12 +129,11 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth)
////only images up to 512x512 are supported
//llassert(mFullHeight <= 512);
//llassert(mFullWidth <= 512);
- gPipeline.allocatePhysicsBuffer();
- llassert(mFullWidth <= static_cast(gPipeline.mPhysicsDisplay.getWidth()));
- llassert(mFullHeight <= static_cast(gPipeline.mPhysicsDisplay.getHeight()));
-
- if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI)
+ llassert(mFullWidth <= static_cast(gPipeline.mBake.getWidth()));
+ llassert(mFullHeight <= static_cast(gPipeline.mBake.getHeight()));
//
+
+ if (gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete())
{ //using offscreen render target, just use the bottom left corner
mOrigin.set(0, 0);
}
@@ -221,15 +220,14 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
return TRUE;
}
- // changes to support higher resolution rendering in the preview
- // bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI;
- bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI;
+ bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete();
+
if (use_fbo)
{
- // gPipeline.mWaterDis.bindTarget();
- gPipeline.mPhysicsDisplay.bindTarget();
+ gPipeline.mBake.bindTarget();
+ gPipeline.mBake.clear();
}
- //
+
LLGLSLShader::bindNoShader();
LLVertexBuffer::unbind();
@@ -247,6 +245,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
gDepthDirty = TRUE;
gGL.color4f(1,1,1,1);
+ dynamicTexture->setBoundTarget(use_fbo ? &gPipeline.mBake : nullptr);
dynamicTexture->preRender(); // Must be called outside of startRender()
result = FALSE;
if (dynamicTexture->render())
@@ -257,7 +256,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
}
gGL.flush();
LLVertexBuffer::unbind();
-
+ dynamicTexture->setBoundTarget(nullptr);
dynamicTexture->postRender(result);
}
}
@@ -265,12 +264,11 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
if (use_fbo)
{
- // changes to support higher resolution rendering in the preview
- // gPipeline.mWaterDis.flush();
- gPipeline.mPhysicsDisplay.flush();
- //
+ gPipeline.mBake.flush();
}
+ gGL.flush();
+
return ret;
}
diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h
index f3f57c9a6b..4bd74a8425 100644
--- a/indra/newview/lldynamictexture.h
+++ b/indra/newview/lldynamictexture.h
@@ -88,6 +88,9 @@ public:
static BOOL updateAllInstances();
static void destroyGL() ;
static void restoreGL() ;
+
+ void setBoundTarget(LLRenderTarget* target) { mBoundTarget = target; }
+
protected:
void generateGLTexture();
void generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes = FALSE);
@@ -97,6 +100,8 @@ protected:
LLCoordGL mOrigin;
LL_ALIGN_16(LLCamera mCamera);
+ LLRenderTarget* mBoundTarget;
+
typedef std::set instance_list_t;
static instance_list_t sInstances[ LLViewerDynamicTexture::ORDER_COUNT ];
static S32 sNumRenders;
diff --git a/indra/newview/llenvadapters.cpp b/indra/newview/llenvadapters.cpp
new file mode 100644
index 0000000000..fdbcf68fa4
--- /dev/null
+++ b/indra/newview/llenvadapters.cpp
@@ -0,0 +1,67 @@
+/**
+ * @file llenvadapters.cpp
+ * @brief Declaration of classes managing WindLight and water settings.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llenvadapters.h"
+
+#include "llsettingssky.h"
+#include "llsettingswater.h"
+//=========================================================================
+
+LLSkySettingsAdapter::LLSkySettingsAdapter():
+ mWLGamma(1.0f, LLSettingsSky::SETTING_GAMMA),
+
+ // Lighting
+ mLightnorm(LLColor4(0.f, 0.707f, -0.707f, 1.f), LLSettingsSky::SETTING_LIGHT_NORMAL),
+ mSunlight(LLColor4(0.5f, 0.5f, 0.5f, 1.0f), LLSettingsSky::SETTING_SUNLIGHT_COLOR, "WLSunlight"),
+
+ mGlow(LLColor4(18.0f, 0.0f, -0.01f, 1.0f), LLSettingsSky::SETTING_GLOW),
+ // Clouds
+ mCloudColor(LLColor4(0.5f, 0.5f, 0.5f, 1.0f), LLSettingsSky::SETTING_CLOUD_COLOR, "WLCloudColor"),
+ mCloudMain(LLColor4(0.5f, 0.5f, 0.125f, 1.0f), LLSettingsSky::SETTING_CLOUD_POS_DENSITY1),
+ mCloudCoverage(0.0f, LLSettingsSky::SETTING_CLOUD_SHADOW),
+ mCloudDetail(LLColor4(0.0f, 0.0f, 0.0f, 1.0f), LLSettingsSky::SETTING_CLOUD_POS_DENSITY2),
+ mCloudScale(0.42f, LLSettingsSky::SETTING_CLOUD_SCALE)
+{
+
+}
+
+LLWatterSettingsAdapter::LLWatterSettingsAdapter():
+ mFogColor(LLColor4((22.f / 255.f), (43.f / 255.f), (54.f / 255.f), (0.0f)), LLSettingsWater::SETTING_FOG_COLOR, "WaterFogColor"),
+ mFogDensity(4, LLSettingsWater::SETTING_FOG_DENSITY, 2),
+ mUnderWaterFogMod(0.25, LLSettingsWater::SETTING_FOG_MOD),
+ mNormalScale(LLVector3(2.f, 2.f, 2.f), LLSettingsWater::SETTING_NORMAL_SCALE),
+ mFresnelScale(0.5f, LLSettingsWater::SETTING_FRESNEL_SCALE),
+ mFresnelOffset(0.4f, LLSettingsWater::SETTING_FRESNEL_OFFSET),
+ mScaleAbove(0.025f, LLSettingsWater::SETTING_SCALE_ABOVE),
+ mScaleBelow(0.2f, LLSettingsWater::SETTING_SCALE_BELOW),
+ mBlurMultiplier(0.1f, LLSettingsWater::SETTING_BLUR_MULTIPILER),
+ mWave1Dir(LLVector2(0.5f, 0.5f), LLSettingsWater::SETTING_WAVE1_DIR),
+ mWave2Dir(LLVector2(0.5f, 0.5f), LLSettingsWater::SETTING_WAVE2_DIR)
+
+{
+
+}
diff --git a/indra/newview/llenvadapters.h b/indra/newview/llenvadapters.h
new file mode 100644
index 0000000000..bd58db0589
--- /dev/null
+++ b/indra/newview/llenvadapters.h
@@ -0,0 +1,459 @@
+/**
+ * @file llenvadapters.h
+ * @brief Declaration of classes managing WindLight and water settings.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_ENVADAPTERS_H
+#define LL_ENVADAPTERS_H
+
+#include "v3math.h"
+#include "v3color.h"
+#include "v4math.h"
+#include "llsettingsbase.h"
+#include "llsettingssky.h"
+
+class WLColorControl
+{
+public:
+ inline WLColorControl(LLColor4 color, const std::string& n, const std::string& slider_name = std::string()):
+ mColor(color),
+ mName(n),
+ mSliderName(slider_name),
+ mHasSliderName(false),
+ mIsSunOrAmbientColor(false),
+ mIsBlueHorizonOrDensity(false)
+ {
+ // if there's a slider name, say we have one
+ mHasSliderName = !mSliderName.empty();
+
+ // if it's the sun controller
+ mIsSunOrAmbientColor = (mSliderName == "WLSunlight" || mSliderName == "WLAmbient");
+ mIsBlueHorizonOrDensity = (mSliderName == "WLBlueHorizon" || mSliderName == "WLBlueDensity");
+ }
+
+ inline void setColor4(const LLColor4 & val)
+ {
+ mColor = val;
+ }
+
+ inline void setColor3(const LLColor3 & val)
+ {
+ mColor = val;
+ }
+
+ inline LLColor4 getColor4() const
+ {
+ return mColor;
+ }
+
+ inline LLColor3 getColor3(void) const
+ {
+ return vec4to3(mColor);
+ }
+
+ inline void update(const LLSettingsBase::ptr_t &psetting) const
+ {
+ psetting->setValue(mName, mColor);
+ }
+
+ inline bool getHasSliderName() const
+ {
+ return mHasSliderName;
+ }
+
+ inline std::string getSliderName() const
+ {
+ return mSliderName;
+ }
+
+ inline bool getIsSunOrAmbientColor() const
+ {
+ return mIsSunOrAmbientColor;
+ }
+
+ inline bool getIsBlueHorizonOrDensity() const
+ {
+ return mIsBlueHorizonOrDensity;
+ }
+
+ inline F32 getRed() const
+ {
+ return mColor[0];
+ }
+
+ inline F32 getGreen() const
+ {
+ return mColor[1];
+ }
+
+ inline F32 getBlue() const
+ {
+ return mColor[2];
+ }
+
+ inline F32 getIntensity() const
+ {
+ return mColor[3];
+ }
+
+ inline void setRed(F32 red)
+ {
+ mColor[0] = red;
+ }
+
+ inline void setGreen(F32 green)
+ {
+ mColor[1] = green;
+ }
+
+ inline void setBlue(F32 blue)
+ {
+ mColor[2] = blue;
+ }
+
+ inline void setIntensity(F32 intensity)
+ {
+ mColor[3] = intensity;
+ }
+
+private:
+ LLColor4 mColor; /// [3] is intensity, not alpha
+ std::string mName; /// name to use to dereference params
+ std::string mSliderName; /// name of the slider in menu
+ bool mHasSliderName; /// only set slider name for true color types
+ bool mIsSunOrAmbientColor; /// flag for if it's the sun or ambient color controller
+ bool mIsBlueHorizonOrDensity; /// flag for if it's the Blue Horizon or Density color controller
+
+};
+
+// float slider control
+class WLFloatControl
+{
+public:
+ inline WLFloatControl(F32 val, const std::string& n, F32 m = 1.0f):
+ x(val),
+ mName(n),
+ mult(m)
+ {
+ }
+
+ inline WLFloatControl &operator = (F32 val)
+ {
+ x = val;
+ return *this;
+ }
+
+ inline operator F32 (void) const
+ {
+ return x;
+ }
+
+ inline void update(const LLSettingsBase::ptr_t &psetting) const
+ {
+ psetting->setValue(mName, x);
+ }
+
+ inline F32 getMult() const
+ {
+ return mult;
+ }
+
+ inline void setValue(F32 val)
+ {
+ x = val;
+ }
+
+private:
+ F32 x;
+ std::string mName;
+ F32 mult;
+};
+
+class WLXFloatControl
+{
+public:
+ inline WLXFloatControl(F32 val, const std::string& n, F32 b):
+ mExp(val),
+ mBase(b),
+ mName(n)
+ {
+ }
+
+ inline WLXFloatControl & operator = (F32 val)
+ {
+ mExp = log(val) / log(mBase);
+
+ return *this;
+ }
+
+ inline operator F32 (void) const
+ {
+ return pow(mBase, mExp);
+ }
+
+ inline void update(const LLSettingsBase::ptr_t &psetting) const
+ {
+ psetting->setValue(mName, pow(mBase, mExp));
+ }
+
+ inline F32 getExp() const
+ {
+ return mExp;
+ }
+
+ inline void setExp(F32 val)
+ {
+ mExp = val;
+ }
+
+ inline F32 getBase() const
+ {
+ return mBase;
+ }
+
+ inline void setBase(F32 val)
+ {
+ mBase = val;
+ }
+
+private:
+ F32 mExp;
+ F32 mBase;
+ std::string mName;
+};
+
+class WLVect2Control
+{
+public:
+ inline WLVect2Control(LLVector2 val, const std::string& n):
+ mU(val.mV[0]),
+ mV(val.mV[1]),
+ mName(n)
+ {
+ }
+
+ inline WLVect2Control & operator = (const LLVector2 & val)
+ {
+ mU = val.mV[0];
+ mV = val.mV[1];
+
+ return *this;
+ }
+
+ inline void update(const LLSettingsBase::ptr_t &psetting) const
+ {
+ psetting->setValue(mName, LLVector2(mU, mV));
+ }
+
+ inline F32 getU() const
+ {
+ return mU;
+ }
+
+ inline void setU(F32 val)
+ {
+ mU = val;
+ }
+
+ inline F32 getV() const
+ {
+ return mV;
+ }
+
+ inline void setV(F32 val)
+ {
+ mV = val;
+ }
+
+private:
+ F32 mU;
+ F32 mV;
+ std::string mName;
+};
+
+class WLVect3Control
+{
+public:
+ inline WLVect3Control(LLVector3 val, const std::string& n):
+ mX(val.mV[0]),
+ mY(val.mV[1]),
+ mZ(val.mV[2]),
+ mName(n)
+ {
+ }
+
+ inline WLVect3Control & operator = (const LLVector3 & val)
+ {
+ mX = val.mV[0];
+ mY = val.mV[1];
+ mZ = val.mV[2];
+
+ return *this;
+ }
+
+ inline void update(const LLSettingsBase::ptr_t &psetting) const
+ {
+ psetting->setValue(mName, LLVector3(mX, mY, mZ));
+ }
+
+ inline F32 getX() const
+ {
+ return mX;
+ }
+
+ inline void setX(F32 val)
+ {
+ mX = val;
+ }
+
+ inline F32 getY() const
+ {
+ return mY;
+ }
+
+ inline void setY(F32 val)
+ {
+ mY = val;
+ }
+
+ inline F32 getZ() const
+ {
+ return mZ;
+ }
+
+ inline void setZ(F32 val)
+ {
+ mZ = val;
+ }
+
+private:
+ F32 mX;
+ F32 mY;
+ F32 mZ;
+ std::string mName;
+};
+
+class LLDensityProfileSettingsAdapter
+{
+public:
+ LLDensityProfileSettingsAdapter(const std::string& config, int layerIndex = 0)
+ : mConfig(config)
+ , mLayerIndex(layerIndex)
+ , mLayerWidth(1.0f, LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH)
+ , mExpTerm(1.0f, LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM)
+ , mExpScale(1.0f, LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR)
+ , mLinTerm(1.0f, LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM)
+ , mConstantTerm(1.0f, LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM)
+ {}
+
+protected:
+ std::string mConfig;
+ int mLayerIndex;
+ WLFloatControl mLayerWidth; // 0.0 -> to top of atmosphere, however big that may be.
+ WLFloatControl mExpTerm;
+ WLFloatControl mExpScale;
+ WLFloatControl mLinTerm;
+ WLFloatControl mConstantTerm;
+};
+
+class LLRayleighDensityProfileSettingsAdapter : public LLDensityProfileSettingsAdapter
+{
+public:
+ LLRayleighDensityProfileSettingsAdapter(int layerIndex = 0)
+ : LLDensityProfileSettingsAdapter(LLSettingsSky::SETTING_RAYLEIGH_CONFIG, layerIndex)
+ {
+ }
+};
+
+class LLMieDensityProfileSettingsAdapter : public LLDensityProfileSettingsAdapter
+{
+public:
+ LLMieDensityProfileSettingsAdapter(int layerIndex = 0)
+ : LLDensityProfileSettingsAdapter(LLSettingsSky::SETTING_MIE_CONFIG, layerIndex)
+ , mAnisotropy(0.8f, LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR)
+ {
+ }
+
+protected:
+ WLFloatControl mAnisotropy;
+};
+
+class LLAbsorptionDensityProfileSettingsAdapter : public LLDensityProfileSettingsAdapter
+{
+public:
+ LLAbsorptionDensityProfileSettingsAdapter(int layerIndex = 0)
+ : LLDensityProfileSettingsAdapter(LLSettingsSky::SETTING_ABSORPTION_CONFIG, layerIndex)
+ {
+ }
+};
+
+//-------------------------------------------------------------------------
+class LLSkySettingsAdapter
+{
+public:
+ typedef std::shared_ptr ptr_t;
+
+ LLSkySettingsAdapter();
+
+ WLFloatControl mWLGamma;
+
+ /// Lighting
+ WLColorControl mLightnorm;
+ WLColorControl mSunlight;
+ WLColorControl mGlow;
+
+ /// Clouds
+ WLColorControl mCloudColor;
+ WLColorControl mCloudMain;
+ WLFloatControl mCloudCoverage;
+ WLColorControl mCloudDetail;
+ WLFloatControl mCloudScale;
+};
+
+class LLWatterSettingsAdapter
+{
+public:
+ typedef std::shared_ptr ptr_t;
+
+ LLWatterSettingsAdapter();
+
+ WLColorControl mFogColor;
+ WLXFloatControl mFogDensity;
+ WLFloatControl mUnderWaterFogMod;
+
+ /// wavelet scales and directions
+ WLVect3Control mNormalScale;
+ WLVect2Control mWave1Dir;
+ WLVect2Control mWave2Dir;
+
+ // controls how water is reflected and refracted
+ WLFloatControl mFresnelScale;
+ WLFloatControl mFresnelOffset;
+ WLFloatControl mScaleAbove;
+ WLFloatControl mScaleBelow;
+ WLFloatControl mBlurMultiplier;
+
+};
+
+#endif // LL_ENVIRONMENT_H
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
new file mode 100644
index 0000000000..d9dd9bbc12
--- /dev/null
+++ b/indra/newview/llenvironment.cpp
@@ -0,0 +1,3397 @@
+/**
+ * @file llenvmanager.cpp
+ * @brief Implementation of classes managing WindLight and water settings.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llenvironment.h"
+
+#include
+
+#include "llagent.h"
+#include "llviewercontrol.h" // for gSavedSettings
+#include "llviewerregion.h"
+#include "llwlhandlers.h"
+#include "lltrans.h"
+#include "lltrace.h"
+#include "llfasttimer.h"
+#include "llviewercamera.h"
+#include "pipeline.h"
+#include "llsky.h"
+
+#include "llviewershadermgr.h"
+
+#include "llparcel.h"
+#include "llviewerparcelmgr.h"
+
+#include "llsdserialize.h"
+#include "lldiriterator.h"
+
+#include "llsettingsvo.h"
+#include "llnotificationsutil.h"
+
+#include "llregioninfomodel.h"
+
+#include
+
+#include "llatmosphere.h"
+#include "llagent.h"
+#include "roles_constants.h"
+#include "llestateinfomodel.h"
+
+#include "lldispatcher.h"
+#include "llviewergenericmessage.h"
+#include "llexperiencelog.h"
+
+//=========================================================================
+namespace
+{
+ const std::string KEY_ENVIRONMENT("environment");
+ const std::string KEY_DAYASSET("day_asset");
+ const std::string KEY_DAYCYCLE("day_cycle");
+ const std::string KEY_DAYHASH("day_hash");
+ const std::string KEY_DAYLENGTH("day_length");
+ const std::string KEY_DAYNAME("day_name");
+ const std::string KEY_DAYNAMES("day_names");
+ const std::string KEY_DAYOFFSET("day_offset");
+ const std::string KEY_ENVVERSION("env_version");
+ const std::string KEY_ISDEFAULT("is_default");
+ const std::string KEY_PARCELID("parcel_id");
+ const std::string KEY_REGIONID("region_id");
+ const std::string KEY_TRACKALTS("track_altitudes");
+ const std::string KEY_FLAGS("flags");
+
+ const std::string MESSAGE_PUSHENVIRONMENT("PushExpEnvironment");
+
+ const std::string ACTION_CLEARENVIRONMENT("ClearEnvironment");
+ const std::string ACTION_PUSHFULLENVIRONMENT("PushFullEnvironment");
+ const std::string ACTION_PUSHPARTIALENVIRONMENT("PushPartialEnvironment");
+
+ const std::string KEY_ASSETID("asset_id");
+ const std::string KEY_TRANSITIONTIME("transition_time");
+ const std::string KEY_ACTION("action");
+ const std::string KEY_ACTIONDATA("action_data");
+ const std::string KEY_EXPERIENCEID("public_id");
+ const std::string KEY_OBJECTNAME("ObjectName"); // some of these do not conform to the '_' format.
+ const std::string KEY_PARCELNAME("ParcelName"); // But changing these would also alter the Experience Log requirements.
+ const std::string KEY_COUNT("Count");
+
+ const std::string LISTENER_NAME("LLEnvironmentSingleton");
+ const std::string PUMP_EXPERIENCE("experience_permission");
+
+ const std::string LOCAL_ENV_STORAGE_FILE("local_environment_data.bin");
+
+ //---------------------------------------------------------------------
+ LLTrace::BlockTimerStatHandle FTM_ENVIRONMENT_UPDATE("Update Environment Tick");
+ LLTrace::BlockTimerStatHandle FTM_SHADER_PARAM_UPDATE("Update Shader Parameters");
+
+ LLSettingsBase::Seconds DEFAULT_UPDATE_THRESHOLD(10.0);
+ const LLSettingsBase::Seconds MINIMUM_SPANLENGTH(0.01f);
+
+ //---------------------------------------------------------------------
+ inline LLSettingsBase::TrackPosition get_wrapping_distance(LLSettingsBase::TrackPosition begin, LLSettingsBase::TrackPosition end)
+ {
+ if (begin < end)
+ {
+ return end - begin;
+ }
+ else if (begin > end)
+ {
+ return LLSettingsBase::TrackPosition(1.0) - (begin - end);
+ }
+
+ return 1.0f;
+ }
+
+ LLSettingsDay::CycleTrack_t::iterator get_wrapping_atafter(LLSettingsDay::CycleTrack_t &collection, const LLSettingsBase::TrackPosition& key)
+ {
+ if (collection.empty())
+ return collection.end();
+
+ LLSettingsDay::CycleTrack_t::iterator it = collection.upper_bound(key);
+
+ if (it == collection.end())
+ { // wrap around
+ it = collection.begin();
+ }
+
+ return it;
+ }
+
+ LLSettingsDay::CycleTrack_t::iterator get_wrapping_atbefore(LLSettingsDay::CycleTrack_t &collection, const LLSettingsBase::TrackPosition& key)
+ {
+ if (collection.empty())
+ return collection.end();
+
+ LLSettingsDay::CycleTrack_t::iterator it = collection.lower_bound(key);
+
+ if (it == collection.end())
+ { // all keyframes are lower, take the last one.
+ --it; // we know the range is not empty
+ }
+ else if ((*it).first > key)
+ { // the keyframe we are interested in is smaller than the found.
+ if (it == collection.begin())
+ it = collection.end();
+ --it;
+ }
+
+ return it;
+ }
+
+ LLSettingsDay::TrackBound_t get_bounding_entries(LLSettingsDay::CycleTrack_t &track, const LLSettingsBase::TrackPosition& keyframe)
+ {
+ return LLSettingsDay::TrackBound_t(get_wrapping_atbefore(track, keyframe), get_wrapping_atafter(track, keyframe));
+ }
+
+ // Find normalized track position of given time along full length of cycle
+ inline LLSettingsBase::TrackPosition convert_time_to_position(const LLSettingsBase::Seconds& time, const LLSettingsBase::Seconds& len)
+ {
+ LLSettingsBase::TrackPosition position = LLSettingsBase::TrackPosition(fmod((F64)time, (F64)len) / (F64)len);
+ return llclamp(position, 0.0f, 1.0f);
+ }
+
+ inline LLSettingsBase::BlendFactor convert_time_to_blend_factor(const LLSettingsBase::Seconds& time, const LLSettingsBase::Seconds& len, LLSettingsDay::CycleTrack_t &track)
+ {
+ LLSettingsBase::TrackPosition position = convert_time_to_position(time, len);
+ LLSettingsDay::TrackBound_t bounds(get_bounding_entries(track, position));
+
+ LLSettingsBase::TrackPosition spanlength(get_wrapping_distance((*bounds.first).first, (*bounds.second).first));
+ if (position < (*bounds.first).first)
+ position += 1.0;
+
+ LLSettingsBase::TrackPosition start = position - (*bounds.first).first;
+
+ return static_cast(start / spanlength);
+ }
+
+ //---------------------------------------------------------------------
+ class LLTrackBlenderLoopingTime : public LLSettingsBlenderTimeDelta
+ {
+ public:
+ LLTrackBlenderLoopingTime(const LLSettingsBase::ptr_t &target, const LLSettingsDay::ptr_t &day, S32 trackno,
+ LLSettingsBase::Seconds cyclelength, LLSettingsBase::Seconds cycleoffset, LLSettingsBase::Seconds updateThreshold) :
+ LLSettingsBlenderTimeDelta(target, LLSettingsBase::ptr_t(), LLSettingsBase::ptr_t(), LLSettingsBase::Seconds(1.0)),
+ mDay(day),
+ mTrackNo(0),
+ mCycleLength(cyclelength),
+ mCycleOffset(cycleoffset)
+ {
+ // must happen prior to getBoundingEntries call...
+ mTrackNo = selectTrackNumber(trackno);
+
+ LLSettingsBase::Seconds now(getAdjustedNow());
+ LLSettingsDay::TrackBound_t initial = getBoundingEntries(now);
+
+ mInitial = (*initial.first).second;
+ mFinal = (*initial.second).second;
+ mBlendSpan = getSpanTime(initial);
+
+ initializeTarget(now);
+ setOnFinished([this](const LLSettingsBlender::ptr_t &){ onFinishedSpan(); });
+ }
+
+ void switchTrack(S32 trackno, const LLSettingsBase::TrackPosition&) override
+ {
+ S32 use_trackno = selectTrackNumber(trackno);
+
+ if (use_trackno == mTrackNo)
+ { // results in no change
+ return;
+ }
+
+ LLSettingsBase::ptr_t pstartsetting = mTarget->buildDerivedClone();
+ mTrackNo = use_trackno;
+
+ LLSettingsBase::Seconds now = getAdjustedNow() + LLEnvironment::TRANSITION_ALTITUDE;
+ LLSettingsDay::TrackBound_t bounds = getBoundingEntries(now);
+
+ LLSettingsBase::ptr_t pendsetting = (*bounds.first).second->buildDerivedClone();
+ LLSettingsBase::TrackPosition targetpos = convert_time_to_position(now, mCycleLength) - (*bounds.first).first;
+ LLSettingsBase::TrackPosition targetspan = get_wrapping_distance((*bounds.first).first, (*bounds.second).first);
+
+ LLSettingsBase::BlendFactor blendf = calculateBlend(targetpos, targetspan);
+ pendsetting->blend((*bounds.second).second, blendf);
+
+ reset(pstartsetting, pendsetting, LLEnvironment::TRANSITION_ALTITUDE);
+ }
+
+ protected:
+ S32 selectTrackNumber(S32 trackno)
+ {
+ if (trackno == 0)
+ { // We are dealing with the water track. There is only ever one.
+ return trackno;
+ }
+
+ for (S32 test = trackno; test != 0; --test)
+ { // Find the track below the requested one with data.
+ LLSettingsDay::CycleTrack_t &track = mDay->getCycleTrack(test);
+
+ if (!track.empty())
+ return test;
+ }
+
+ return 1;
+ }
+
+ LLSettingsDay::TrackBound_t getBoundingEntries(LLSettingsBase::Seconds time)
+ {
+ LLSettingsDay::CycleTrack_t &wtrack = mDay->getCycleTrack(mTrackNo);
+ LLSettingsBase::TrackPosition position = convert_time_to_position(time, mCycleLength);
+ LLSettingsDay::TrackBound_t bounds = get_bounding_entries(wtrack, position);
+ return bounds;
+ }
+
+ void initializeTarget(LLSettingsBase::Seconds time)
+ {
+ LLSettingsBase::BlendFactor blendf(convert_time_to_blend_factor(time, mCycleLength, mDay->getCycleTrack(mTrackNo)));
+
+ blendf = llclamp(blendf, 0.0, 0.999);
+ setTimeSpent(LLSettingsBase::Seconds(blendf * mBlendSpan));
+
+ setBlendFactor(blendf);
+ }
+
+ LLSettingsBase::Seconds getAdjustedNow() const
+ {
+ LLSettingsBase::Seconds now(LLDate::now().secondsSinceEpoch());
+
+ return (now + mCycleOffset);
+ }
+
+ LLSettingsBase::Seconds getSpanTime(const LLSettingsDay::TrackBound_t &bounds) const
+ {
+ LLSettingsBase::Seconds span = mCycleLength * get_wrapping_distance((*bounds.first).first, (*bounds.second).first);
+ if (span < MINIMUM_SPANLENGTH) // for very short spans set a minimum length.
+ span = MINIMUM_SPANLENGTH;
+ return span;
+ }
+
+ private:
+ LLSettingsDay::ptr_t mDay;
+ S32 mTrackNo;
+ LLSettingsBase::Seconds mCycleLength;
+ LLSettingsBase::Seconds mCycleOffset;
+
+ void onFinishedSpan()
+ {
+ LLSettingsBase::Seconds adjusted_now = getAdjustedNow();
+ LLSettingsDay::TrackBound_t next = getBoundingEntries(adjusted_now);
+ LLSettingsBase::Seconds nextspan = getSpanTime(next);
+
+ reset((*next.first).second, (*next.second).second, nextspan);
+
+ // Recalculate (reinitialize) position. Because:
+ // - 'delta' from applyTimeDelta accumulates errors (probably should be fixed/changed to absolute time)
+ // - freezes and lag can result in reset being called too late, so we need to add missed time
+ // - occasional time corrections can happen
+ // - some transition switches can happen outside applyTimeDelta thus causing 'desync' from 'delta' (can be fixed by getting rid of delta)
+ initializeTarget(adjusted_now);
+ }
+ };
+
+ class LLEnvironmentPushDispatchHandler : public LLDispatchHandler
+ {
+ public:
+ virtual bool operator()(const LLDispatcher *, const std::string& key, const LLUUID& invoice, const sparam_t& strings) override
+ {
+ LLSD message;
+ sparam_t::const_iterator it = strings.begin();
+
+ if (it != strings.end())
+ {
+ const std::string& llsdRaw = *it++;
+ std::istringstream llsdData(llsdRaw);
+ if (!LLSDSerialize::deserialize(message, llsdData, llsdRaw.length()))
+ {
+ LL_WARNS() << "LLExperienceLogDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL;
+ }
+ }
+
+ message[KEY_EXPERIENCEID] = invoice;
+ // Object Name
+ if (it != strings.end())
+ {
+ message[KEY_OBJECTNAME] = *it++;
+ }
+
+ // parcel Name
+ if (it != strings.end())
+ {
+ message[KEY_PARCELNAME] = *it++;
+ }
+ message[KEY_COUNT] = 1;
+
+ LLEnvironment::instance().handleEnvironmentPush(message);
+ return true;
+ }
+ };
+
+ LLEnvironmentPushDispatchHandler environment_push_dispatch_handler;
+
+ template
+ class LLSettingsInjected : public SETTINGT
+ {
+ public:
+ typedef std::shared_ptr > ptr_t;
+
+ LLSettingsInjected(typename SETTINGT::ptr_t source) :
+ SETTINGT(),
+ mSource(source),
+ mLastSourceHash(0),
+ mLastHash(0)
+ {}
+
+ virtual ~LLSettingsInjected() {};
+
+ typename SETTINGT::ptr_t getSource() const { return this->mSource; }
+ void setSource(const typename SETTINGT::ptr_t &source)
+ {
+ if (source.get() == this) // do not set a source to itself.
+ return;
+ this->mSource = source;
+ this->setDirtyFlag(true);
+ this->mLastSourceHash = 0;
+ }
+
+ virtual bool isDirty() const override { return SETTINGT::isDirty() || (this->mSource->isDirty()); }
+ virtual bool isVeryDirty() const override { return SETTINGT::isVeryDirty() || (this->mSource->isVeryDirty()); }
+
+ void injectSetting(const std::string keyname, LLSD value, LLUUID experience_id, F32Seconds transition)
+ {
+ if (transition > 0.1)
+ {
+ typename Injection::ptr_t injection = std::make_shared(transition, keyname, value, true, experience_id);
+
+ mInjections.push_back(injection);
+ std::stable_sort(mInjections.begin(), mInjections.end(), [](const typename Injection::ptr_t &a, const typename Injection::ptr_t &b) { return a->mTimeRemaining < b->mTimeRemaining; });
+ }
+ else
+ {
+ mOverrideValues[keyname] = value;
+ mOverrideExps[keyname] = experience_id;
+ this->setDirtyFlag(true);
+ }
+ }
+
+ void removeInjection(const std::string keyname, LLUUID experience, LLSettingsBase::Seconds transition)
+ {
+ injections_t injections_buf;
+ for (auto it = mInjections.begin(); it != mInjections.end(); it++)
+ {
+ if ((keyname.empty() || ((*it)->mKeyName == keyname)) &&
+ (experience.isNull() || (experience == (*it)->mExperience)))
+ {
+ if (transition != LLEnvironment::TRANSITION_INSTANT)
+ {
+ typename Injection::ptr_t injection = std::make_shared(transition, keyname, (*it)->mLastValue, false, LLUUID::null);
+ injections_buf.push_front(injection);
+ }
+ }
+ else
+ {
+ injections_buf.push_front(*it);
+ }
+ }
+ mInjections.clear();
+ mInjections = injections_buf;
+
+ for (auto itexp = mOverrideExps.begin(); itexp != mOverrideExps.end();)
+ {
+ if (experience.isNull() || ((*itexp).second == experience))
+ {
+ if (transition != LLEnvironment::TRANSITION_INSTANT)
+ {
+ typename Injection::ptr_t injection = std::make_shared(transition, (*itexp).first, mOverrideValues[(*itexp).first], false, LLUUID::null);
+ mInjections.push_front(injection);
+ }
+ mOverrideValues.erase((*itexp).first);
+ mOverrideExps.erase(itexp++);
+ }
+ else
+ ++itexp;
+ }
+ std::stable_sort(mInjections.begin(), mInjections.end(), [](const typename Injection::ptr_t &a, const typename Injection::ptr_t &b) { return a->mTimeRemaining < b->mTimeRemaining; });
+ }
+
+ void removeInjections(LLUUID experience_id, LLSettingsBase::Seconds transition)
+ {
+ removeInjection(std::string(), experience_id, transition);
+ }
+
+ void injectExperienceValues(LLSD values, LLUUID experience_id, typename LLSettingsBase::Seconds transition)
+ {
+ for (auto it = values.beginMap(); it != values.endMap(); ++it)
+ {
+ injectSetting((*it).first, (*it).second, experience_id, transition);
+ }
+ this->setDirtyFlag(true);
+ }
+
+ void applyInjections(LLSettingsBase::Seconds delta)
+ {
+ this->mSettings = this->mSource->getSettings();
+
+ for (auto ito = mOverrideValues.beginMap(); ito != mOverrideValues.endMap(); ++ito)
+ {
+ this->mSettings[(*ito).first] = (*ito).second;
+ }
+
+ const LLSettingsBase::stringset_t &slerps = this->getSlerpKeys();
+ const LLSettingsBase::stringset_t &skips = this->getSkipInterpolateKeys();
+ const LLSettingsBase::stringset_t &specials = this->getSpecialKeys();
+
+ typename injections_t::iterator it;
+ for (it = mInjections.begin(); it != mInjections.end(); ++it)
+ {
+ std::string key_name = (*it)->mKeyName;
+
+ LLSD value = this->mSettings[key_name];
+ LLSD target = (*it)->mValue;
+
+ if ((*it)->mFirstTime)
+ (*it)->mFirstTime = false;
+ else
+ (*it)->mTimeRemaining -= delta;
+
+ typename LLSettingsBase::BlendFactor mix = 1.0f - ((*it)->mTimeRemaining.value() / (*it)->mTransition.value());
+
+ if (mix >= 1.0)
+ {
+ if ((*it)->mBlendIn)
+ {
+ mOverrideValues[key_name] = target;
+ mOverrideExps[key_name] = (*it)->mExperience;
+ this->mSettings[key_name] = target;
+ }
+ else
+ {
+ this->mSettings.erase(key_name);
+ }
+ }
+ else if (specials.find(key_name) != specials.end())
+ {
+ updateSpecial(*it, mix);
+ }
+ else if (skips.find(key_name) == skips.end())
+ {
+ if (!(*it)->mBlendIn)
+ mix = 1.0 - mix;
+ (*it)->mLastValue = this->interpolateSDValue(key_name, value, target, this->getParameterMap(), mix, slerps);
+ this->mSettings[key_name] = (*it)->mLastValue;
+ }
+ }
+
+ size_t hash = this->getHash();
+
+ if (hash != mLastHash)
+ {
+ this->setDirtyFlag(true);
+ mLastHash = hash;
+ }
+
+ it = mInjections.begin();
+ it = std::find_if(mInjections.begin(), mInjections.end(), [](const typename Injection::ptr_t &a) { return a->mTimeRemaining > 0.0f; });
+
+ if (it != mInjections.begin())
+ {
+ mInjections.erase(mInjections.begin(), mInjections.end());
+ }
+
+ }
+
+ bool hasInjections() const
+ {
+ return (!mInjections.empty() || (mOverrideValues.size() > 0));
+ }
+
+ protected:
+ struct Injection
+ {
+ Injection(typename LLSettingsBase::Seconds transition, const std::string &keyname, LLSD value, bool blendin, LLUUID experince, S32 index = -1) :
+ mTransition(transition),
+ mTimeRemaining(transition),
+ mKeyName(keyname),
+ mValue(value),
+ mExperience(experince),
+ mIndex(index),
+ mBlendIn(blendin),
+ mFirstTime(true)
+ {}
+
+ typename LLSettingsBase::Seconds mTransition;
+ typename LLSettingsBase::Seconds mTimeRemaining;
+ std::string mKeyName;
+ LLSD mValue;
+ LLSD mLastValue;
+ LLUUID mExperience;
+ S32 mIndex;
+ bool mBlendIn;
+ bool mFirstTime;
+
+ typedef std::shared_ptr ptr_t;
+ };
+
+
+ virtual void updateSettings() override
+ {
+ static LLFrameTimer timer;
+
+ if (!this->mSource)
+ return;
+
+ // clears the dirty flag on this object. Need to prevent triggering
+ // more calls into this updateSettings
+ LLSettingsBase::updateSettings();
+
+ resetSpecial();
+
+ if (this->mSource->isDirty())
+ {
+ this->mSource->updateSettings();
+ }
+
+ typename LLSettingsBase::Seconds delta(timer.getElapsedTimeAndResetF32());
+
+
+ SETTINGT::updateSettings();
+
+ if (!mInjections.empty())
+ this->setDirtyFlag(true);
+ }
+
+ LLSettingsBase::stringset_t getSpecialKeys() const;
+ void resetSpecial();
+ void updateSpecial(const typename Injection::ptr_t &injection, typename LLSettingsBase::BlendFactor mix);
+
+ private:
+ typedef std::map key_to_expid_t;
+ typedef std::deque injections_t;
+
+ size_t mLastSourceHash;
+ size_t mLastHash;
+ typename SETTINGT::ptr_t mSource;
+ injections_t mInjections;
+ LLSD mOverrideValues;
+ key_to_expid_t mOverrideExps;
+ };
+
+ template<>
+ LLSettingsBase::stringset_t LLSettingsInjected::getSpecialKeys() const
+ {
+ static LLSettingsBase::stringset_t specialSet;
+
+ if (specialSet.empty())
+ {
+ specialSet.insert(SETTING_BLOOM_TEXTUREID);
+ specialSet.insert(SETTING_RAINBOW_TEXTUREID);
+ specialSet.insert(SETTING_HALO_TEXTUREID);
+ specialSet.insert(SETTING_CLOUD_TEXTUREID);
+ specialSet.insert(SETTING_MOON_TEXTUREID);
+ specialSet.insert(SETTING_SUN_TEXTUREID);
+ }
+ return specialSet;
+ }
+
+ template<>
+ LLSettingsBase::stringset_t LLSettingsInjected::getSpecialKeys() const
+ {
+ static stringset_t specialSet;
+
+ if (specialSet.empty())
+ {
+ specialSet.insert(SETTING_TRANSPARENT_TEXTURE);
+ specialSet.insert(SETTING_NORMAL_MAP);
+ }
+ return specialSet;
+ }
+
+ template<>
+ void LLSettingsInjected::resetSpecial()
+ {
+ mNextSunTextureId.setNull();
+ mNextMoonTextureId.setNull();
+ mNextCloudTextureId.setNull();
+ mNextBloomTextureId.setNull();
+ mNextRainbowTextureId.setNull();
+ mNextHaloTextureId.setNull();
+ setBlendFactor(0.0f);
+ }
+
+ template<>
+ void LLSettingsInjected::resetSpecial()
+ {
+ mNextNormalMapID.setNull();
+ mNextTransparentTextureID.setNull();
+ setBlendFactor(0.0f);
+ }
+
+ template<>
+ void LLSettingsInjected::updateSpecial(const typename LLSettingsInjected::Injection::ptr_t &injection, typename LLSettingsBase::BlendFactor mix)
+ {
+ if (injection->mKeyName == SETTING_SUN_TEXTUREID)
+ {
+ mNextSunTextureId = injection->mValue.asUUID();
+ }
+ else if (injection->mKeyName == SETTING_MOON_TEXTUREID)
+ {
+ mNextMoonTextureId = injection->mValue.asUUID();
+ }
+ else if (injection->mKeyName == SETTING_CLOUD_TEXTUREID)
+ {
+ mNextCloudTextureId = injection->mValue.asUUID();
+ }
+ else if (injection->mKeyName == SETTING_BLOOM_TEXTUREID)
+ {
+ mNextBloomTextureId = injection->mValue.asUUID();
+ }
+ else if (injection->mKeyName == SETTING_RAINBOW_TEXTUREID)
+ {
+ mNextRainbowTextureId = injection->mValue.asUUID();
+ }
+ else if (injection->mKeyName == SETTING_HALO_TEXTUREID)
+ {
+ mNextHaloTextureId = injection->mValue.asUUID();
+ }
+
+ // Unfortunately I don't have a per texture blend factor. We'll just pick the one that is furthest along.
+ if (getBlendFactor() < mix)
+ {
+ setBlendFactor(mix);
+ }
+ }
+
+ template<>
+ void LLSettingsInjected::updateSpecial(const typename LLSettingsInjected::Injection::ptr_t &injection, typename LLSettingsBase::BlendFactor mix)
+ {
+ if (injection->mKeyName == SETTING_NORMAL_MAP)
+ {
+ mNextNormalMapID = injection->mValue.asUUID();
+ }
+ else if (injection->mKeyName == SETTING_TRANSPARENT_TEXTURE)
+ {
+ mNextTransparentTextureID = injection->mValue.asUUID();
+ }
+
+ // Unfortunately I don't have a per texture blend factor. We'll just pick the one that is furthest along.
+ if (getBlendFactor() < mix)
+ {
+ setBlendFactor(mix);
+ }
+ }
+
+ typedef LLSettingsInjected LLSettingsInjectedSky;
+ typedef LLSettingsInjected LLSettingsInjectedWater;
+
+ //=====================================================================
+ class DayInjection : public LLEnvironment::DayInstance
+ {
+ friend class InjectedTransition;
+
+ public:
+ typedef std::shared_ptr ptr_t;
+ typedef std::weak_ptr wptr_t;
+
+ DayInjection(LLEnvironment::EnvSelection_t env);
+ virtual ~DayInjection();
+
+ virtual bool applyTimeDelta(const LLSettingsBase::Seconds& delta) override;
+
+ void setInjectedDay(const LLSettingsDay::ptr_t &pday, LLUUID experience_id, LLSettingsBase::Seconds transition);
+ void setInjectedSky(const LLSettingsSky::ptr_t &psky, LLUUID experience_id, LLSettingsBase::Seconds transition);
+ void setInjectedWater(const LLSettingsWater::ptr_t &pwater, LLUUID experience_id, LLSettingsBase::Seconds transition);
+
+ void injectSkySettings(LLSD settings, LLUUID experience_id, LLSettingsBase::Seconds transition);
+ void injectWaterSettings(LLSD settings, LLUUID experience_id, LLSettingsBase::Seconds transition);
+
+ void clearInjections(LLUUID experience_id, LLSettingsBase::Seconds transition_time);
+
+ virtual void animate() override;
+
+ LLEnvironment::DayInstance::ptr_t getBaseDayInstance() const { return mBaseDayInstance; }
+ void setBaseDayInstance(const LLEnvironment::DayInstance::ptr_t &baseday);
+
+ S32 countExperiencesActive() const { return mActiveExperiences.size(); }
+
+ bool isOverriddenSky() const { return !mSkyExperience.isNull(); }
+ bool isOverriddenWater() const { return !mWaterExperience.isNull(); }
+
+ bool hasInjections() const;
+
+ void testExperiencesOnParcel(S32 parcel_id);
+ private:
+ static void testExperiencesOnParcelCoro(wptr_t that, S32 parcel_id);
+
+
+ void animateSkyChange(LLSettingsSky::ptr_t psky, LLSettingsBase::Seconds transition);
+ void animateWaterChange(LLSettingsWater::ptr_t pwater, LLSettingsBase::Seconds transition);
+
+ void onEnvironmentChanged(LLEnvironment::EnvSelection_t env);
+ void onParcelChange();
+
+ void checkExperience();
+
+
+ LLEnvironment::DayInstance::ptr_t mBaseDayInstance;
+
+ LLSettingsInjectedSky::ptr_t mInjectedSky;
+ LLSettingsInjectedWater::ptr_t mInjectedWater;
+ std::set mActiveExperiences;
+ LLUUID mDayExperience;
+ LLUUID mSkyExperience;
+ LLUUID mWaterExperience;
+ LLEnvironment::connection_t mEnvChangeConnection;
+ boost::signals2::connection mParcelChangeConnection;
+ };
+
+ class InjectedTransition : public LLEnvironment::DayTransition
+ {
+ public:
+ InjectedTransition(const DayInjection::ptr_t &injection, const LLSettingsSky::ptr_t &skystart, const LLSettingsWater::ptr_t &waterstart, DayInstance::ptr_t &end, LLSettingsDay::Seconds time):
+ LLEnvironment::DayTransition(skystart, waterstart, end, time),
+ mInjection(injection)
+ { }
+ virtual ~InjectedTransition() { };
+
+ virtual void animate() override;
+
+ protected:
+ DayInjection::ptr_t mInjection;
+ };
+
+}
+
+//=========================================================================
+const F32Seconds LLEnvironment::TRANSITION_INSTANT(0.0f);
+const F32Seconds LLEnvironment::TRANSITION_FAST(1.0f);
+const F32Seconds LLEnvironment::TRANSITION_DEFAULT(5.0f);
+const F32Seconds LLEnvironment::TRANSITION_SLOW(10.0f);
+const F32Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f);
+
+const LLUUID LLEnvironment::KNOWN_SKY_SUNRISE("01e41537-ff51-2f1f-8ef7-17e4df760bfb");
+const LLUUID LLEnvironment::KNOWN_SKY_MIDDAY("6c83e853-e7f8-cad7-8ee6-5f31c453721c");
+const LLUUID LLEnvironment::KNOWN_SKY_SUNSET("084e26cd-a900-28e8-08d0-64a9de5c15e2");
+const LLUUID LLEnvironment::KNOWN_SKY_MIDNIGHT("8a01b97a-cb20-c1ea-ac63-f7ea84ad0090");
+
+const S32 LLEnvironment::NO_TRACK(-1);
+const S32 LLEnvironment::NO_VERSION(-3); // For viewer sided change, like ENV_LOCAL. -3 since -1 and -2 are taken by parcel initial server/viewer version
+const S32 LLEnvironment::VERSION_CLEANUP(-4); // for cleanups
+
+const F32 LLEnvironment::SUN_DELTA_YAW(F_PI); // 180deg
+
+
+const U32 LLEnvironment::DayInstance::NO_ANIMATE_SKY(0x01);
+const U32 LLEnvironment::DayInstance::NO_ANIMATE_WATER(0x02);
+
+
+//-------------------------------------------------------------------------
+LLEnvironment::LLEnvironment():
+ mCloudScrollDelta(),
+ mCloudScrollPaused(false),
+ mSelectedSky(),
+ mSelectedWater(),
+ mSelectedDay(),
+ mSelectedEnvironment(LLEnvironment::ENV_LOCAL),
+ mCurrentTrack(1),
+ mEditorCounter(0),
+ mShowSunBeacon(false),
+ mShowMoonBeacon(false)
+{
+}
+
+void LLEnvironment::initSingleton()
+{
+ LLSettingsSky::ptr_t p_default_sky = LLSettingsVOSky::buildDefaultSky();
+ LLSettingsWater::ptr_t p_default_water = LLSettingsVOWater::buildDefaultWater();
+
+ mCurrentEnvironment = std::make_shared(ENV_DEFAULT);
+ mCurrentEnvironment->setSky(p_default_sky);
+ mCurrentEnvironment->setWater(p_default_water);
+
+ mEnvironments[ENV_DEFAULT] = mCurrentEnvironment;
+
+ requestRegion();
+
+ gAgent.addParcelChangedCallback([this]() { onParcelChange(); });
+
+ //TODO: This frequently results in one more request than we need. It isn't breaking, but should be nicer.
+ // We need to know new env version to fix this, without it we can only do full re-request
+ // Happens: on updates, on opening LLFloaterRegionInfo, on region crossing if info floater is open
+ LLRegionInfoModel::instance().setUpdateCallback([this]() { requestRegion(); });
+ gAgent.addRegionChangedCallback([this]() { onRegionChange(); });
+
+ gAgent.whenPositionChanged([this](const LLVector3 &localpos, const LLVector3d &) { onAgentPositionHasChanged(localpos); });
+
+ if (!gGenericDispatcher.isHandlerPresent(MESSAGE_PUSHENVIRONMENT))
+ {
+ gGenericDispatcher.addHandler(MESSAGE_PUSHENVIRONMENT, &environment_push_dispatch_handler);
+ }
+
+ LLEventPumps::instance().obtain(PUMP_EXPERIENCE).listen(LISTENER_NAME, [this](LLSD message) { listenExperiencePump(message); return false; });
+
+ loadFromSettings();
+}
+
+void LLEnvironment::cleanupSingleton()
+{
+ LLEventPumps::instance().obtain(PUMP_EXPERIENCE).stopListening(LISTENER_NAME);
+}
+
+LLEnvironment::~LLEnvironment()
+{
+}
+
+bool LLEnvironment::canEdit() const
+{
+ return true;
+}
+
+LLSettingsSky::ptr_t LLEnvironment::getCurrentSky() const
+{
+ LLSettingsSky::ptr_t psky = mCurrentEnvironment->getSky();
+
+ if (!psky && mCurrentEnvironment->getEnvironmentSelection() >= ENV_EDIT)
+ {
+ for (int idx = 0; idx < ENV_END; ++idx)
+ {
+ if (mEnvironments[idx]->getSky())
+ {
+ psky = mEnvironments[idx]->getSky();
+ break;
+ }
+ }
+ }
+ return psky;
+}
+
+LLSettingsWater::ptr_t LLEnvironment::getCurrentWater() const
+{
+ LLSettingsWater::ptr_t pwater = mCurrentEnvironment->getWater();
+
+ if (!pwater && mCurrentEnvironment->getEnvironmentSelection() >= ENV_EDIT)
+ {
+ for (int idx = 0; idx < ENV_END; ++idx)
+ {
+ if (mEnvironments[idx]->getWater())
+ {
+ pwater = mEnvironments[idx]->getWater();
+ break;
+ }
+ }
+ }
+ return pwater;
+}
+
+void LayerConfigToDensityLayer(const LLSD& layerConfig, DensityLayer& layerOut)
+{
+ layerOut.constant_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM].asReal();
+ layerOut.exp_scale = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR].asReal();
+ layerOut.exp_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM].asReal();
+ layerOut.linear_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM].asReal();
+ layerOut.width = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH].asReal();
+}
+
+void LLEnvironment::getAtmosphericModelSettings(AtmosphericModelSettings& settingsOut, const LLSettingsSky::ptr_t &psky)
+{
+ settingsOut.m_skyBottomRadius = psky->getSkyBottomRadius();
+ settingsOut.m_skyTopRadius = psky->getSkyTopRadius();
+ settingsOut.m_sunArcRadians = psky->getSunArcRadians();
+ settingsOut.m_mieAnisotropy = psky->getMieAnisotropy();
+
+ LLSD rayleigh = psky->getRayleighConfigs();
+ settingsOut.m_rayleighProfile.clear();
+ for (LLSD::array_iterator itf = rayleigh.beginArray(); itf != rayleigh.endArray(); ++itf)
+ {
+ DensityLayer layer;
+ LLSD& layerConfig = (*itf);
+ LayerConfigToDensityLayer(layerConfig, layer);
+ settingsOut.m_rayleighProfile.push_back(layer);
+ }
+
+ LLSD mie = psky->getMieConfigs();
+ settingsOut.m_mieProfile.clear();
+ for (LLSD::array_iterator itf = mie.beginArray(); itf != mie.endArray(); ++itf)
+ {
+ DensityLayer layer;
+ LLSD& layerConfig = (*itf);
+ LayerConfigToDensityLayer(layerConfig, layer);
+ settingsOut.m_mieProfile.push_back(layer);
+ }
+ settingsOut.m_mieAnisotropy = psky->getMieAnisotropy();
+
+ LLSD absorption = psky->getAbsorptionConfigs();
+ settingsOut.m_absorptionProfile.clear();
+ for (LLSD::array_iterator itf = absorption.beginArray(); itf != absorption.endArray(); ++itf)
+ {
+ DensityLayer layer;
+ LLSD& layerConfig = (*itf);
+ LayerConfigToDensityLayer(layerConfig, layer);
+ settingsOut.m_absorptionProfile.push_back(layer);
+ }
+}
+
+bool LLEnvironment::canAgentUpdateParcelEnvironment() const
+{
+ LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel());
+
+ return canAgentUpdateParcelEnvironment(parcel);
+}
+
+
+bool LLEnvironment::canAgentUpdateParcelEnvironment(LLParcel *parcel) const
+{
+ if (!parcel)
+ return false;
+
+ if (!LLEnvironment::instance().isExtendedEnvironmentEnabled())
+ return false;
+
+ if (gAgent.isGodlike())
+ return true;
+
+ if (!parcel->getRegionAllowEnvironmentOverride())
+ return false;
+
+ return LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_ALLOW_ENVIRONMENT);
+}
+
+bool LLEnvironment::canAgentUpdateRegionEnvironment() const
+{
+ if (gAgent.isGodlike())
+ return true;
+
+ return gAgent.getRegion()->canManageEstate();
+}
+
+bool LLEnvironment::isExtendedEnvironmentEnabled() const
+{
+ return !gAgent.getRegionCapability("ExtEnvironment").empty();
+}
+
+bool LLEnvironment::isInventoryEnabled() const
+{
+ return (!gAgent.getRegionCapability("UpdateSettingsAgentInventory").empty() &&
+ !gAgent.getRegionCapability("UpdateSettingsTaskInventory").empty());
+}
+
+void LLEnvironment::onRegionChange()
+{
+// if (gAgent.getRegionCapability("ExperienceQuery").empty())
+// {
+// // for now environmental experiences do not survive region crossings
+ clearExperienceEnvironment(LLUUID::null, TRANSITION_DEFAULT);
+// }
+
+ LLViewerRegion* cur_region = gAgent.getRegion();
+ if (!cur_region)
+ {
+ return;
+ }
+ if (!cur_region->capabilitiesReceived())
+ {
+ cur_region->setCapabilitiesReceivedCallback([](LLUUID region_id) { LLEnvironment::instance().requestRegion(); });
+ return;
+ }
+ requestRegion();
+}
+
+void LLEnvironment::onParcelChange()
+{
+ S32 parcel_id(INVALID_PARCEL_ID);
+ LLParcel* parcel = LLViewerParcelMgr::instance().getAgentParcel();
+
+ if (parcel)
+ {
+ parcel_id = parcel->getLocalID();
+ }
+
+ requestParcel(parcel_id);
+}
+
+//-------------------------------------------------------------------------
+F32 LLEnvironment::getCamHeight() const
+{
+ return (mCurrentEnvironment->getSky()->getDomeOffset() * mCurrentEnvironment->getSky()->getDomeRadius());
+}
+
+F32 LLEnvironment::getWaterHeight() const
+{
+ return gAgent.getRegion()->getWaterHeight();
+}
+
+bool LLEnvironment::getIsSunUp() const
+{
+ if (!mCurrentEnvironment || !mCurrentEnvironment->getSky())
+ return false;
+ return mCurrentEnvironment->getSky()->getIsSunUp();
+}
+
+bool LLEnvironment::getIsMoonUp() const
+{
+ if (!mCurrentEnvironment || !mCurrentEnvironment->getSky())
+ return false;
+ return mCurrentEnvironment->getSky()->getIsMoonUp();
+}
+
+//-------------------------------------------------------------------------
+void LLEnvironment::setSelectedEnvironment(LLEnvironment::EnvSelection_t env, LLSettingsBase::Seconds transition, bool forced)
+{
+ mSelectedEnvironment = env;
+ updateEnvironment(transition, forced);
+}
+
+bool LLEnvironment::hasEnvironment(LLEnvironment::EnvSelection_t env)
+{
+ if ((env < ENV_EDIT) || (env >= ENV_DEFAULT) || (!mEnvironments[env]))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+LLEnvironment::DayInstance::ptr_t LLEnvironment::getEnvironmentInstance(LLEnvironment::EnvSelection_t env, bool create /*= false*/)
+{
+ DayInstance::ptr_t environment = mEnvironments[env];
+ if (create)
+ {
+ if (environment)
+ environment = environment->clone();
+ else
+ {
+ if (env == ENV_PUSH)
+ environment = std::make_shared(env);
+ else
+ environment = std::make_shared(env);
+ }
+ mEnvironments[env] = environment;
+ }
+
+ return environment;
+}
+
+
+void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, S32 env_version)
+{
+ if ((env < ENV_EDIT) || (env >= ENV_DEFAULT))
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to change invalid environment selection." << LL_ENDL;
+ return;
+ }
+
+ DayInstance::ptr_t environment = getEnvironmentInstance(env, true);
+
+ environment->clear();
+ environment->setDay(pday, daylength, dayoffset);
+ environment->setSkyTrack(mCurrentTrack);
+ environment->animate();
+
+ if (!mSignalEnvChanged.empty())
+ mSignalEnvChanged(env, env_version);
+}
+
+
+void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironment::fixedEnvironment_t fixed, S32 env_version)
+{
+ if ((env < ENV_EDIT) || (env >= ENV_DEFAULT))
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to change invalid environment selection." << LL_ENDL;
+ return;
+ }
+
+ DayInstance::ptr_t environment = getEnvironmentInstance(env, true);
+
+
+ if (fixed.first)
+ {
+ environment->setSky(fixed.first);
+ environment->setFlags(DayInstance::NO_ANIMATE_SKY);
+ }
+ else if (!environment->getSky())
+ {
+ environment->setSky(mCurrentEnvironment->getSky());
+ environment->setFlags(DayInstance::NO_ANIMATE_SKY);
+ }
+
+ if (fixed.second)
+ {
+ environment->setWater(fixed.second);
+ environment->setFlags(DayInstance::NO_ANIMATE_WATER);
+ }
+ else if (!environment->getWater())
+ {
+ environment->setWater(mCurrentEnvironment->getWater());
+ environment->setFlags(DayInstance::NO_ANIMATE_WATER);
+ }
+
+ if (!mSignalEnvChanged.empty())
+ mSignalEnvChanged(env, env_version);
+
+ /*TODO: readjust environment*/
+}
+
+void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsBase::ptr_t &settings, S32 env_version)
+{
+ DayInstance::ptr_t environment = getEnvironmentInstance(env);
+
+ if (env == ENV_DEFAULT)
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to set default environment. Not allowed." << LL_ENDL;
+ return;
+ }
+
+ if (!settings)
+ {
+ clearEnvironment(env);
+ return;
+ }
+
+ if (settings->getSettingsType() == "daycycle")
+ {
+ LLSettingsDay::Seconds daylength(LLSettingsDay::DEFAULT_DAYLENGTH);
+ LLSettingsDay::Seconds dayoffset(LLSettingsDay::DEFAULT_DAYOFFSET);
+ if (environment)
+ {
+ daylength = environment->getDayLength();
+ dayoffset = environment->getDayOffset();
+ }
+ setEnvironment(env, std::static_pointer_cast(settings), daylength, dayoffset);
+ }
+ else if (settings->getSettingsType() == "sky")
+ {
+ fixedEnvironment_t fixedenv(std::static_pointer_cast(settings), LLSettingsWater::ptr_t());
+ setEnvironment(env, fixedenv);
+ }
+ else if (settings->getSettingsType() == "water")
+ {
+ fixedEnvironment_t fixedenv(LLSettingsSky::ptr_t(), std::static_pointer_cast(settings));
+ setEnvironment(env, fixedenv);
+ }
+}
+
+void LLEnvironment::setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version)
+{
+ setEnvironment(env, assetId, LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET);
+}
+
+
+void LLEnvironment::setEnvironment(EnvSelection_t env,
+ const LLUUID &assetId,
+ LLSettingsDay::Seconds daylength,
+ LLSettingsDay::Seconds dayoffset,
+ S32 env_version)
+{
+ LLSettingsVOBase::getSettingsAsset(assetId,
+ [this, env, daylength, dayoffset, env_version](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)
+ {
+ onSetEnvAssetLoaded(env, asset_id, settings, daylength, dayoffset, TRANSITION_DEFAULT, status, env_version);
+ });
+}
+
+void LLEnvironment::onSetEnvAssetLoaded(EnvSelection_t env,
+ LLUUID asset_id,
+ LLSettingsBase::ptr_t settings,
+ LLSettingsDay::Seconds daylength,
+ LLSettingsDay::Seconds dayoffset,
+ LLSettingsBase::Seconds transition,
+ S32 status,
+ S32 env_version)
+{
+ if (!settings || status)
+ {
+ LLSD args;
+ args["DESC"] = asset_id.asString();
+ LLNotificationsUtil::add("FailedToFindSettings", args);
+ return;
+ }
+
+ setEnvironment(env, settings);
+ updateEnvironment(transition);
+}
+
+void LLEnvironment::clearEnvironment(LLEnvironment::EnvSelection_t env)
+{
+ if ((env < ENV_EDIT) || (env >= ENV_DEFAULT))
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to change invalid environment selection." << LL_ENDL;
+ return;
+ }
+
+ mEnvironments[env].reset();
+
+ if (!mSignalEnvChanged.empty())
+ mSignalEnvChanged(env, VERSION_CLEANUP);
+
+ /*TODO: readjust environment*/
+}
+
+LLSettingsDay::ptr_t LLEnvironment::getEnvironmentDay(LLEnvironment::EnvSelection_t env)
+{
+ if ((env < ENV_EDIT) || (env > ENV_DEFAULT))
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection." << LL_ENDL;
+ return LLSettingsDay::ptr_t();
+ }
+
+ DayInstance::ptr_t environment = getEnvironmentInstance(env);
+
+ if (environment)
+ return environment->getDayCycle();
+
+ return LLSettingsDay::ptr_t();
+}
+
+LLSettingsDay::Seconds LLEnvironment::getEnvironmentDayLength(EnvSelection_t env)
+{
+ if ((env < ENV_EDIT) || (env > ENV_DEFAULT))
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection." << LL_ENDL;
+ return LLSettingsDay::Seconds(0);
+ }
+
+ DayInstance::ptr_t environment = getEnvironmentInstance(env);
+
+ if (environment)
+ return environment->getDayLength();
+
+ return LLSettingsDay::Seconds(0);
+}
+
+LLSettingsDay::Seconds LLEnvironment::getEnvironmentDayOffset(EnvSelection_t env)
+{
+ if ((env < ENV_EDIT) || (env > ENV_DEFAULT))
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection." << LL_ENDL;
+ return LLSettingsDay::Seconds(0);
+ }
+
+ DayInstance::ptr_t environment = getEnvironmentInstance(env);
+ if (environment)
+ return environment->getDayOffset();
+
+ return LLSettingsDay::Seconds(0);
+}
+
+
+LLEnvironment::fixedEnvironment_t LLEnvironment::getEnvironmentFixed(LLEnvironment::EnvSelection_t env, bool resolve)
+{
+ if ((env == ENV_CURRENT) || resolve)
+ {
+ fixedEnvironment_t fixed;
+ for (S32 idx = ((resolve) ? env : mSelectedEnvironment); idx < ENV_END; ++idx)
+ {
+ if (fixed.first && fixed.second)
+ break;
+
+ if (idx == ENV_EDIT)
+ continue; // skip the edit environment.
+
+ DayInstance::ptr_t environment = getEnvironmentInstance(static_cast(idx));
+ if (environment)
+ {
+ if (!fixed.first)
+ fixed.first = environment->getSky();
+ if (!fixed.second)
+ fixed.second = environment->getWater();
+ }
+ }
+
+ if (!fixed.first || !fixed.second)
+ LL_WARNS("ENVIRONMENT") << "Can not construct complete fixed environment. Missing Sky and/or Water." << LL_ENDL;
+
+ return fixed;
+ }
+
+ if ((env < ENV_EDIT) || (env > ENV_DEFAULT))
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection." << LL_ENDL;
+ return fixedEnvironment_t();
+ }
+
+ DayInstance::ptr_t environment = getEnvironmentInstance(env);
+
+ if (environment)
+ return fixedEnvironment_t(environment->getSky(), environment->getWater());
+
+ return fixedEnvironment_t();
+}
+
+LLEnvironment::DayInstance::ptr_t LLEnvironment::getSelectedEnvironmentInstance()
+{
+ for (S32 idx = mSelectedEnvironment; idx < ENV_DEFAULT; ++idx)
+ {
+ if (mEnvironments[idx])
+ return mEnvironments[idx];
+ }
+
+ return mEnvironments[ENV_DEFAULT];
+}
+
+LLEnvironment::DayInstance::ptr_t LLEnvironment::getSharedEnvironmentInstance()
+{
+ for (S32 idx = ENV_PARCEL; idx < ENV_DEFAULT; ++idx)
+ {
+ if (mEnvironments[idx])
+ return mEnvironments[idx];
+ }
+
+ return mEnvironments[ENV_DEFAULT];
+}
+
+void LLEnvironment::updateEnvironment(LLSettingsBase::Seconds transition, bool forced)
+{
+ DayInstance::ptr_t pinstance = getSelectedEnvironmentInstance();
+
+ if ((mCurrentEnvironment != pinstance) || forced)
+ {
+ if (transition != TRANSITION_INSTANT)
+ {
+ DayInstance::ptr_t trans = std::make_shared(
+ mCurrentEnvironment->getSky(), mCurrentEnvironment->getWater(), pinstance, transition);
+
+ trans->animate();
+
+ mCurrentEnvironment = trans;
+ }
+ else
+ {
+ mCurrentEnvironment = pinstance;
+ }
+ }
+}
+
+LLVector4 LLEnvironment::toCFR(const LLVector3 vec) const
+{
+ LLVector4 vec_cfr(vec.mV[1], vec.mV[0], vec.mV[2], 0.0f);
+ return vec_cfr;
+}
+
+LLVector4 LLEnvironment::toLightNorm(const LLVector3 vec) const
+{
+ LLVector4 vec_ogl(vec.mV[1], vec.mV[2], vec.mV[0], 0.0f);
+ return vec_ogl;
+}
+
+LLVector3 LLEnvironment::getLightDirection() const
+{
+ LLSettingsSky::ptr_t psky = mCurrentEnvironment->getSky();
+ if (!psky)
+ {
+ return LLVector3(0, 0, 1);
+ }
+ return psky->getLightDirection();
+}
+
+LLVector3 LLEnvironment::getSunDirection() const
+{
+ LLSettingsSky::ptr_t psky = mCurrentEnvironment->getSky();
+ if (!psky)
+ {
+ return LLVector3(0, 0, 1);
+ }
+ return psky->getSunDirection();
+}
+
+LLVector3 LLEnvironment::getMoonDirection() const
+{
+ LLSettingsSky::ptr_t psky = mCurrentEnvironment->getSky();
+ if (!psky)
+ {
+ return LLVector3(0, 0, -1);
+ }
+ return psky->getMoonDirection();
+}
+
+LLVector4 LLEnvironment::getLightDirectionCFR() const
+{
+ LLVector3 light_direction = getLightDirection();
+ LLVector4 light_direction_cfr = toCFR(light_direction);
+ return light_direction_cfr;
+}
+
+LLVector4 LLEnvironment::getSunDirectionCFR() const
+{
+ LLVector3 light_direction = getSunDirection();
+ LLVector4 light_direction_cfr = toCFR(light_direction);
+ return light_direction_cfr;
+}
+
+LLVector4 LLEnvironment::getMoonDirectionCFR() const
+{
+ LLVector3 light_direction = getMoonDirection();
+ LLVector4 light_direction_cfr = toCFR(light_direction);
+ return light_direction_cfr;
+}
+
+LLVector4 LLEnvironment::getClampedLightNorm() const
+{
+ LLVector3 light_direction = getLightDirection();
+ if (light_direction.mV[2] < -0.1f)
+ {
+ light_direction.mV[2] = -0.1f;
+ }
+ return toLightNorm(light_direction);
+}
+
+LLVector4 LLEnvironment::getClampedSunNorm() const
+{
+ LLVector3 light_direction = getSunDirection();
+ if (light_direction.mV[2] < -0.1f)
+ {
+ light_direction.mV[2] = -0.1f;
+ }
+ return toLightNorm(light_direction);
+}
+
+LLVector4 LLEnvironment::getClampedMoonNorm() const
+{
+ LLVector3 light_direction = getMoonDirection();
+ if (light_direction.mV[2] < -0.1f)
+ {
+ light_direction.mV[2] = -0.1f;
+ }
+ return toLightNorm(light_direction);
+}
+
+LLVector4 LLEnvironment::getRotatedLightNorm() const
+{
+ LLVector3 light_direction = getLightDirection();
+ light_direction *= LLQuaternion(-mLastCamYaw, LLVector3(0.f, 1.f, 0.f));
+ return toLightNorm(light_direction);
+}
+
+//-------------------------------------------------------------------------
+void LLEnvironment::update(const LLViewerCamera * cam)
+{
+ LL_RECORD_BLOCK_TIME(FTM_ENVIRONMENT_UPDATE);
+ //F32Seconds now(LLDate::now().secondsSinceEpoch());
+ static LLFrameTimer timer;
+
+ F32Seconds delta(timer.getElapsedTimeAndResetF32());
+
+ {
+ DayInstance::ptr_t keeper = mCurrentEnvironment;
+ // make sure the current environment does not go away until applyTimeDelta is done.
+ mCurrentEnvironment->applyTimeDelta(delta);
+
+ }
+ // update clouds, sun, and general
+ updateCloudScroll();
+
+ // cache this for use in rotating the rotated light vec for shader param updates later...
+ mLastCamYaw = cam->getYaw() + SUN_DELTA_YAW;
+
+ stop_glerror();
+
+ // *TODO: potential optimization - this block may only need to be
+ // executed some of the time. For example for water shaders only.
+ {
+ LLViewerShaderMgr::shader_iter shaders_iter, end_shaders;
+ end_shaders = LLViewerShaderMgr::instance()->endShaders();
+ for (shaders_iter = LLViewerShaderMgr::instance()->beginShaders(); shaders_iter != end_shaders; ++shaders_iter)
+ {
+ if ((shaders_iter->mProgramObject != 0)
+ && (gPipeline.canUseWindLightShaders()
+ || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER))
+ {
+ shaders_iter->mUniformsDirty = TRUE;
+ }
+ }
+ }
+}
+
+void LLEnvironment::updateCloudScroll()
+{
+ // This is a function of the environment rather than the sky, since it should
+ // persist through sky transitions.
+ static LLTimer s_cloud_timer;
+
+ F64 delta_t = s_cloud_timer.getElapsedTimeAndResetF64();
+
+ if (mCurrentEnvironment->getSky() && !mCloudScrollPaused)
+ {
+ LLVector2 cloud_delta = static_cast(delta_t)* (mCurrentEnvironment->getSky()->getCloudScrollRate()) / 100.0;
+ mCloudScrollDelta += cloud_delta;
+ }
+
+}
+
+// static
+void LLEnvironment::updateGLVariablesForSettings(LLGLSLShader *shader, const LLSettingsBase::ptr_t &psetting)
+{
+ LL_RECORD_BLOCK_TIME(FTM_SHADER_PARAM_UPDATE);
+
+ //_WARNS("RIDER") << "----------------------------------------------------------------" << LL_ENDL;
+ LLSettingsBase::parammapping_t params = psetting->getParameterMap();
+ for (auto &it: params)
+ {
+ LLSD value;
+ // legacy first since it contains ambient color and we prioritize value from legacy, see getAmbientColor()
+ if (psetting->mSettings.has(LLSettingsSky::SETTING_LEGACY_HAZE) && psetting->mSettings[LLSettingsSky::SETTING_LEGACY_HAZE].has(it.first))
+ {
+ value = psetting->mSettings[LLSettingsSky::SETTING_LEGACY_HAZE][it.first];
+ }
+ else if (psetting->mSettings.has(it.first))
+ {
+ value = psetting->mSettings[it.first];
+ }
+ else
+ {
+ // We need to reset shaders, use defaults
+ value = it.second.getDefaultValue();
+ }
+
+ LLSD::Type setting_type = value.type();
+ stop_glerror();
+ switch (setting_type)
+ {
+ case LLSD::TypeInteger:
+ shader->uniform1i(it.second.getShaderKey(), value.asInteger());
+ //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL;
+ break;
+ case LLSD::TypeReal:
+ shader->uniform1f(it.second.getShaderKey(), value.asReal());
+ //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL;
+ break;
+
+ case LLSD::TypeBoolean:
+ shader->uniform1i(it.second.getShaderKey(), value.asBoolean() ? 1 : 0);
+ //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL;
+ break;
+
+ case LLSD::TypeArray:
+ {
+ LLVector4 vect4(value);
+ //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << vect4 << LL_ENDL;
+ shader->uniform4fv(it.second.getShaderKey(), 1, vect4.mV);
+ break;
+ }
+
+ // case LLSD::TypeMap:
+ // case LLSD::TypeString:
+ // case LLSD::TypeUUID:
+ // case LLSD::TypeURI:
+ // case LLSD::TypeBinary:
+ // case LLSD::TypeDate:
+ default:
+ break;
+ }
+ stop_glerror();
+ }
+ //_WARNS("RIDER") << "----------------------------------------------------------------" << LL_ENDL;
+
+ psetting->applySpecial(shader);
+}
+
+void LLEnvironment::updateShaderUniforms(LLGLSLShader *shader)
+{
+ updateGLVariablesForSettings(shader, mCurrentEnvironment->getWater());
+ updateGLVariablesForSettings(shader, mCurrentEnvironment->getSky());
+}
+
+void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envinfo, LLSettingsBase::Seconds transition)
+{
+ if (envinfo->mParcelId == INVALID_PARCEL_ID)
+ {
+ // the returned info applies to an entire region.
+ if (!envinfo->mDayCycle)
+ {
+ clearEnvironment(ENV_PARCEL);
+ setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET, envinfo->mEnvVersion);
+ updateEnvironment();
+ }
+ else if (envinfo->mDayCycle->isTrackEmpty(LLSettingsDay::TRACK_WATER)
+ || envinfo->mDayCycle->isTrackEmpty(LLSettingsDay::TRACK_GROUND_LEVEL))
+ {
+ LL_WARNS("ENVIRONMENT") << "Invalid day cycle for region" << LL_ENDL;
+ clearEnvironment(ENV_PARCEL);
+ setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET, envinfo->mEnvVersion);
+ updateEnvironment();
+ }
+ else
+ {
+ setEnvironment(ENV_REGION, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset, envinfo->mEnvVersion);
+ mTrackAltitudes = envinfo->mAltitudes;
+ }
+
+ LL_DEBUGS("ENVIRONMENT") << "Altitudes set to {" << mTrackAltitudes[0] << ", "<< mTrackAltitudes[1] << ", " << mTrackAltitudes[2] << ", " << mTrackAltitudes[3] << LL_ENDL;
+ }
+ else
+ {
+ LLParcel *parcel = LLViewerParcelMgr::instance().getAgentParcel();
+ LL_DEBUGS("ENVIRONMENT") << "Have parcel environment #" << envinfo->mParcelId << LL_ENDL;
+ if (parcel && (parcel->getLocalID() != parcel_id))
+ {
+ LL_DEBUGS("ENVIRONMENT") << "Requested parcel #" << parcel_id << " agent is on " << parcel->getLocalID() << LL_ENDL;
+ return;
+ }
+
+ if (!envinfo->mDayCycle)
+ {
+ LL_DEBUGS("ENVIRONMENT") << "Clearing environment on parcel #" << parcel_id << LL_ENDL;
+ clearEnvironment(ENV_PARCEL);
+ }
+ else if (envinfo->mDayCycle->isTrackEmpty(LLSettingsDay::TRACK_WATER)
+ || envinfo->mDayCycle->isTrackEmpty(LLSettingsDay::TRACK_GROUND_LEVEL))
+ {
+ LL_WARNS("ENVIRONMENT") << "Invalid day cycle for parcel #" << parcel_id << LL_ENDL;
+ clearEnvironment(ENV_PARCEL);
+ }
+ else
+ {
+ setEnvironment(ENV_PARCEL, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset, envinfo->mEnvVersion);
+ }
+ }
+
+ updateEnvironment(transition);
+}
+
+void LLEnvironment::adjustRegionOffset(F32 adjust)
+{
+ if (isExtendedEnvironmentEnabled())
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to adjust region offset on EEP region. Legacy regions only." << LL_ENDL;
+ }
+
+ if (mEnvironments[ENV_REGION])
+ {
+ F32 day_length = mEnvironments[ENV_REGION]->getDayLength();
+ F32 day_offset = mEnvironments[ENV_REGION]->getDayOffset();
+
+ F32 day_adjustment = adjust * day_length;
+
+ day_offset += day_adjustment;
+ if (day_offset < 0.0f)
+ day_offset = day_length + day_offset;
+ mEnvironments[ENV_REGION]->setDayOffset(LLSettingsBase::Seconds(day_offset));
+ }
+}
+
+//=========================================================================
+void LLEnvironment::requestRegion(environment_apply_fn cb)
+{
+ requestParcel(INVALID_PARCEL_ID, cb);
+}
+
+void LLEnvironment::updateRegion(const LLSettingsDay::ptr_t &pday, S32 day_length, S32 day_offset, LLEnvironment::altitudes_vect_t altitudes, environment_apply_fn cb)
+{
+ updateParcel(INVALID_PARCEL_ID, pday, day_length, day_offset, altitudes, cb);
+}
+
+void LLEnvironment::updateRegion(const LLUUID &asset_id, std::string display_name, S32 track_num, S32 day_length, S32 day_offset, U32 flags, LLEnvironment::altitudes_vect_t altitudes, environment_apply_fn cb)
+{
+ if (!isExtendedEnvironmentEnabled())
+ {
+ LL_WARNS("ENVIRONMENT") << "attempt to apply asset id to region not supporting it." << LL_ENDL;
+ LLNotificationsUtil::add("NoEnvironmentSettings");
+ return;
+ }
+
+ updateParcel(INVALID_PARCEL_ID, asset_id, display_name, track_num, day_length, day_offset, flags, altitudes, cb);
+}
+
+void LLEnvironment::updateRegion(const LLSettingsSky::ptr_t &psky, S32 day_length, S32 day_offset, LLEnvironment::altitudes_vect_t altitudes, environment_apply_fn cb)
+{
+ updateParcel(INVALID_PARCEL_ID, psky, day_length, day_offset, altitudes, cb);
+}
+
+void LLEnvironment::updateRegion(const LLSettingsWater::ptr_t &pwater, S32 day_length, S32 day_offset, LLEnvironment::altitudes_vect_t altitudes, environment_apply_fn cb)
+{
+ updateParcel(INVALID_PARCEL_ID, pwater, day_length, day_offset, altitudes, cb);
+}
+
+
+void LLEnvironment::resetRegion(environment_apply_fn cb)
+{
+ resetParcel(INVALID_PARCEL_ID, cb);
+}
+
+void LLEnvironment::requestParcel(S32 parcel_id, environment_apply_fn cb)
+{
+ if (!isExtendedEnvironmentEnabled())
+ { /*TODO: When EEP is live on the entire grid, this can go away. */
+ if (parcel_id == INVALID_PARCEL_ID)
+ {
+ if (!cb)
+ {
+ LLSettingsBase::Seconds transition = LLViewerParcelMgr::getInstance()->getTeleportInProgress() ? TRANSITION_FAST : TRANSITION_DEFAULT;
+ cb = [this, transition](S32 pid, EnvironmentInfo::ptr_t envinfo)
+ {
+ clearEnvironment(ENV_PARCEL);
+ recordEnvironment(pid, envinfo, transition);
+ };
+ }
+
+ LLEnvironmentRequest::initiate(cb);
+ }
+ else if (cb)
+ cb(parcel_id, EnvironmentInfo::ptr_t());
+ return;
+ }
+
+ if (!cb)
+ {
+ LLSettingsBase::Seconds transition = LLViewerParcelMgr::getInstance()->getTeleportInProgress() ? TRANSITION_FAST : TRANSITION_DEFAULT;
+ cb = [this, transition](S32 pid, EnvironmentInfo::ptr_t envinfo) { recordEnvironment(pid, envinfo, transition); };
+ }
+
+ std::string coroname =
+ LLCoros::instance().launch("LLEnvironment::coroRequestEnvironment",
+ [this, parcel_id, cb]() { coroRequestEnvironment(parcel_id, cb); });
+}
+
+void LLEnvironment::updateParcel(S32 parcel_id, const LLUUID &asset_id, std::string display_name, S32 track_num, S32 day_length, S32 day_offset, U32 flags, LLEnvironment::altitudes_vect_t altitudes, environment_apply_fn cb)
+{
+ UpdateInfo::ptr_t updates(std::make_shared(asset_id, display_name, day_length, day_offset, altitudes, flags));
+ std::string coroname =
+ LLCoros::instance().launch("LLEnvironment::coroUpdateEnvironment",
+ [this, parcel_id, track_num, updates, cb]() { coroUpdateEnvironment(parcel_id, track_num, updates, cb); });
+}
+
+void LLEnvironment::onUpdateParcelAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 parcel_id, S32 day_length, S32 day_offset, LLEnvironment::altitudes_vect_t altitudes)
+{
+ if (status)
+ {
+ LL_WARNS("ENVIRONMENT") << "Unable to get settings asset with id " << asset_id << "!" << LL_ENDL;
+ LLNotificationsUtil::add("FailedToLoadSettingsApply");
+ return;
+ }
+
+ LLSettingsDay::ptr_t pday;
+
+ if (settings->getSettingsType() == "daycycle")
+ pday = std::static_pointer_cast(settings);
+ else
+ {
+ pday = createDayCycleFromEnvironment( (parcel_id == INVALID_PARCEL_ID) ? ENV_REGION : ENV_PARCEL, settings);
+ }
+
+ if (!pday)
+ {
+ LL_WARNS("ENVIRONMENT") << "Unable to construct day around " << asset_id << "!" << LL_ENDL;
+ LLNotificationsUtil::add("FailedToBuildSettingsDay");
+ return;
+ }
+
+ updateParcel(parcel_id, pday, day_length, day_offset, altitudes);
+}
+
+void LLEnvironment::updateParcel(S32 parcel_id, const LLSettingsSky::ptr_t &psky, S32 day_length, S32 day_offset, LLEnvironment::altitudes_vect_t altitudes, environment_apply_fn cb)
+{
+ LLSettingsDay::ptr_t pday = createDayCycleFromEnvironment((parcel_id == INVALID_PARCEL_ID) ? ENV_REGION : ENV_PARCEL, psky);
+ pday->setFlag(psky->getFlags());
+ updateParcel(parcel_id, pday, day_length, day_offset, altitudes, cb);
+}
+
+void LLEnvironment::updateParcel(S32 parcel_id, const LLSettingsWater::ptr_t &pwater, S32 day_length, S32 day_offset, LLEnvironment::altitudes_vect_t altitudes, environment_apply_fn cb)
+{
+ LLSettingsDay::ptr_t pday = createDayCycleFromEnvironment((parcel_id == INVALID_PARCEL_ID) ? ENV_REGION : ENV_PARCEL, pwater);
+ pday->setFlag(pwater->getFlags());
+ updateParcel(parcel_id, pday, day_length, day_offset, altitudes, cb);
+}
+
+void LLEnvironment::updateParcel(S32 parcel_id, const LLSettingsDay::ptr_t &pday, S32 track_num, S32 day_length, S32 day_offset, LLEnvironment::altitudes_vect_t altitudes, environment_apply_fn cb)
+{
+ UpdateInfo::ptr_t updates(std::make_shared(pday, day_length, day_offset, altitudes));
+
+ std::string coroname =
+ LLCoros::instance().launch("LLEnvironment::coroUpdateEnvironment",
+ [this, parcel_id, track_num, updates, cb]() { coroUpdateEnvironment(parcel_id, track_num, updates, cb); });
+}
+
+void LLEnvironment::updateParcel(S32 parcel_id, const LLSettingsDay::ptr_t &pday, S32 day_length, S32 day_offset, LLEnvironment::altitudes_vect_t altitudes, environment_apply_fn cb)
+{
+ updateParcel(parcel_id, pday, NO_TRACK, day_length, day_offset, altitudes, cb);
+}
+
+
+
+void LLEnvironment::resetParcel(S32 parcel_id, environment_apply_fn cb)
+{
+ std::string coroname =
+ LLCoros::instance().launch("LLEnvironment::coroResetEnvironment",
+ [this, parcel_id, cb]() { coroResetEnvironment(parcel_id, NO_TRACK, cb); });
+}
+
+void LLEnvironment::coroRequestEnvironment(S32 parcel_id, LLEnvironment::environment_apply_fn apply)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("ResetEnvironment", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ std::string url = gAgent.getRegionCapability("ExtEnvironment");
+ if (url.empty())
+ return;
+
+ LL_DEBUGS("ENVIRONMENT") << "Requesting for parcel_id=" << parcel_id << LL_ENDL;
+
+ if (parcel_id != INVALID_PARCEL_ID)
+ {
+ std::stringstream query;
+
+ query << "?parcelid=" << parcel_id;
+ url += query.str();
+ }
+
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
+ // results that come back may contain the new settings
+
+ LLSD httpResults = result["http_result"];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ if (!status)
+ {
+ LL_WARNS("ENVIRONMENT") << "Couldn't retrieve environment settings for " << ((parcel_id == INVALID_PARCEL_ID) ? ("region!") : ("parcel!")) << LL_ENDL;
+ }
+ else
+ {
+ LLSD environment = result[KEY_ENVIRONMENT];
+ if (environment.isDefined() && apply)
+ {
+ EnvironmentInfo::ptr_t envinfo = LLEnvironment::EnvironmentInfo::extract(environment);
+ apply(parcel_id, envinfo);
+ }
+ }
+
+}
+
+void LLEnvironment::coroUpdateEnvironment(S32 parcel_id, S32 track_no, UpdateInfo::ptr_t updates, environment_apply_fn apply)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("ResetEnvironment", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ std::string url = gAgent.getRegionCapability("ExtEnvironment");
+ if (url.empty())
+ return;
+
+ LLSD body(LLSD::emptyMap());
+ body[KEY_ENVIRONMENT] = LLSD::emptyMap();
+
+ if (track_no == NO_TRACK)
+ { // day length and offset are only applicable if we are addressing the entire day cycle.
+ if (updates->mDayLength > 0)
+ body[KEY_ENVIRONMENT][KEY_DAYLENGTH] = updates->mDayLength;
+ if (updates->mDayOffset > 0)
+ body[KEY_ENVIRONMENT][KEY_DAYOFFSET] = updates->mDayOffset;
+
+ if ((parcel_id == INVALID_PARCEL_ID) && (updates->mAltitudes.size() == 3))
+ { // only test for altitude changes if we are changing the region.
+ body[KEY_ENVIRONMENT][KEY_TRACKALTS] = LLSD::emptyArray();
+ for (S32 i = 0; i < 3; ++i)
+ {
+ body[KEY_ENVIRONMENT][KEY_TRACKALTS][i] = updates->mAltitudes[i];
+ }
+ }
+ }
+
+ if (updates->mDayp)
+ body[KEY_ENVIRONMENT][KEY_DAYCYCLE] = updates->mDayp->getSettings();
+ else if (!updates->mSettingsAsset.isNull())
+ {
+ body[KEY_ENVIRONMENT][KEY_DAYASSET] = updates->mSettingsAsset;
+ if (!updates->mDayName.empty())
+ body[KEY_ENVIRONMENT][KEY_DAYNAME] = updates->mDayName;
+ }
+
+ body[KEY_ENVIRONMENT][KEY_FLAGS] = LLSD::Integer(updates->mFlags);
+ //_WARNS("ENVIRONMENT") << "Body = " << body << LL_ENDL;
+
+ if ((parcel_id != INVALID_PARCEL_ID) || (track_no != NO_TRACK))
+ {
+ std::stringstream query;
+ query << "?";
+
+ if (parcel_id != INVALID_PARCEL_ID)
+ {
+ query << "parcelid=" << parcel_id;
+
+ if (track_no != NO_TRACK)
+ query << "&";
+ }
+ if (track_no != NO_TRACK)
+ {
+ query << "trackno=" << track_no;
+ }
+ url += query.str();
+ }
+
+ LLSD result = httpAdapter->putAndSuspend(httpRequest, url, body);
+ // results that come back may contain the new settings
+
+ LLSD notify;
+
+ LLSD httpResults = result["http_result"];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if ((!status) || !result["success"].asBoolean())
+ {
+ LL_WARNS("ENVIRONMENT") << "Couldn't update Windlight settings for " << ((parcel_id == INVALID_PARCEL_ID) ? ("region!") : ("parcel!")) << LL_ENDL;
+
+ notify = LLSD::emptyMap();
+ notify["FAIL_REASON"] = result["message"].asString();
+ }
+ else
+ {
+ LLSD environment = result[KEY_ENVIRONMENT];
+ if (environment.isDefined() && apply)
+ {
+ EnvironmentInfo::ptr_t envinfo = LLEnvironment::EnvironmentInfo::extract(environment);
+ apply(parcel_id, envinfo);
+ }
+ }
+
+ if (!notify.isUndefined())
+ {
+ LLNotificationsUtil::add("WLRegionApplyFail", notify);
+ //LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false);
+ }
+}
+
+void LLEnvironment::coroResetEnvironment(S32 parcel_id, S32 track_no, environment_apply_fn apply)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("ResetEnvironment", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ std::string url = gAgent.getRegionCapability("ExtEnvironment");
+ if (url.empty())
+ return;
+
+ if ((parcel_id != INVALID_PARCEL_ID) || (track_no != NO_TRACK))
+ {
+ std::stringstream query;
+ query << "?";
+
+ if (parcel_id != INVALID_PARCEL_ID)
+ {
+ query << "parcelid=" << parcel_id;
+
+ if (track_no != NO_TRACK)
+ query << "&";
+ }
+ if (track_no != NO_TRACK)
+ {
+ query << "trackno=" << track_no;
+ }
+ url += query.str();
+ }
+
+ LLSD result = httpAdapter->deleteAndSuspend(httpRequest, url);
+ // results that come back may contain the new settings
+
+ LLSD notify;
+
+ LLSD httpResults = result["http_result"];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if ((!status) || !result["success"].asBoolean())
+ {
+ LL_WARNS("ENVIRONMENT") << "Couldn't reset Windlight settings in " << ((parcel_id == INVALID_PARCEL_ID) ? ("region!") : ("parcel!")) << LL_ENDL;
+
+ notify = LLSD::emptyMap();
+ notify["FAIL_REASON"] = result["message"].asString();
+ }
+ else
+ {
+ LLSD environment = result[KEY_ENVIRONMENT];
+ if (environment.isDefined() && apply)
+ {
+ EnvironmentInfo::ptr_t envinfo = LLEnvironment::EnvironmentInfo::extract(environment);
+ apply(parcel_id, envinfo);
+ }
+ }
+
+ if (!notify.isUndefined())
+ {
+ LLNotificationsUtil::add("WLRegionApplyFail", notify);
+ //LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false);
+ }
+
+}
+
+
+//=========================================================================
+
+LLEnvironment::EnvironmentInfo::EnvironmentInfo():
+ mParcelId(INVALID_PARCEL_ID),
+ mRegionId(),
+ mDayLength(0),
+ mDayOffset(0),
+ mDayHash(0),
+ mDayCycle(),
+ mAltitudes({ { 0.0, 0.0, 0.0, 0.0 } }),
+ mIsDefault(false),
+ mIsLegacy(false),
+ mDayCycleName(),
+ mNameList(),
+ mEnvVersion(INVALID_PARCEL_ENVIRONMENT_VERSION)
+{
+}
+
+LLEnvironment::EnvironmentInfo::ptr_t LLEnvironment::EnvironmentInfo::extract(LLSD environment)
+{
+ ptr_t pinfo = std::make_shared();
+
+ pinfo->mIsDefault = environment.has(KEY_ISDEFAULT) ? environment[KEY_ISDEFAULT].asBoolean() : true;
+ pinfo->mParcelId = environment.has(KEY_PARCELID) ? environment[KEY_PARCELID].asInteger() : INVALID_PARCEL_ID;
+ pinfo->mRegionId = environment.has(KEY_REGIONID) ? environment[KEY_REGIONID].asUUID() : LLUUID::null;
+ pinfo->mIsLegacy = false;
+
+ if (environment.has(KEY_TRACKALTS))
+ {
+ for (int idx = 0; idx < 3; idx++)
+ {
+ pinfo->mAltitudes[idx+1] = environment[KEY_TRACKALTS][idx].asReal();
+ }
+ pinfo->mAltitudes[0] = 0;
+ }
+
+ if (environment.has(KEY_DAYCYCLE))
+ {
+ pinfo->mDayCycle = LLSettingsVODay::buildFromEnvironmentMessage(environment[KEY_DAYCYCLE]);
+ pinfo->mDayLength = LLSettingsDay::Seconds(environment.has(KEY_DAYLENGTH) ? environment[KEY_DAYLENGTH].asInteger() : -1);
+ pinfo->mDayOffset = LLSettingsDay::Seconds(environment.has(KEY_DAYOFFSET) ? environment[KEY_DAYOFFSET].asInteger() : -1);
+ pinfo->mDayHash = environment.has(KEY_DAYHASH) ? environment[KEY_DAYHASH].asInteger() : 0;
+ }
+ else
+ {
+ pinfo->mDayLength = LLEnvironment::instance().getEnvironmentDayLength(ENV_REGION);
+ pinfo->mDayOffset = LLEnvironment::instance().getEnvironmentDayOffset(ENV_REGION);
+ }
+
+ if (environment.has(KEY_DAYASSET))
+ {
+ pinfo->mAssetId = environment[KEY_DAYASSET].asUUID();
+ }
+
+ if (environment.has(KEY_DAYNAMES))
+ {
+ LLSD daynames = environment[KEY_DAYNAMES];
+ if (daynames.isArray())
+ {
+ pinfo->mDayCycleName.clear();
+ for (S32 index = 0; index < pinfo->mNameList.size(); ++index)
+ {
+ pinfo->mNameList[index] = daynames[index].asString();
+ }
+ }
+ else if (daynames.isString())
+ {
+ for (std::string &name: pinfo->mNameList)
+ {
+ name.clear();
+ }
+
+ pinfo->mDayCycleName = daynames.asString();
+ }
+ }
+ else if (pinfo->mDayCycle)
+ {
+ pinfo->mDayCycleName = pinfo->mDayCycle->getName();
+ }
+
+
+ if (environment.has(KEY_ENVVERSION))
+ {
+ LLSD version = environment[KEY_ENVVERSION];
+ pinfo->mEnvVersion = version.asInteger();
+ }
+ else
+ {
+ // can be used for region, but versions should be same
+ pinfo->mEnvVersion = pinfo->mIsDefault ? UNSET_PARCEL_ENVIRONMENT_VERSION : INVALID_PARCEL_ENVIRONMENT_VERSION;
+ }
+
+ return pinfo;
+}
+
+
+LLEnvironment::EnvironmentInfo::ptr_t LLEnvironment::EnvironmentInfo::extractLegacy(LLSD legacy)
+{
+ if (!legacy.isArray() || !legacy[0].has("regionID"))
+ {
+ LL_WARNS("ENVIRONMENT") << "Invalid legacy settings for environment: " << legacy << LL_ENDL;
+ return ptr_t();
+ }
+
+ ptr_t pinfo = std::make_shared();
+
+ pinfo->mIsDefault = false;
+ pinfo->mParcelId = INVALID_PARCEL_ID;
+ pinfo->mRegionId = legacy[0]["regionID"].asUUID();
+ pinfo->mIsLegacy = true;
+
+ pinfo->mDayLength = LLSettingsDay::DEFAULT_DAYLENGTH;
+ pinfo->mDayOffset = LLSettingsDay::DEFAULT_DAYOFFSET;
+ pinfo->mDayCycle = LLSettingsVODay::buildFromLegacyMessage(pinfo->mRegionId, legacy[1], legacy[2], legacy[3]);
+ if (pinfo->mDayCycle)
+ pinfo->mDayHash = pinfo->mDayCycle->getHash();
+
+ pinfo->mAltitudes[0] = 0;
+ pinfo->mAltitudes[2] = 10001;
+ pinfo->mAltitudes[3] = 10002;
+ pinfo->mAltitudes[4] = 10003;
+
+ return pinfo;
+}
+
+//=========================================================================
+LLSettingsWater::ptr_t LLEnvironment::createWaterFromLegacyPreset(const std::string filename, LLSD &messages)
+{
+ std::string name(gDirUtilp->getBaseFileName(filename, true));
+ std::string path(gDirUtilp->getDirName(filename));
+
+ LLSettingsWater::ptr_t water = LLSettingsVOWater::buildFromLegacyPresetFile(name, path, messages);
+
+ if (!water)
+ {
+ messages["NAME"] = name;
+ messages["FILE"] = filename;
+ }
+ return water;
+}
+
+LLSettingsSky::ptr_t LLEnvironment::createSkyFromLegacyPreset(const std::string filename, LLSD &messages)
+{
+ std::string name(gDirUtilp->getBaseFileName(filename, true));
+ std::string path(gDirUtilp->getDirName(filename));
+
+ LLSettingsSky::ptr_t sky = LLSettingsVOSky::buildFromLegacyPresetFile(name, path, messages);
+ if (!sky)
+ {
+ messages["NAME"] = name;
+ messages["FILE"] = filename;
+ }
+ return sky;
+}
+
+LLSettingsDay::ptr_t LLEnvironment::createDayCycleFromLegacyPreset(const std::string filename, LLSD &messages)
+{
+ std::string name(gDirUtilp->getBaseFileName(filename, true));
+ std::string path(gDirUtilp->getDirName(filename));
+
+ LLSettingsDay::ptr_t day = LLSettingsVODay::buildFromLegacyPresetFile(name, path, messages);
+ if (!day)
+ {
+ messages["NAME"] = name;
+ messages["FILE"] = filename;
+ }
+ return day;
+}
+
+LLSettingsDay::ptr_t LLEnvironment::createDayCycleFromEnvironment(EnvSelection_t env, LLSettingsBase::ptr_t settings)
+{
+ std::string type(settings->getSettingsType());
+
+ if (type == "daycycle")
+ return std::static_pointer_cast(settings);
+
+ if ((env != ENV_PARCEL) && (env != ENV_REGION))
+ {
+ LL_WARNS("ENVIRONMENT") << "May only create from parcel or region environment." << LL_ENDL;
+ return LLSettingsDay::ptr_t();
+ }
+
+ LLSettingsDay::ptr_t day = this->getEnvironmentDay(env);
+ if (!day && (env == ENV_PARCEL))
+ {
+ day = this->getEnvironmentDay(ENV_REGION);
+ }
+
+ if (!day)
+ {
+ LL_WARNS("ENVIRONMENT") << "Could not retrieve existing day settings." << LL_ENDL;
+ return LLSettingsDay::ptr_t();
+ }
+
+ day = day->buildClone();
+
+ if (type == "sky")
+ {
+ for (S32 idx = 1; idx < LLSettingsDay::TRACK_MAX; ++idx)
+ day->clearCycleTrack(idx);
+ day->setSettingsAtKeyframe(settings, 0.0f, 1);
+ }
+ else if (type == "water")
+ {
+ day->clearCycleTrack(LLSettingsDay::TRACK_WATER);
+ day->setSettingsAtKeyframe(settings, 0.0f, LLSettingsDay::TRACK_WATER);
+ }
+
+ return day;
+}
+
+void LLEnvironment::onAgentPositionHasChanged(const LLVector3 &localpos)
+{
+ S32 trackno = calculateSkyTrackForAltitude(localpos.mV[VZ]);
+ if (trackno == mCurrentTrack)
+ return;
+
+ mCurrentTrack = trackno;
+ for (S32 env = ENV_LOCAL; env < ENV_DEFAULT; ++env)
+ {
+ if (mEnvironments[env])
+ mEnvironments[env]->setSkyTrack(mCurrentTrack);
+ }
+}
+
+S32 LLEnvironment::calculateSkyTrackForAltitude(F64 altitude)
+{
+ auto it = std::find_if_not(mTrackAltitudes.begin(), mTrackAltitudes.end(), [altitude](F32 test) { return altitude > test; });
+
+ if (it == mTrackAltitudes.begin())
+ return 1;
+ else if (it == mTrackAltitudes.end())
+ return 4;
+
+ return std::min(static_cast(std::distance(mTrackAltitudes.begin(), it)), 4);
+}
+
+//-------------------------------------------------------------------------
+void LLEnvironment::handleEnvironmentPush(LLSD &message)
+{
+ // Log the experience message
+ LLExperienceLog::instance().handleExperienceMessage(message);
+
+ std::string action = message[KEY_ACTION].asString();
+ LLUUID experience_id = message[KEY_EXPERIENCEID].asUUID();
+ LLSD action_data = message[KEY_ACTIONDATA];
+ F32 transition_time = action_data[KEY_TRANSITIONTIME].asReal();
+
+ //TODO: Check here that the viewer thinks the experience is still valid.
+
+
+ if (action == ACTION_CLEARENVIRONMENT)
+ {
+ handleEnvironmentPushClear(experience_id, action_data, transition_time);
+ }
+ else if (action == ACTION_PUSHFULLENVIRONMENT)
+ {
+ handleEnvironmentPushFull(experience_id, action_data, transition_time);
+ }
+ else if (action == ACTION_PUSHPARTIALENVIRONMENT)
+ {
+ handleEnvironmentPushPartial(experience_id, action_data, transition_time);
+ }
+ else
+ {
+ LL_WARNS("ENVIRONMENT", "GENERICMESSAGES") << "Unknown environment push action '" << action << "'" << LL_ENDL;
+ }
+}
+
+void LLEnvironment::handleEnvironmentPushClear(LLUUID experience_id, LLSD &message, F32 transition)
+{
+ clearExperienceEnvironment(experience_id, LLSettingsBase::Seconds(transition));
+}
+
+void LLEnvironment::handleEnvironmentPushFull(LLUUID experience_id, LLSD &message, F32 transition)
+{
+ LLUUID asset_id(message[KEY_ASSETID].asUUID());
+
+ setExperienceEnvironment(experience_id, asset_id, LLSettingsBase::Seconds(transition));
+}
+
+void LLEnvironment::handleEnvironmentPushPartial(LLUUID experience_id, LLSD &message, F32 transition)
+{
+ LLSD settings(message["settings"]);
+
+ if (settings.isUndefined())
+ return;
+
+ setExperienceEnvironment(experience_id, settings, LLSettingsBase::Seconds(transition));
+}
+
+void LLEnvironment::clearExperienceEnvironment(LLUUID experience_id, LLSettingsBase::Seconds transition_time)
+{
+ DayInjection::ptr_t injection = std::dynamic_pointer_cast(getEnvironmentInstance(ENV_PUSH));
+ if (injection)
+ {
+ injection->clearInjections(experience_id, transition_time);
+ }
+
+}
+
+void LLEnvironment::setSharedEnvironment()
+{
+ clearEnvironment(LLEnvironment::ENV_LOCAL);
+ setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
+ updateEnvironment();
+}
+
+void LLEnvironment::setExperienceEnvironment(LLUUID experience_id, LLUUID asset_id, F32 transition_time)
+{
+ LLSettingsVOBase::getSettingsAsset(asset_id,
+ [this, experience_id, transition_time](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)
+ {
+ onSetExperienceEnvAssetLoaded(experience_id, settings, transition_time, status);
+ });
+
+
+}
+
+void LLEnvironment::onSetExperienceEnvAssetLoaded(LLUUID experience_id, LLSettingsBase::ptr_t settings, F32 transition_time, S32 status)
+{
+ DayInjection::ptr_t environment = std::dynamic_pointer_cast(getEnvironmentInstance(ENV_PUSH));
+ bool updateenvironment(false);
+
+ if (!settings || status)
+ {
+ LLSD args;
+ args["DESC"] = experience_id.asString();
+ LLNotificationsUtil::add("FailedToFindSettings", args);
+ return;
+ }
+
+ if (!environment)
+ {
+ environment = std::dynamic_pointer_cast(getEnvironmentInstance(ENV_PUSH, true));
+ updateenvironment = true;
+ }
+
+ if (settings->getSettingsType() == "daycycle")
+ {
+ environment->setInjectedDay(std::static_pointer_cast(settings), experience_id, LLSettingsBase::Seconds(transition_time));
+ }
+ else if (settings->getSettingsType() == "sky")
+ {
+ environment->setInjectedSky(std::static_pointer_cast(settings), experience_id, LLSettingsBase::Seconds(transition_time));
+ }
+ else if (settings->getSettingsType() == "water")
+ {
+ environment->setInjectedWater(std::static_pointer_cast(settings), experience_id, LLSettingsBase::Seconds(transition_time));
+ }
+
+ if (updateenvironment)
+ updateEnvironment(TRANSITION_INSTANT, true);
+}
+
+
+void LLEnvironment::setExperienceEnvironment(LLUUID experience_id, LLSD data, F32 transition_time)
+{
+ LLSD sky(data["sky"]);
+ LLSD water(data["water"]);
+
+ if (sky.isUndefined() && water.isUndefined())
+ {
+ clearExperienceEnvironment(experience_id, LLSettingsBase::Seconds(transition_time));
+ return;
+ }
+
+ DayInjection::ptr_t environment = std::dynamic_pointer_cast(getEnvironmentInstance(ENV_PUSH));
+ bool updateenvironment(false);
+
+ if (!environment)
+ {
+ environment = std::dynamic_pointer_cast(getEnvironmentInstance(ENV_PUSH, true));
+ updateenvironment = true;
+ }
+
+ if (!sky.isUndefined())
+ {
+ environment->injectSkySettings(sky, experience_id, LLSettingsBase::Seconds(transition_time));
+ }
+
+ if (!water.isUndefined())
+ {
+ environment->injectWaterSettings(sky, experience_id, LLSettingsBase::Seconds(transition_time));
+ }
+
+ if (updateenvironment)
+ updateEnvironment(TRANSITION_INSTANT, true);
+
+}
+
+void LLEnvironment::listenExperiencePump(const LLSD &message)
+{
+ LLUUID experience_id = message["experience"];
+ LLSD data = message[experience_id.asString()];
+ std::string permission(data["permission"].asString());
+
+ if ((permission == "Forget") || (permission == "Block"))
+ {
+ clearExperienceEnvironment(experience_id, (permission == "Block") ? TRANSITION_INSTANT : TRANSITION_FAST);
+ }
+}
+
+//=========================================================================
+LLEnvironment::DayInstance::DayInstance(EnvSelection_t env) :
+ mDayCycle(),
+ mSky(),
+ mWater(),
+ mDayLength(LLSettingsDay::DEFAULT_DAYLENGTH),
+ mDayOffset(LLSettingsDay::DEFAULT_DAYOFFSET),
+ mDayOffsetOverride(LLSettingsDay::MINIMUM_DAYOFFSET), // KC
+ mBlenderSky(),
+ mBlenderWater(),
+ mInitialized(false),
+ mSkyTrack(1),
+ mEnv(env),
+ mAnimateFlags(0)
+{ }
+
+
+LLEnvironment::DayInstance::ptr_t LLEnvironment::DayInstance::clone() const
+{
+ ptr_t environment = std::make_shared(mEnv);
+
+ environment->mDayCycle = mDayCycle;
+ environment->mSky = mSky;
+ environment->mWater = mWater;
+ environment->mDayLength = mDayLength;
+ environment->mDayOffset = mDayOffset;
+ environment->mBlenderSky = mBlenderSky;
+ environment->mBlenderWater = mBlenderWater;
+ environment->mInitialized = mInitialized;
+ environment->mSkyTrack = mSkyTrack;
+ environment->mAnimateFlags = mAnimateFlags;
+
+ return environment;
+}
+
+bool LLEnvironment::DayInstance::applyTimeDelta(const LLSettingsBase::Seconds& delta)
+{
+ ptr_t keeper(shared_from_this()); // makes sure that this does not go away while it is being worked on.
+
+ bool changed(false);
+ if (!mInitialized)
+ initialize();
+
+ if (mBlenderSky)
+ changed |= mBlenderSky->applyTimeDelta(delta);
+ if (mBlenderWater)
+ changed |= mBlenderWater->applyTimeDelta(delta);
+ return changed;
+}
+
+void LLEnvironment::DayInstance::setDay(const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset)
+{
+ mInitialized = false;
+
+ mAnimateFlags = 0;
+
+ mDayCycle = pday;
+ mDayLength = daylength;
+ mDayOffset = dayoffset;
+
+ mBlenderSky.reset();
+ mBlenderWater.reset();
+
+ mSky = LLSettingsVOSky::buildDefaultSky();
+ mWater = LLSettingsVOWater::buildDefaultWater();
+
+ animate();
+}
+
+
+void LLEnvironment::DayInstance::setSky(const LLSettingsSky::ptr_t &psky)
+{
+ mInitialized = false;
+
+ bool different_sky = mSky != psky;
+
+ mSky = psky;
+ mSky->mReplaced |= different_sky;
+ mSky->update();
+ mBlenderSky.reset();
+
+ if (gAtmosphere)
+ {
+ AtmosphericModelSettings settings;
+ LLEnvironment::getAtmosphericModelSettings(settings, psky);
+ gAtmosphere->configureAtmosphericModel(settings);
+ }
+}
+
+void LLEnvironment::DayInstance::setWater(const LLSettingsWater::ptr_t &pwater)
+{
+ mInitialized = false;
+
+ bool different_water = mWater != pwater;
+ mWater = pwater;
+ mWater->mReplaced |= different_water;
+ mWater->update();
+ mBlenderWater.reset();
+}
+
+void LLEnvironment::DayInstance::initialize()
+{
+ mInitialized = true;
+
+ if (!mWater)
+ mWater = LLSettingsVOWater::buildDefaultWater();
+ if (!mSky)
+ mSky = LLSettingsVOSky::buildDefaultSky();
+}
+
+void LLEnvironment::DayInstance::clear()
+{
+ mDayCycle.reset();
+ mSky.reset();
+ mWater.reset();
+ mDayLength = LLSettingsDay::DEFAULT_DAYLENGTH;
+ mDayOffset = LLSettingsDay::DEFAULT_DAYOFFSET;
+ mDayOffsetOverride = LLSettingsDay::MINIMUM_DAYOFFSET; // KC
+ mBlenderSky.reset();
+ mBlenderWater.reset();
+ mSkyTrack = 1;
+}
+
+void LLEnvironment::DayInstance::setSkyTrack(S32 trackno)
+{
+ mSkyTrack = trackno;
+ if (mBlenderSky)
+ {
+ mBlenderSky->switchTrack(trackno, 0.0);
+ }
+}
+
+void LLEnvironment::DayInstance::setBlenders(const LLSettingsBlender::ptr_t &skyblend, const LLSettingsBlender::ptr_t &waterblend)
+{
+ mBlenderSky = skyblend;
+ mBlenderWater = waterblend;
+}
+
+LLSettingsBase::TrackPosition LLEnvironment::DayInstance::getProgress() const
+{
+ LLSettingsBase::Seconds now(LLDate::now().secondsSinceEpoch());
+ // now += mDayOffset;
+ now += mDayOffset + mDayOffsetOverride; // KC
+
+ if ((mDayLength <= 0) || !mDayCycle)
+ return -1.0f; // no actual day cycle.
+
+ return convert_time_to_position(now, mDayLength);
+}
+
+LLSettingsBase::TrackPosition LLEnvironment::DayInstance::secondsToKeyframe(LLSettingsDay::Seconds seconds)
+{
+ return convert_time_to_position(seconds, mDayLength);
+}
+
+void LLEnvironment::DayInstance::animate()
+{
+ LLSettingsBase::Seconds now(LLDate::now().secondsSinceEpoch());
+
+ // now += mDayOffset;
+ now += mDayOffset + mDayOffsetOverride; // KC
+
+ if (!mDayCycle)
+ return;
+
+ if (!(mAnimateFlags & NO_ANIMATE_WATER))
+ {
+ LLSettingsDay::CycleTrack_t &wtrack = mDayCycle->getCycleTrack(0);
+
+ if (wtrack.empty())
+ {
+ mWater.reset();
+ mBlenderWater.reset();
+ }
+ else
+ {
+ mWater = LLSettingsVOWater::buildDefaultWater();
+ mBlenderWater = std::make_shared(mWater, mDayCycle, 0,
+ // mDayLength, mDayOffset, DEFAULT_UPDATE_THRESHOLD);
+ mDayLength, mDayOffset + mDayOffsetOverride, DEFAULT_UPDATE_THRESHOLD); // KC
+ }
+ }
+
+ if (!(mAnimateFlags & NO_ANIMATE_SKY))
+ {
+ // sky, initialize to track 1
+ LLSettingsDay::CycleTrack_t &track = mDayCycle->getCycleTrack(1);
+
+ if (track.empty())
+ {
+ mSky.reset();
+ mBlenderSky.reset();
+ }
+ else
+ {
+ mSky = LLSettingsVOSky::buildDefaultSky();
+ mBlenderSky = std::make_shared(mSky, mDayCycle, 1,
+ // mDayLength, mDayOffset, DEFAULT_UPDATE_THRESHOLD);
+ mDayLength, mDayOffset + mDayOffsetOverride, DEFAULT_UPDATE_THRESHOLD); // KC
+ mBlenderSky->switchTrack(mSkyTrack, 0.0);
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+LLEnvironment::DayTransition::DayTransition(const LLSettingsSky::ptr_t &skystart,
+ const LLSettingsWater::ptr_t &waterstart, LLEnvironment::DayInstance::ptr_t &end, LLSettingsDay::Seconds time) :
+ DayInstance(ENV_NONE),
+ mStartSky(skystart),
+ mStartWater(waterstart),
+ mNextInstance(end),
+ mTransitionTime(time)
+{
+
+}
+
+bool LLEnvironment::DayTransition::applyTimeDelta(const LLSettingsBase::Seconds& delta)
+{
+ bool changed(false);
+
+ changed = mNextInstance->applyTimeDelta(delta);
+ changed |= DayInstance::applyTimeDelta(delta);
+ return changed;
+}
+
+void LLEnvironment::DayTransition::animate()
+{
+ mNextInstance->animate();
+
+ mWater = mStartWater->buildClone();
+ mBlenderWater = std::make_shared(mWater, mStartWater, mNextInstance->getWater(), mTransitionTime);
+ mBlenderWater->setOnFinished(
+ [this](LLSettingsBlender::ptr_t blender) {
+ mBlenderWater.reset();
+
+ if (!mBlenderSky && !mBlenderWater)
+ LLEnvironment::instance().mCurrentEnvironment = mNextInstance;
+ else
+ setWater(mNextInstance->getWater());
+ });
+
+ mSky = mStartSky->buildClone();
+ mBlenderSky = std::make_shared(mSky, mStartSky, mNextInstance->getSky(), mTransitionTime);
+ mBlenderSky->setOnFinished(
+ [this](LLSettingsBlender::ptr_t blender) {
+ mBlenderSky.reset();
+
+ if (!mBlenderSky && !mBlenderWater)
+ LLEnvironment::instance().mCurrentEnvironment = mNextInstance;
+ else
+ setSky(mNextInstance->getSky());
+ });
+}
+
+void LLEnvironment::saveToSettings()
+{
+ std::string user_dir = gDirUtilp->getLindenUserDir();
+ if (user_dir.empty())
+ {
+ // not logged in
+ return;
+ }
+ bool has_data = false;
+
+ if (gSavedSettings.getBOOL("EnvironmentPersistAcrossLogin"))
+ {
+ DayInstance::ptr_t environment = getEnvironmentInstance(ENV_LOCAL);
+ if (environment)
+ {
+ // Environment is 'layered'. No data in ENV_LOCAL means we are using parcel/region
+ // Store local environment for next session
+ LLSD env_data;
+
+ LLSettingsDay::ptr_t day = environment->getDayCycle();
+ if (day)
+ {
+ const std::string name = day->getName();
+ const LLUUID asset_id = day->getAssetId();
+ if (asset_id.notNull())
+ {
+ // just save the id
+ env_data["day_id"] = asset_id;
+ env_data["day_length"] = LLSD::Integer(environment->getDayLength());
+ env_data["day_offset"] = LLSD::Integer(environment->getDayOffset());
+ has_data = true;
+ }
+ else if (!name.empty() && name != LLSettingsBase::DEFAULT_SETTINGS_NAME)
+ {
+ // This setting was created locally and was not saved
+ // The only option is to save the whole thing
+ env_data["day_llsd"] = day->getSettings();
+ env_data["day_length"] = LLSD::Integer(environment->getDayLength());
+ env_data["day_offset"] = LLSD::Integer(environment->getDayOffset());
+ has_data = true;
+ }
+ }
+
+ LLSettingsSky::ptr_t sky = environment->getSky();
+ if ((environment->getFlags() & DayInstance::NO_ANIMATE_SKY) && sky)
+ {
+ const std::string name = sky->getName();
+ const LLUUID asset_id = sky->getAssetId();
+ if (asset_id.notNull())
+ {
+ // just save the id
+ env_data["sky_id"] = asset_id;
+ has_data = true;
+ }
+ else if (!name.empty() && name != LLSettingsBase::DEFAULT_SETTINGS_NAME)
+ {
+ // This setting was created locally and was not saved
+ // The only option is to save the whole thing
+ env_data["sky_llsd"] = sky->getSettings();
+ has_data = true;
+ }
+ has_data = true;
+ }
+
+ LLSettingsWater::ptr_t water = environment->getWater();
+ if ((environment->getFlags() & DayInstance::NO_ANIMATE_WATER) && water)
+ {
+ const std::string name = water->getName();
+ const LLUUID asset_id = water->getAssetId();
+ if (asset_id.notNull())
+ {
+ // just save the id
+ env_data["water_id"] = asset_id;
+ has_data = true;
+ }
+ else if (!name.empty() && name != LLSettingsBase::DEFAULT_SETTINGS_NAME)
+ {
+ // This setting was created locally and was not saved
+ // The only option is to save the whole thing
+ env_data["water_llsd"] = water->getSettings();
+ has_data = true;
+ }
+ }
+
+ std::string user_filepath = user_dir + gDirUtilp->getDirDelimiter() + LOCAL_ENV_STORAGE_FILE;
+ llofstream out(user_filepath.c_str(), std::ios_base::out | std::ios_base::binary);
+ if (out.good())
+ {
+ LLSDSerialize::toBinary(env_data, out);
+ out.close();
+ }
+ else
+ {
+ LL_WARNS("ENVIRONMENT") << "Unable to open " << user_filepath << " for output." << LL_ENDL;
+ }
+ }
+ }
+
+ if (!has_data)
+ {
+ LLFile::remove(user_dir + gDirUtilp->getDirDelimiter() + LOCAL_ENV_STORAGE_FILE, ENOENT);
+ }
+}
+
+bool LLEnvironment::loadFromSettings()
+{
+ if (!gSavedSettings.getBOOL("EnvironmentPersistAcrossLogin"))
+ {
+ return false;
+ }
+
+ std::string user_path = gDirUtilp->getLindenUserDir();
+ if (user_path.empty())
+ {
+ LL_WARNS("ENVIRONMENT") << "Can't load previous environment, Environment was initialized before user logged in" << LL_ENDL;
+ return false;
+ }
+ std::string user_filepath(user_path + gDirUtilp->getDirDelimiter() + LOCAL_ENV_STORAGE_FILE);
+ if (!gDirUtilp->fileExists(user_filepath))
+ {
+ // No previous environment
+ return false;
+ }
+
+ LLSD env_data;
+ llifstream file(user_filepath.c_str(), std::ios_base::in | std::ios_base::binary);
+ if (file.is_open())
+ {
+ LLSDSerialize::fromBinary(env_data, file, LLSDSerialize::SIZE_UNLIMITED);
+ if (env_data.isUndefined())
+ {
+ LL_WARNS("ENVIRONMENT") << "error loading " << user_filepath << LL_ENDL;
+ return false;
+ }
+ else
+ {
+ LL_INFOS("ENVIRONMENT") << "Loaded previous session environment from: " << user_filepath << LL_ENDL;
+ }
+ file.close();
+ }
+ else
+ {
+ LL_INFOS("ENVIRONMENT") << "Unable to open previous session environment file " << user_filepath << LL_ENDL;
+ }
+
+ if (!env_data.isMap() || env_data.emptyMap())
+ {
+ LL_DEBUGS("ENVIRONMENT") << "Empty map loaded from: " << user_filepath << LL_ENDL;
+ return false;
+ }
+
+ bool valid = false;
+
+ if (env_data.has("day_id"))
+ {
+ S32 length = env_data["day_length"].asInteger();
+ S32 offset = env_data["day_offset"].asInteger();
+ setEnvironment(ENV_LOCAL, env_data["day_id"].asUUID(), LLSettingsDay::Seconds(length), LLSettingsDay::Seconds(offset));
+ valid = true;
+ }
+ else if (env_data.has("day_llsd"))
+ {
+ S32 length = env_data["day_length"].asInteger();
+ S32 offset = env_data["day_offset"].asInteger();
+ LLSettingsDay::ptr_t day = std::make_shared(env_data["day_llsd"]);
+ setEnvironment(ENV_LOCAL, day, LLSettingsDay::Seconds(length), LLSettingsDay::Seconds(offset));
+ valid = true;
+ }
+
+ if (env_data.has("sky_id"))
+ {
+ setEnvironment(ENV_LOCAL, env_data["sky_id"].asUUID());
+ valid = true;
+ }
+ else if (env_data.has("sky_llsd"))
+ {
+ LLSettingsSky::ptr_t sky = std::make_shared(env_data["sky_llsd"]);
+ setEnvironment(ENV_LOCAL, sky);
+ valid = true;
+ }
+
+ if (env_data.has("water_id"))
+ {
+ setEnvironment(ENV_LOCAL, env_data["water_id"].asUUID());
+ valid = true;
+ }
+ else if (env_data.has("water_llsd"))
+ {
+ LLSettingsWater::ptr_t sky = std::make_shared(env_data["water_llsd"]);
+ setEnvironment(ENV_LOCAL, sky);
+ valid = true;
+ }
+
+ if (valid)
+ {
+ updateEnvironment(TRANSITION_INSTANT, true);
+ }
+ return valid;
+}
+
+void LLEnvironment::saveBeaconsState()
+{
+ if (mEditorCounter == 0)
+ {
+ mShowSunBeacon = gSavedSettings.getBOOL("sunbeacon");
+ mShowMoonBeacon = gSavedSettings.getBOOL("moonbeacon");
+ }
+ ++mEditorCounter;
+}
+void LLEnvironment::revertBeaconsState()
+{
+ --mEditorCounter;
+ if (mEditorCounter == 0)
+ {
+ gSavedSettings.setBOOL("sunbeacon", mShowSunBeacon && gSavedSettings.getBOOL("sunbeacon"));
+ gSavedSettings.setBOOL("moonbeacon", mShowMoonBeacon && gSavedSettings.getBOOL("moonbeacon"));
+ }
+}
+
+//=========================================================================
+LLTrackBlenderLoopingManual::LLTrackBlenderLoopingManual(const LLSettingsBase::ptr_t &target, const LLSettingsDay::ptr_t &day, S32 trackno) :
+ LLSettingsBlender(target, LLSettingsBase::ptr_t(), LLSettingsBase::ptr_t()),
+ mDay(day),
+ mTrackNo(trackno),
+ mPosition(0.0)
+{
+ LLSettingsDay::TrackBound_t initial = getBoundingEntries(mPosition);
+
+ if (initial.first != mEndMarker)
+ { // No frames in track
+ mInitial = (*initial.first).second;
+ mFinal = (*initial.second).second;
+
+ LLSD initSettings = mInitial->getSettings();
+ mTarget->replaceSettings(initSettings);
+ }
+}
+
+LLSettingsBase::BlendFactor LLTrackBlenderLoopingManual::setPosition(const LLSettingsBase::TrackPosition& position)
+{
+ mPosition = llclamp(position, 0.0f, 1.0f);
+
+ LLSettingsDay::TrackBound_t bounds = getBoundingEntries(mPosition);
+
+ if (bounds.first == mEndMarker)
+ { // No frames in track.
+ return 0.0;
+ }
+
+ mInitial = (*bounds.first).second;
+ mFinal = (*bounds.second).second;
+
+ F64 spanLength = getSpanLength(bounds);
+
+ F64 spanPos = ((mPosition < (*bounds.first).first) ? (mPosition + 1.0) : mPosition) - (*bounds.first).first;
+
+ if (spanPos > spanLength)
+ {
+ // we are clamping position to 0-1 and spanLength is 1
+ // so don't account for case of spanPos == spanLength
+ spanPos = fmod(spanPos, spanLength);
+ }
+
+ F64 blendf = spanPos / spanLength;
+ return LLSettingsBlender::setBlendFactor(blendf);
+}
+
+void LLTrackBlenderLoopingManual::switchTrack(S32 trackno, const LLSettingsBase::TrackPosition& position)
+{
+ mTrackNo = trackno;
+
+ LLSettingsBase::TrackPosition useposition = (position < 0.0) ? mPosition : position;
+
+ setPosition(useposition);
+}
+
+LLSettingsDay::TrackBound_t LLTrackBlenderLoopingManual::getBoundingEntries(F64 position)
+{
+ LLSettingsDay::CycleTrack_t &wtrack = mDay->getCycleTrack(mTrackNo);
+
+ mEndMarker = wtrack.end();
+
+ LLSettingsDay::TrackBound_t bounds = get_bounding_entries(wtrack, position);
+ return bounds;
+}
+
+F64 LLTrackBlenderLoopingManual::getSpanLength(const LLSettingsDay::TrackBound_t &bounds) const
+{
+ return get_wrapping_distance((*bounds.first).first, (*bounds.second).first);
+}
+
+//=========================================================================
+namespace
+{
+ DayInjection::DayInjection(LLEnvironment::EnvSelection_t env):
+ LLEnvironment::DayInstance(env),
+ mBaseDayInstance(),
+ mInjectedSky(),
+ mInjectedWater(),
+ mActiveExperiences(),
+ mDayExperience(),
+ mSkyExperience(),
+ mWaterExperience(),
+ mEnvChangeConnection(),
+ mParcelChangeConnection()
+ {
+ mInjectedSky = std::make_shared(LLEnvironment::instance().getCurrentSky());
+ mInjectedWater = std::make_shared(LLEnvironment::instance().getCurrentWater());
+ mBaseDayInstance = LLEnvironment::instance().getSharedEnvironmentInstance();
+ mSky = mInjectedSky;
+ mWater = mInjectedWater;
+
+ mEnvChangeConnection = LLEnvironment::instance().setEnvironmentChanged([this](LLEnvironment::EnvSelection_t env, S32) { onEnvironmentChanged(env); });
+ mParcelChangeConnection = gAgent.addParcelChangedCallback([this]() { onParcelChange(); });
+ }
+
+ DayInjection::~DayInjection()
+ {
+ if (mEnvChangeConnection.connected())
+ mEnvChangeConnection.disconnect();
+ if (mParcelChangeConnection.connected())
+ mParcelChangeConnection.disconnect();
+ }
+
+
+ bool DayInjection::applyTimeDelta(const LLSettingsBase::Seconds& delta)
+ {
+ bool changed(false);
+
+ if (mBaseDayInstance)
+ changed |= mBaseDayInstance->applyTimeDelta(delta);
+ mInjectedSky->applyInjections(delta);
+ mInjectedWater->applyInjections(delta);
+ changed |= LLEnvironment::DayInstance::applyTimeDelta(delta);
+ if (changed)
+ {
+ mInjectedSky->setDirtyFlag(true);
+ mInjectedWater->setDirtyFlag(true);
+ }
+ mInjectedSky->update();
+ mInjectedWater->update();
+
+ if (!hasInjections())
+ { // There are no injections being managed. This should really go away.
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_PUSH);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+ }
+
+ return changed;
+ }
+
+ void DayInjection::setBaseDayInstance(const LLEnvironment::DayInstance::ptr_t &baseday)
+ {
+ mBaseDayInstance = baseday;
+
+ if (mSkyExperience.isNull())
+ mInjectedSky->setSource(mBaseDayInstance->getSky());
+ if (mWaterExperience.isNull())
+ mInjectedWater->setSource(mBaseDayInstance->getWater());
+ }
+
+
+ bool DayInjection::hasInjections() const
+ {
+ return (!mSkyExperience.isNull() || !mWaterExperience.isNull() || !mDayExperience.isNull() ||
+ mBlenderSky || mBlenderWater || mInjectedSky->hasInjections() || mInjectedWater->hasInjections());
+ }
+
+
+ void DayInjection::testExperiencesOnParcel(S32 parcel_id)
+ {
+ LLCoros::instance().launch("DayInjection::testExperiencesOnParcel",
+ [this, parcel_id]() { DayInjection::testExperiencesOnParcelCoro(std::static_pointer_cast(this->shared_from_this()), parcel_id); });
+
+ }
+
+ void DayInjection::setInjectedDay(const LLSettingsDay::ptr_t &pday, LLUUID experience_id, LLSettingsBase::Seconds transition)
+ {
+ mSkyExperience = experience_id;
+ mWaterExperience = experience_id;
+ mDayExperience = experience_id;
+
+ mBaseDayInstance = mBaseDayInstance->clone();
+ mBaseDayInstance->setEnvironmentSelection(LLEnvironment::ENV_NONE);
+ mBaseDayInstance->setDay(pday, mBaseDayInstance->getDayLength(), mBaseDayInstance->getDayOffset());
+ animateSkyChange(mBaseDayInstance->getSky(), transition);
+ animateWaterChange(mBaseDayInstance->getWater(), transition);
+
+ mActiveExperiences.insert(experience_id);
+ }
+
+ void DayInjection::setInjectedSky(const LLSettingsSky::ptr_t &psky, LLUUID experience_id, LLSettingsBase::Seconds transition)
+ {
+ mSkyExperience = experience_id;
+ mActiveExperiences.insert(experience_id);
+ checkExperience();
+ animateSkyChange(psky, transition);
+ }
+
+ void DayInjection::setInjectedWater(const LLSettingsWater::ptr_t &pwater, LLUUID experience_id, LLSettingsBase::Seconds transition)
+ {
+ mWaterExperience = experience_id;
+ mActiveExperiences.insert(experience_id);
+ checkExperience();
+ animateWaterChange(pwater, transition);
+ }
+
+ void DayInjection::injectSkySettings(LLSD settings, LLUUID experience_id, LLSettingsBase::Seconds transition)
+ {
+ mInjectedSky->injectExperienceValues(settings, experience_id, transition);
+ mActiveExperiences.insert(experience_id);
+ }
+
+ void DayInjection::injectWaterSettings(LLSD settings, LLUUID experience_id, LLSettingsBase::Seconds transition)
+ {
+ mInjectedWater->injectExperienceValues(settings, experience_id, transition);
+ mActiveExperiences.insert(experience_id);
+ }
+
+ void DayInjection::clearInjections(LLUUID experience_id, LLSettingsBase::Seconds transition_time)
+ {
+ if ((experience_id.isNull() && !mDayExperience.isNull()) || (experience_id == mDayExperience))
+ {
+ mDayExperience.setNull();
+ if (mSkyExperience == experience_id)
+ mSkyExperience.setNull();
+ if (mWaterExperience == experience_id)
+ mWaterExperience.setNull();
+
+ mBaseDayInstance = LLEnvironment::instance().getSharedEnvironmentInstance();
+
+ if (mSkyExperience.isNull())
+ animateSkyChange(mBaseDayInstance->getSky(), transition_time);
+ if (mWaterExperience.isNull())
+ animateWaterChange(mBaseDayInstance->getWater(), transition_time);
+ }
+
+ if ((experience_id.isNull() && !mSkyExperience.isNull()) || (experience_id == mSkyExperience))
+ {
+ mSkyExperience.setNull();
+ animateSkyChange(mBaseDayInstance->getSky(), transition_time);
+ }
+ if ((experience_id.isNull() && !mWaterExperience.isNull()) || (experience_id == mWaterExperience))
+ {
+ mWaterExperience.setNull();
+ animateWaterChange(mBaseDayInstance->getWater(), transition_time);
+ }
+
+ mInjectedSky->removeInjections(experience_id, transition_time);
+ mInjectedWater->removeInjections(experience_id, transition_time);
+
+ if (experience_id.isNull())
+ mActiveExperiences.clear();
+ else
+ mActiveExperiences.erase(experience_id);
+
+ if ((transition_time == LLEnvironment::TRANSITION_INSTANT) && (countExperiencesActive() == 0))
+ { // Only do this if instant and there are no other experiences injecting values.
+ // (otherwise will be handled after transition)
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_PUSH);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+ }
+ }
+
+
+ void DayInjection::testExperiencesOnParcelCoro(wptr_t that, S32 parcel_id)
+ {
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("testExperiencesOnParcelCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ std::string url = gAgent.getRegionCapability("ExperienceQuery");
+
+ if (url.empty())
+ {
+ LL_WARNS("ENVIRONMENT") << "No experience query cap." << LL_ENDL;
+ return; // no checking in this region.
+ }
+
+ {
+ ptr_t thatlock(that);
+ std::stringstream fullurl;
+
+ if (!thatlock)
+ return;
+
+ fullurl << url << "?";
+ fullurl << "parcelid=" << parcel_id;
+
+ for (auto it = thatlock->mActiveExperiences.begin(); it != thatlock->mActiveExperiences.end(); ++it)
+ {
+ if (it != thatlock->mActiveExperiences.begin())
+ fullurl << ",";
+ else
+ fullurl << "&experiences=";
+ fullurl << (*it).asString();
+ }
+ url = fullurl.str();
+ }
+
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS() << "Unable to retrieve experience status for parcel." << LL_ENDL;
+ return;
+ }
+
+ {
+ LLParcel* parcel = LLViewerParcelMgr::instance().getAgentParcel();
+ if (!parcel)
+ return;
+
+ if (parcel_id != parcel->getLocalID())
+ {
+ // Agent no longer on queried parcel.
+ return;
+ }
+ }
+
+
+ LLSD experiences = result["experiences"];
+ {
+ ptr_t thatlock(that);
+ if (!thatlock)
+ return;
+
+ for (LLSD::map_iterator itr = experiences.beginMap(); itr != experiences.endMap(); ++itr)
+ {
+ if (!((*itr).second.asBoolean()))
+ thatlock->clearInjections(LLUUID((*itr).first), LLEnvironment::TRANSITION_FAST);
+
+ }
+ }
+ }
+
+ void DayInjection::animateSkyChange(LLSettingsSky::ptr_t psky, LLSettingsBase::Seconds transition)
+ {
+ if (mInjectedSky.get() == psky.get())
+ { // An attempt to animate to itself... don't do it.
+ return;
+ }
+ if (transition == LLEnvironment::TRANSITION_INSTANT)
+ {
+ mBlenderSky.reset();
+ mInjectedSky->setSource(psky);
+ }
+ else
+ {
+ LLSettingsSky::ptr_t start_sky(mInjectedSky->getSource()->buildClone());
+ LLSettingsSky::ptr_t target_sky(start_sky->buildClone());
+ mInjectedSky->setSource(target_sky);
+
+ mBlenderSky = std::make_shared(target_sky, start_sky, psky, transition);
+ mBlenderSky->setOnFinished(
+ [this, psky](LLSettingsBlender::ptr_t blender)
+ {
+ mBlenderSky.reset();
+ mInjectedSky->setSource(psky);
+ setSky(mInjectedSky);
+ if (!mBlenderWater && (countExperiencesActive() == 0))
+ {
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_PUSH);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+ }
+ });
+ }
+ }
+
+ void DayInjection::animateWaterChange(LLSettingsWater::ptr_t pwater, LLSettingsBase::Seconds transition)
+ {
+ if (mInjectedWater.get() == pwater.get())
+ { // An attempt to animate to itself. Bad idea.
+ return;
+ }
+ if (transition == LLEnvironment::TRANSITION_INSTANT)
+ {
+ mBlenderWater.reset();
+ mInjectedWater->setSource(pwater);
+ }
+ else
+ {
+ LLSettingsWater::ptr_t start_Water(mInjectedWater->getSource()->buildClone());
+ LLSettingsWater::ptr_t scratch_Water(start_Water->buildClone());
+ mInjectedWater->setSource(scratch_Water);
+
+ mBlenderWater = std::make_shared(scratch_Water, start_Water, pwater, transition);
+ mBlenderWater->setOnFinished(
+ [this, pwater](LLSettingsBlender::ptr_t blender)
+ {
+ mBlenderWater.reset();
+ mInjectedWater->setSource(pwater);
+ setWater(mInjectedWater);
+ if (!mBlenderSky && (countExperiencesActive() == 0))
+ {
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_PUSH);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+ }
+ });
+ }
+ }
+
+ void DayInjection::onEnvironmentChanged(LLEnvironment::EnvSelection_t env)
+ {
+ if (env >= LLEnvironment::ENV_PARCEL)
+ {
+ LLEnvironment::EnvSelection_t base_env(mBaseDayInstance->getEnvironmentSelection());
+ LLEnvironment::DayInstance::ptr_t nextbase = LLEnvironment::instance().getSharedEnvironmentInstance();
+
+ if ((base_env == LLEnvironment::ENV_NONE) || (nextbase == mBaseDayInstance) ||
+ (!mSkyExperience.isNull() && !mWaterExperience.isNull()))
+ { // base instance completely overridden, or not changed no transition will happen
+ return;
+ }
+
+ LL_WARNS("PUSHENV") << "Underlying environment has changed (" << env << ")! Base env is type " << base_env << LL_ENDL;
+
+ LLEnvironment::DayInstance::ptr_t trans = std::make_shared(std::static_pointer_cast(shared_from_this()),
+ mBaseDayInstance->getSky(), mBaseDayInstance->getWater(), nextbase, LLEnvironment::TRANSITION_DEFAULT);
+
+ trans->animate();
+ setBaseDayInstance(trans);
+ }
+ }
+
+ void DayInjection::onParcelChange()
+ {
+ S32 parcel_id(INVALID_PARCEL_ID);
+ LLParcel* parcel = LLViewerParcelMgr::instance().getAgentParcel();
+
+ if (!parcel)
+ return;
+
+ parcel_id = parcel->getLocalID();
+
+ testExperiencesOnParcel(parcel_id);
+ }
+
+ void DayInjection::checkExperience()
+ {
+ if ((!mDayExperience.isNull()) && (mSkyExperience != mDayExperience) && (mWaterExperience != mDayExperience))
+ { // There was a day experience but we've replaced it with a water and a sky experience.
+ mDayExperience.setNull();
+ mBaseDayInstance = LLEnvironment::instance().getSharedEnvironmentInstance();
+ }
+ }
+
+ void DayInjection::animate()
+ {
+
+ }
+
+ void InjectedTransition::animate()
+ {
+ mNextInstance->animate();
+
+ if (!mInjection->isOverriddenSky())
+ {
+ mSky = mStartSky->buildClone();
+ mBlenderSky = std::make_shared(mSky, mStartSky, mNextInstance->getSky(), mTransitionTime);
+ mBlenderSky->setOnFinished(
+ [this](LLSettingsBlender::ptr_t blender) {
+ mBlenderSky.reset();
+
+ if (!mBlenderSky && !mBlenderSky)
+ mInjection->setBaseDayInstance(mNextInstance);
+ else
+ mInjection->mInjectedSky->setSource(mNextInstance->getSky());
+ });
+ }
+ else
+ {
+ mSky = mInjection->getSky();
+ mBlenderSky.reset();
+ }
+
+ if (!mInjection->isOverriddenWater())
+ {
+ mWater = mStartWater->buildClone();
+ mBlenderWater = std::make_shared(mWater, mStartWater, mNextInstance->getWater(), mTransitionTime);
+ mBlenderWater->setOnFinished(
+ [this](LLSettingsBlender::ptr_t blender) {
+ mBlenderWater.reset();
+
+ if (!mBlenderSky && !mBlenderWater)
+ mInjection->setBaseDayInstance(mNextInstance);
+ else
+ mInjection->mInjectedWater->setSource(mNextInstance->getWater());
+ });
+ }
+ else
+ {
+ mWater = mInjection->getWater();
+ mBlenderWater.reset();
+ }
+
+ }
+
+}
+
diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h
new file mode 100644
index 0000000000..ce69d7ea3a
--- /dev/null
+++ b/indra/newview/llenvironment.h
@@ -0,0 +1,484 @@
+/**
+ * @file llenvmanager.h
+ * @brief Declaration of classes managing WindLight and water settings.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_ENVIRONMENT_H
+#define LL_ENVIRONMENT_H
+
+#include "llsingleton.h"
+#include "llmemory.h"
+#include "llsd.h"
+
+#include "llsettingsbase.h"
+#include "llsettingssky.h"
+#include "llsettingswater.h"
+#include "llsettingsdaycycle.h"
+
+#include "llatmosphere.h"
+
+#include
+
+//-------------------------------------------------------------------------
+class LLViewerCamera;
+class LLGLSLShader;
+class LLParcel;
+
+//-------------------------------------------------------------------------
+class LLEnvironment : public LLSingleton
+{
+ LLSINGLETON_C11(LLEnvironment);
+ LOG_CLASS(LLEnvironment);
+
+public:
+ static const F32Seconds TRANSITION_INSTANT;
+ static const F32Seconds TRANSITION_FAST;
+ static const F32Seconds TRANSITION_DEFAULT;
+ static const F32Seconds TRANSITION_SLOW;
+ static const F32Seconds TRANSITION_ALTITUDE;
+
+ static const LLUUID KNOWN_SKY_SUNRISE;
+ static const LLUUID KNOWN_SKY_MIDDAY;
+ static const LLUUID KNOWN_SKY_SUNSET;
+ static const LLUUID KNOWN_SKY_MIDNIGHT;
+
+ static const S32 NO_TRACK;
+ static const S32 NO_VERSION;
+ static const S32 VERSION_CLEANUP;
+
+ struct EnvironmentInfo
+ {
+ EnvironmentInfo();
+
+ typedef std::shared_ptr ptr_t;
+ typedef std::array namelist_t;
+
+ S32 mParcelId;
+ LLUUID mRegionId;
+ S64Seconds mDayLength;
+ S64Seconds mDayOffset;
+ size_t mDayHash;
+ LLSettingsDay::ptr_t mDayCycle;
+ std::array mAltitudes;
+ bool mIsDefault;
+ LLUUID mAssetId;
+ bool mIsLegacy;
+ std::string mDayCycleName;
+ namelist_t mNameList;
+ S32 mEnvVersion;
+
+ static ptr_t extract(LLSD);
+ static ptr_t extractLegacy(LLSD);
+ };
+
+ enum EnvSelection_t
+ {
+ ENV_EDIT = 0,
+ ENV_LOCAL,
+ ENV_PUSH,
+ ENV_PARCEL,
+ ENV_REGION,
+ ENV_DEFAULT,
+ ENV_END,
+ ENV_CURRENT = -1,
+ ENV_NONE = -2
+ };
+
+ typedef boost::signals2::connection connection_t;
+
+ typedef std::pair fixedEnvironment_t;
+ typedef std::function environment_apply_fn;
+ typedef boost::signals2::signal env_changed_signal_t;
+ typedef env_changed_signal_t::slot_type env_changed_fn;
+ typedef std::array altitude_list_t;
+ typedef std::vector altitudes_vect_t;
+
+ virtual ~LLEnvironment();
+
+ bool canEdit() const;
+ bool isExtendedEnvironmentEnabled() const;
+ bool isInventoryEnabled() const;
+ bool canAgentUpdateParcelEnvironment() const;
+ bool canAgentUpdateParcelEnvironment(LLParcel *parcel) const;
+ bool canAgentUpdateRegionEnvironment() const;
+
+ LLSettingsDay::ptr_t getCurrentDay() const { return mCurrentEnvironment->getDayCycle(); }
+ LLSettingsSky::ptr_t getCurrentSky() const;
+ LLSettingsWater::ptr_t getCurrentWater() const;
+
+ static void getAtmosphericModelSettings(AtmosphericModelSettings& settingsOut, const LLSettingsSky::ptr_t &psky);
+
+ void update(const LLViewerCamera * cam);
+
+ static void updateGLVariablesForSettings(LLGLSLShader *shader, const LLSettingsBase::ptr_t &psetting);
+ void updateShaderUniforms(LLGLSLShader *shader);
+
+ void setSelectedEnvironment(EnvSelection_t env, LLSettingsBase::Seconds transition = TRANSITION_DEFAULT, bool forced = false);
+ EnvSelection_t getSelectedEnvironment() const { return mSelectedEnvironment; }
+
+ bool hasEnvironment(EnvSelection_t env);
+ void setEnvironment(EnvSelection_t env, const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, S32 env_version = NO_VERSION);
+ void setEnvironment(EnvSelection_t env, fixedEnvironment_t fixed, S32 env_version = NO_VERSION);
+ void setEnvironment(EnvSelection_t env, const LLSettingsBase::ptr_t &fixed, S32 env_version = NO_VERSION);
+ void setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixed, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(fixed, LLSettingsWater::ptr_t()), env_version); }
+ void setEnvironment(EnvSelection_t env, const LLSettingsWater::ptr_t & fixed, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(LLSettingsSky::ptr_t(), fixed), env_version); }
+ void setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixeds, const LLSettingsWater::ptr_t & fixedw, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(fixeds, fixedw), env_version); }
+ void setEnvironment(EnvSelection_t env, const LLUUID &assetId, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, S32 env_version = NO_VERSION);
+ void setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version = NO_VERSION);
+
+ void setSharedEnvironment();
+
+ void clearEnvironment(EnvSelection_t env);
+ LLSettingsDay::ptr_t getEnvironmentDay(EnvSelection_t env);
+ LLSettingsDay::Seconds getEnvironmentDayLength(EnvSelection_t env);
+ LLSettingsDay::Seconds getEnvironmentDayOffset(EnvSelection_t env);
+ fixedEnvironment_t getEnvironmentFixed(EnvSelection_t env, bool resolve = false);
+ LLSettingsSky::ptr_t getEnvironmentFixedSky(EnvSelection_t env, bool resolve = false) { return getEnvironmentFixed(env, resolve).first; };
+ LLSettingsWater::ptr_t getEnvironmentFixedWater(EnvSelection_t env, bool resolve = false) { return getEnvironmentFixed(env, resolve).second; };
+
+ void updateEnvironment(LLSettingsBase::Seconds transition = TRANSITION_DEFAULT, bool forced = false);
+
+ inline LLVector2 getCloudScrollDelta() const { return mCloudScrollDelta; }
+ void pauseCloudScroll() { mCloudScrollPaused = true; }
+ void resumeCloudScroll() { mCloudScrollPaused = false; }
+ bool isCloudScrollPaused() const { return mCloudScrollPaused; }
+
+ F32 getCamHeight() const;
+ F32 getWaterHeight() const;
+ bool getIsSunUp() const;
+ bool getIsMoonUp() const;
+
+ void saveToSettings();
+ bool loadFromSettings();
+ void saveBeaconsState();
+ void revertBeaconsState();
+
+ // Returns either sun or moon direction (depending on which is up and stronger)
+ // Light direction in +x right, +z up, +y at internal coord sys
+ LLVector3 getLightDirection() const; // returns sun or moon depending on which is up
+ LLVector3 getSunDirection() const;
+ LLVector3 getMoonDirection() const;
+
+ // Returns light direction converted to CFR coord system
+ LLVector4 getLightDirectionCFR() const; // returns sun or moon depending on which is up
+ LLVector4 getSunDirectionCFR() const;
+ LLVector4 getMoonDirectionCFR() const;
+
+ // Returns light direction converted to OGL coord system
+ // and clamped above -0.1f in Y to avoid render artifacts in sky shaders
+ LLVector4 getClampedLightNorm() const; // returns sun or moon depending on which is up
+ LLVector4 getClampedSunNorm() const;
+ LLVector4 getClampedMoonNorm() const;
+
+ // Returns light direction converted to OGL coord system
+ // and rotated by last cam yaw needed by water rendering shaders
+ LLVector4 getRotatedLightNorm() const;
+
+ static LLSettingsWater::ptr_t createWaterFromLegacyPreset(const std::string filename, LLSD &messages);
+ static LLSettingsSky::ptr_t createSkyFromLegacyPreset(const std::string filename, LLSD &messages);
+ static LLSettingsDay::ptr_t createDayCycleFromLegacyPreset(const std::string filename, LLSD &messages);
+
+ // Construct a new day cycle based on the environment. Replacing either the water or the sky tracks.
+ LLSettingsDay::ptr_t createDayCycleFromEnvironment(EnvSelection_t env, LLSettingsBase::ptr_t settings);
+
+ F32 getProgress() const { return (mCurrentEnvironment) ? mCurrentEnvironment->getProgress() : -1.0f; }
+ F32 getRegionProgress() const { return (mEnvironments[ENV_REGION]) ? mEnvironments[ENV_REGION]->getProgress() : -1.0f; }
+ void adjustRegionOffset(F32 adjust); // only used on legacy regions, to better sync the viewer with other agents
+
+ //-------------------------------------------
+ connection_t setEnvironmentChanged(env_changed_fn cb) { return mSignalEnvChanged.connect(cb); }
+
+ void requestRegion(environment_apply_fn cb = environment_apply_fn());
+ void updateRegion(const LLUUID &asset_id, std::string display_name, S32 track_num, S32 day_length, S32 day_offset, U32 flags, altitudes_vect_t altitudes = altitudes_vect_t(), environment_apply_fn cb = environment_apply_fn());
+ void updateRegion(const LLSettingsDay::ptr_t &pday, S32 day_length, S32 day_offset, altitudes_vect_t altitudes = altitudes_vect_t(), environment_apply_fn cb = environment_apply_fn());
+ void updateRegion(const LLSettingsSky::ptr_t &psky, S32 day_length, S32 day_offset, altitudes_vect_t altitudes = altitudes_vect_t(), environment_apply_fn cb = environment_apply_fn());
+ void updateRegion(const LLSettingsWater::ptr_t &pwater, S32 day_length, S32 day_offset, altitudes_vect_t altitudes = altitudes_vect_t(), environment_apply_fn cb = environment_apply_fn());
+ void resetRegion(environment_apply_fn cb = environment_apply_fn());
+ void requestParcel(S32 parcel_id, environment_apply_fn cb = environment_apply_fn());
+ void updateParcel(S32 parcel_id, const LLUUID &asset_id, std::string display_name, S32 track_num, S32 day_length, S32 day_offset, U32 flags, altitudes_vect_t altitudes = altitudes_vect_t(), environment_apply_fn cb = environment_apply_fn());
+ void updateParcel(S32 parcel_id, const LLSettingsDay::ptr_t &pday, S32 track_num, S32 day_length, S32 day_offset, altitudes_vect_t altitudes = altitudes_vect_t(), environment_apply_fn cb = environment_apply_fn());
+ void updateParcel(S32 parcel_id, const LLSettingsDay::ptr_t &pday, S32 day_length, S32 day_offset, altitudes_vect_t altitudes = altitudes_vect_t(), environment_apply_fn cb = environment_apply_fn());
+ void updateParcel(S32 parcel_id, const LLSettingsSky::ptr_t &psky, S32 day_length, S32 day_offset, altitudes_vect_t altitudes = altitudes_vect_t(), environment_apply_fn cb = environment_apply_fn());
+ void updateParcel(S32 parcel_id, const LLSettingsWater::ptr_t &pwater, S32 day_length, S32 day_offset, altitudes_vect_t altitudes = altitudes_vect_t(), environment_apply_fn cb = environment_apply_fn());
+ void resetParcel(S32 parcel_id, environment_apply_fn cb = environment_apply_fn());
+
+ void selectAgentEnvironment();
+
+ S32 calculateSkyTrackForAltitude(F64 altitude);
+
+ const altitude_list_t & getRegionAltitudes() const { return mTrackAltitudes; }
+
+ void handleEnvironmentPush(LLSD &message);
+
+ class DayInstance: public std::enable_shared_from_this
+ {
+ public:
+ typedef std::shared_ptr ptr_t;
+
+ static const U32 NO_ANIMATE_SKY;
+ static const U32 NO_ANIMATE_WATER;
+
+ DayInstance(EnvSelection_t env);
+ virtual ~DayInstance() { };
+
+ virtual ptr_t clone() const;
+
+ virtual bool applyTimeDelta(const LLSettingsBase::Seconds& delta);
+
+ virtual void setDay(const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset);
+ virtual void setSky(const LLSettingsSky::ptr_t &psky);
+ virtual void setWater(const LLSettingsWater::ptr_t &pwater);
+
+ void initialize();
+ bool isInitialized();
+
+ void clear();
+
+ void setSkyTrack(S32 trackno);
+
+ LLSettingsDay::ptr_t getDayCycle() const { return mDayCycle; }
+ LLSettingsSky::ptr_t getSky() const { return mSky; }
+ LLSettingsWater::ptr_t getWater() const { return mWater; }
+ LLSettingsDay::Seconds getDayLength() const { return mDayLength; }
+ LLSettingsDay::Seconds getDayOffset() const { return mDayOffset; }
+ LLSettingsDay::Seconds getDayOffsetOverride() const { return mDayOffsetOverride; } //KC
+ S32 getSkyTrack() const { return mSkyTrack; }
+
+ void setDayOffset(LLSettingsBase::Seconds offset) { mDayOffset = offset; animate(); }
+ void setDayOffsetOverride(LLSettingsBase::Seconds offset) { mDayOffsetOverride = offset; animate(); } //KC
+
+ virtual void animate();
+
+ void setBlenders(const LLSettingsBlender::ptr_t &skyblend, const LLSettingsBlender::ptr_t &waterblend);
+
+ EnvSelection_t getEnvironmentSelection() const { return mEnv; }
+ void setEnvironmentSelection(EnvSelection_t env) { mEnv = env; }
+
+ LLSettingsBase::TrackPosition getProgress() const;
+
+ void setFlags(U32 flag) { mAnimateFlags |= flag; }
+ void clearFlags(U32 flag) { mAnimateFlags &= ~flag; }
+ U32 getFlags() { return mAnimateFlags; }
+
+ protected:
+
+
+ LLSettingsDay::ptr_t mDayCycle;
+ LLSettingsSky::ptr_t mSky;
+ LLSettingsWater::ptr_t mWater;
+ S32 mSkyTrack;
+
+ bool mInitialized;
+
+ LLSettingsDay::Seconds mDayLength;
+ LLSettingsDay::Seconds mDayOffset;
+ LLSettingsDay::Seconds mDayOffsetOverride;
+ S32 mLastTrackAltitude;
+
+ LLSettingsBlender::ptr_t mBlenderSky;
+ LLSettingsBlender::ptr_t mBlenderWater;
+
+ EnvSelection_t mEnv;
+
+ U32 mAnimateFlags;
+
+ LLSettingsBase::TrackPosition secondsToKeyframe(LLSettingsDay::Seconds seconds);
+ };
+
+ class DayTransition : public DayInstance
+ {
+ public:
+ DayTransition(const LLSettingsSky::ptr_t &skystart, const LLSettingsWater::ptr_t &waterstart, DayInstance::ptr_t &end, LLSettingsDay::Seconds time);
+ virtual ~DayTransition() { };
+
+ virtual bool applyTimeDelta(const LLSettingsBase::Seconds& delta) override;
+ virtual void animate() override;
+
+ protected:
+ LLSettingsSky::ptr_t mStartSky;
+ LLSettingsWater::ptr_t mStartWater;
+ DayInstance::ptr_t mNextInstance;
+ LLSettingsDay::Seconds mTransitionTime;
+ };
+
+ DayInstance::ptr_t getSelectedEnvironmentInstance();
+ DayInstance::ptr_t getSharedEnvironmentInstance();
+
+//
+public:
+ LLSettingsDay::Seconds getDayLength() const { return (mCurrentEnvironment) ? mCurrentEnvironment->getDayLength() : LLSettingsDay::MINIMUM_DAYOFFSET; }
+ LLSettingsDay::Seconds getDayOffset() const { return (mCurrentEnvironment) ? mCurrentEnvironment->getDayOffset() : LLSettingsDay::INVALID_DAYOFFSET; }
+ void setDayOffsetOverride(LLSettingsBase::Seconds offset) { if (mCurrentEnvironment) mCurrentEnvironment->setDayOffsetOverride(offset); }
+ LLSettingsDay::Seconds getDayOffsetOverride() const { return (mCurrentEnvironment) ? mCurrentEnvironment->getDayOffsetOverride() : LLSettingsDay::MINIMUM_DAYOFFSET; }
+//
+
+protected:
+ virtual void initSingleton() override;
+ virtual void cleanupSingleton() override;
+
+
+private:
+ LLVector4 toCFR(const LLVector3 vec) const;
+ LLVector4 toLightNorm(const LLVector3 vec) const;
+
+ typedef std::array InstanceArray_t;
+
+ struct ExpEnvironmentEntry
+ {
+ typedef std::shared_ptr ptr_t;
+
+ S32Seconds mTime;
+ LLUUID mExperienceId;
+ LLSD mEnvironmentOverrides;
+ };
+ typedef std::deque mPushOverrides;
+
+ LLUUID mPushEnvironmentExpId;
+
+ static const F32 SUN_DELTA_YAW;
+ F32 mLastCamYaw = 0.0f;
+
+ LLVector2 mCloudScrollDelta; // cumulative cloud delta
+ bool mCloudScrollPaused;
+
+ InstanceArray_t mEnvironments;
+
+ EnvSelection_t mSelectedEnvironment;
+ DayInstance::ptr_t mCurrentEnvironment;
+
+ LLSettingsSky::ptr_t mSelectedSky;
+ LLSettingsWater::ptr_t mSelectedWater;
+ LLSettingsDay::ptr_t mSelectedDay;
+
+ LLSettingsBlender::ptr_t mBlenderSky;
+ LLSettingsBlender::ptr_t mBlenderWater;
+
+ env_changed_signal_t mSignalEnvChanged;
+
+ S32 mCurrentTrack;
+ altitude_list_t mTrackAltitudes;
+
+ LLSD mSkyOverrides;
+ LLSD mWaterOverrides;
+ typedef std::map experience_overrides_t;
+ experience_overrides_t mExperienceOverrides;
+
+ DayInstance::ptr_t getEnvironmentInstance(EnvSelection_t env, bool create = false);
+
+ void updateCloudScroll();
+
+ void onRegionChange();
+ void onParcelChange();
+
+ bool mShowSunBeacon;
+ bool mShowMoonBeacon;
+ S32 mEditorCounter;
+
+ struct UpdateInfo
+ {
+ typedef std::shared_ptr ptr_t;
+
+ UpdateInfo(LLSettingsDay::ptr_t pday, S32 day_length, S32 day_offset, altitudes_vect_t altitudes):
+ mDayp(pday),
+ mSettingsAsset(),
+ mDayLength(day_length),
+ mDayOffset(day_offset),
+ mAltitudes(altitudes),
+ mDayName(),
+ mFlags(0)
+ {
+ if (mDayp)
+ {
+ mDayName = mDayp->getName();
+ mFlags = mDayp->getFlags();
+ }
+ }
+
+ UpdateInfo(LLUUID settings_asset, std::string name, S32 day_length, S32 day_offset, altitudes_vect_t altitudes, U32 flags) :
+ mDayp(),
+ mSettingsAsset(settings_asset),
+ mDayLength(day_length),
+ mDayOffset(day_offset),
+ mAltitudes(altitudes),
+ mDayName(name),
+ mFlags(flags)
+ {}
+
+ LLSettingsDay::ptr_t mDayp;
+ LLUUID mSettingsAsset;
+ S32 mDayLength;
+ S32 mDayOffset;
+ altitudes_vect_t mAltitudes;
+ std::string mDayName;
+ U32 mFlags;
+ };
+
+ void coroRequestEnvironment(S32 parcel_id, environment_apply_fn apply);
+ void coroUpdateEnvironment(S32 parcel_id, S32 track_no, UpdateInfo::ptr_t updates, environment_apply_fn apply);
+ void coroResetEnvironment(S32 parcel_id, S32 track_no, environment_apply_fn apply);
+
+ void recordEnvironment(S32 parcel_id, EnvironmentInfo::ptr_t environment, LLSettingsBase::Seconds transition);
+
+ void onAgentPositionHasChanged(const LLVector3 &localpos);
+
+ void onSetEnvAssetLoaded(EnvSelection_t env, LLUUID asset_id, LLSettingsBase::ptr_t settings, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, LLSettingsBase::Seconds transition, S32 status, S32 env_version);
+ void onUpdateParcelAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 parcel_id, S32 day_length, S32 day_offset, altitudes_vect_t altitudes);
+
+ void handleEnvironmentPushClear(LLUUID experience_id, LLSD &message, F32 transition);
+ void handleEnvironmentPushFull(LLUUID experience_id, LLSD &message, F32 transition);
+ void handleEnvironmentPushPartial(LLUUID experience_id, LLSD &message, F32 transition);
+
+ void clearExperienceEnvironment(LLUUID experience_id, LLSettingsBase::Seconds transition_time);
+ void setExperienceEnvironment(LLUUID experience_id, LLUUID asset_id, F32 transition_time);
+ void setExperienceEnvironment(LLUUID experience_id, LLSD environment, F32 transition_time);
+ void onSetExperienceEnvAssetLoaded(LLUUID experience_id, LLSettingsBase::ptr_t setting, F32 transition_time, S32 status);
+
+ void listenExperiencePump(const LLSD &message);
+
+};
+
+class LLTrackBlenderLoopingManual : public LLSettingsBlender
+{
+public:
+ LLTrackBlenderLoopingManual(const LLSettingsBase::ptr_t &target, const LLSettingsDay::ptr_t &day, S32 trackno);
+
+ F64 setPosition(const LLSettingsBase::TrackPosition& position);
+ virtual void switchTrack(S32 trackno, const LLSettingsBase::TrackPosition& position) override;
+ S32 getTrack() const { return mTrackNo; }
+
+ typedef std::shared_ptr ptr_t;
+protected:
+ LLSettingsDay::TrackBound_t getBoundingEntries(F64 position);
+ F64 getSpanLength(const LLSettingsDay::TrackBound_t &bounds) const;
+
+private:
+ LLSettingsDay::ptr_t mDay;
+ S32 mTrackNo;
+ F64 mPosition;
+
+ LLSettingsDay::CycleTrack_t::iterator mEndMarker;
+};
+
+#endif // LL_ENVIRONMENT_H
+
diff --git a/indra/newview/llenvmanager.cpp b/indra/newview/llenvmanager.cpp
deleted file mode 100644
index aac05e7c9b..0000000000
--- a/indra/newview/llenvmanager.cpp
+++ /dev/null
@@ -1,843 +0,0 @@
-/**
- * @file llenvmanager.cpp
- * @brief Implementation of classes managing WindLight and water settings.
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llenvmanager.h"
-
-#include "llagent.h"
-#include "lldaycyclemanager.h"
-#include "llviewercontrol.h" // for gSavedSettings
-#include "llviewerregion.h"
-#include "llwaterparammanager.h"
-#include "llwlhandlers.h"
-#include "llwlparammanager.h"
-#include "lltrans.h"
-// [RLVa:KB] - Checked: 2011-09-04 (RLVa-1.4.1a) | Added: RLVa-1.4.1a
-#include
-#include "rlvhandler.h"
-// [/RLVa:KB]
-#include "kcwlinterface.h"
-#include "quickprefs.h"
-
-std::string LLWLParamKey::toString() const
-{
- switch (scope)
- {
- case SCOPE_LOCAL:
- return name + std::string(" (") + LLTrans::getString("Local") + std::string(")");
- break;
- case SCOPE_REGION:
- return name + std::string(" (") + LLTrans::getString("Region") + std::string(")");
- break;
- default:
- return name + " (?)";
- }
-}
-
-std::string LLEnvPrefs::getWaterPresetName() const
-{
- if (mWaterPresetName.empty())
- {
- LL_WARNS() << "Water preset name is empty" << LL_ENDL;
- }
-
- return mWaterPresetName;
-}
-
-std::string LLEnvPrefs::getSkyPresetName() const
-{
- if (mSkyPresetName.empty())
- {
- LL_WARNS() << "Sky preset name is empty" << LL_ENDL;
- }
-
- return mSkyPresetName;
-}
-
-std::string LLEnvPrefs::getDayCycleName() const
-{
- if (mDayCycleName.empty())
- {
- LL_WARNS() << "Day cycle name is empty" << LL_ENDL;
- }
-
- return mDayCycleName;
-}
-
-void LLEnvPrefs::setUseRegionSettings(bool val)
-{
- mUseRegionSettings = val;
-}
-
-void LLEnvPrefs::setUseWaterPreset(const std::string& name)
-{
- mUseRegionSettings = false;
- mWaterPresetName = name;
-}
-
-void LLEnvPrefs::setUseSkyPreset(const std::string& name)
-{
- mUseRegionSettings = false;
- mUseDayCycle = false;
- mSkyPresetName = name;
-}
-
-void LLEnvPrefs::setUseDayCycle(const std::string& name)
-{
- mUseRegionSettings = false;
- mUseDayCycle = true;
- mDayCycleName = name;
-}
-
-//=============================================================================
-LLEnvManagerNew::LLEnvManagerNew():
- mInterpNextChangeMessage(true),
- mCurRegionUUID(LLUUID::null),
- mLastReceivedID(LLUUID::null)
-{
-
- // Set default environment settings.
- mUserPrefs.mUseRegionSettings = true;
- mUserPrefs.mUseDayCycle = true;
- mUserPrefs.mWaterPresetName = "Default";
- mUserPrefs.mSkyPresetName = "Default";
- mUserPrefs.mDayCycleName = "Default";
-
- LL_DEBUGS("Windlight")< Quickprefs integration
- FloaterQuickPrefs::updateParam(QP_PARAM_WATER, name);
-
- LL_DEBUGS("Windlight") << "Displaying water preset " << name << LL_ENDL;
- LLWaterParamManager& water_mgr = LLWaterParamManager::instance();
- bool rslt = water_mgr.getParamSet(name, water_mgr.mCurParams);
- llassert(rslt == true);
- return rslt;
-}
-
-bool LLEnvManagerNew::useWaterParams(const LLSD& params)
-{
- LL_DEBUGS("Windlight") << "Displaying water params" << LL_ENDL;
- LLWaterParamManager::instance().mCurParams.setAll(params);
- return true;
-}
-
-bool LLEnvManagerNew::useSkyPreset(const std::string& name, bool interpolate /*= false*/)
-{
- LLWLParamManager& sky_mgr = LLWLParamManager::instance();
- LLWLParamSet param_set;
-
- if (!sky_mgr.getParamSet(LLWLParamKey(name, LLEnvKey::SCOPE_LOCAL), param_set))
- {
- LL_WARNS() << "No sky preset named " << name << LL_ENDL;
- return false;
- }
-
- // Quickprefs integration
- FloaterQuickPrefs::updateParam(QP_PARAM_SKY, name);
-
- LL_DEBUGS("Windlight") << "Displaying sky preset " << name << LL_ENDL;
- sky_mgr.applySkyParams(param_set.getAll(), interpolate);
- return true;
-}
-
-bool LLEnvManagerNew::useSkyParams(const LLSD& params)
-{
- LL_DEBUGS("Windlight") << "Displaying sky params" << LL_ENDL;
- LLWLParamManager::instance().applySkyParams(params);
- return true;
-}
-
-bool LLEnvManagerNew::useDayCycle(const std::string& name, LLEnvKey::EScope scope)
-{
- LLSD params;
-
- if (scope == LLEnvKey::SCOPE_REGION)
- {
- LL_DEBUGS("Windlight") << "Displaying region day cycle " << name << LL_ENDL;
- params = getRegionSettings().getWLDayCycle();
-
- // Quickprefs integration
- FloaterQuickPrefs::updateParam(QP_PARAM_DAYCYCLE, PRESET_NAME_REGION_DEFAULT);
- }
- else
- {
- LL_DEBUGS("Windlight") << "Displaying local day cycle " << name << LL_ENDL;
-
- if (!LLDayCycleManager::instance().getPreset(name, params))
- {
- LL_WARNS() << "No day cycle named " << name << LL_ENDL;
- return false;
- }
-
- // Quickprefs integration
- FloaterQuickPrefs::updateParam(QP_PARAM_DAYCYCLE, name);
- }
-
- bool rslt = LLWLParamManager::instance().applyDayCycleParams(params, scope);
- llassert(rslt == true);
- return rslt;
-}
-
-bool LLEnvManagerNew::useDayCycleParams(const LLSD& params, LLEnvKey::EScope scope, F32 time /* = 0.5*/)
-{
- LL_DEBUGS("Windlight") << "Displaying day cycle params" << LL_ENDL;
- return LLWLParamManager::instance().applyDayCycleParams(params, scope);
-}
-
-void LLEnvManagerNew::setUseRegionSettings(bool val, bool interpolate /*= false*/)
-{
- mUserPrefs.setUseRegionSettings(val);
- saveUserPrefs();
- updateManagersFromPrefs(interpolate);
-}
-
-void LLEnvManagerNew::setUseWaterPreset(const std::string& name, bool interpolate /*= false*/)
-{
- // *TODO: make sure the preset exists.
- if (name.empty())
- {
- LL_WARNS() << "Empty water preset name passed" << LL_ENDL;
- return;
- }
-
- mUserPrefs.setUseWaterPreset(name);
- saveUserPrefs();
- updateManagersFromPrefs(interpolate);
-}
-
-void LLEnvManagerNew::setUseSkyPreset(const std::string& name, bool interpolate /*= false*/)
-{
- // *TODO: make sure the preset exists.
- if (name.empty())
- {
- LL_WARNS() << "Empty sky preset name passed" << LL_ENDL;
- return;
- }
-
- mUserPrefs.setUseSkyPreset(name);
- saveUserPrefs();
- updateManagersFromPrefs(interpolate);
-}
-
-void LLEnvManagerNew::setUseDayCycle(const std::string& name, bool interpolate /*= false*/)
-{
- if (!LLDayCycleManager::instance().presetExists(name))
- {
- LL_WARNS() << "Invalid day cycle name passed" << LL_ENDL;
- return;
- }
-
- mUserPrefs.setUseDayCycle(name);
- saveUserPrefs();
- updateManagersFromPrefs(interpolate);
-}
-
-void LLEnvManagerNew::loadUserPrefs()
-{
- // operate on members directly to avoid side effects
- mUserPrefs.mWaterPresetName = gSavedSettings.getString("WaterPresetName");
- mUserPrefs.mSkyPresetName = gSavedSettings.getString("SkyPresetName");
- mUserPrefs.mDayCycleName = gSavedSettings.getString("DayCycleName");
-
- bool use_region_settings = gSavedSettings.getBOOL("EnvironmentPersistAcrossLogin") ? gSavedSettings.getBOOL("UseEnvironmentFromRegion") : true;
- mUserPrefs.mUseRegionSettings = use_region_settings;
- mUserPrefs.mUseDayCycle = gSavedSettings.getBOOL("UseDayCycle");
-
- if (mUserPrefs.mUseRegionSettings)
- {
- requestRegionSettings();
- }
-}
-
-void LLEnvManagerNew::saveUserPrefs()
-{
- gSavedSettings.setString("WaterPresetName", getWaterPresetName());
- gSavedSettings.setString("SkyPresetName", getSkyPresetName());
- gSavedSettings.setString("DayCycleName", getDayCycleName());
-
- gSavedSettings.setBOOL("UseEnvironmentFromRegion", getUseRegionSettings());
- gSavedSettings.setBOOL("UseDayCycle", getUseDayCycle());
-
- mUsePrefsChangeSignal();
-}
-
-void LLEnvManagerNew::setUserPrefs(
- const std::string& water_preset,
- const std::string& sky_preset,
- const std::string& day_cycle_preset,
- bool use_fixed_sky,
- // Allow interpolation
- //bool use_region_settings)
- bool use_region_settings,
- bool interpolate)
- //
-{
- // operate on members directly to avoid side effects
- mUserPrefs.mWaterPresetName = water_preset;
- mUserPrefs.mSkyPresetName = sky_preset;
- mUserPrefs.mDayCycleName = day_cycle_preset;
-
- mUserPrefs.mUseRegionSettings = use_region_settings;
- mUserPrefs.mUseDayCycle = !use_fixed_sky;
-
- saveUserPrefs();
- // Allow interpolation
- //updateManagersFromPrefs(false);
- updateManagersFromPrefs(interpolate);
- //
-}
-
-void LLEnvManagerNew::dumpUserPrefs()
-{
- LL_DEBUGS("Windlight") << "WaterPresetName: " << gSavedSettings.getString("WaterPresetName") << LL_ENDL;
- LL_DEBUGS("Windlight") << "SkyPresetName: " << gSavedSettings.getString("SkyPresetName") << LL_ENDL;
- LL_DEBUGS("Windlight") << "DayCycleName: " << gSavedSettings.getString("DayCycleName") << LL_ENDL;
-
- LL_DEBUGS("Windlight") << "UseEnvironmentFromRegion: " << gSavedSettings.getBOOL("UseEnvironmentFromRegion") << LL_ENDL;
- LL_DEBUGS("Windlight") << "UseDayCycle: " << gSavedSettings.getBOOL("UseDayCycle") << LL_ENDL;
-}
-
-void LLEnvManagerNew::dumpPresets()
-{
- const LLEnvironmentSettings& region_settings = getRegionSettings();
- std::string region_name = gAgent.getRegion() ? gAgent.getRegion()->getName() : "Unknown region";
-
- // Dump water presets.
- LL_DEBUGS("Windlight") << "Waters:" << LL_ENDL;
- if (region_settings.getWaterParams().size() != 0)
- {
- LL_DEBUGS("Windlight") << " - " << region_name << LL_ENDL;
- }
- LLWaterParamManager::preset_name_list_t water_presets;
- LLWaterParamManager::instance().getPresetNames(water_presets);
- for (LLWaterParamManager::preset_name_list_t::const_iterator it = water_presets.begin(); it != water_presets.end(); ++it)
- {
- LL_DEBUGS("Windlight") << " - " << *it << LL_ENDL;
- }
-
- // Dump sky presets.
- LL_DEBUGS("Windlight") << "Skies:" << LL_ENDL;
- LLWLParamManager::preset_key_list_t sky_preset_keys;
- LLWLParamManager::instance().getPresetKeys(sky_preset_keys);
- for (LLWLParamManager::preset_key_list_t::const_iterator it = sky_preset_keys.begin(); it != sky_preset_keys.end(); ++it)
- {
- std::string preset_name = it->name;
- std::string item_title;
-
- if (it->scope == LLEnvKey::SCOPE_LOCAL) // local preset
- {
- item_title = preset_name;
- }
- else // region preset
- {
- item_title = preset_name + " (" + region_name + ")";
- }
- LL_DEBUGS("Windlight") << " - " << item_title << LL_ENDL;
- }
-
- // Dump day cycles.
- LL_DEBUGS("Windlight") << "Days:" << LL_ENDL;
- const LLSD& cur_region_dc = region_settings.getWLDayCycle();
- if (cur_region_dc.size() != 0)
- {
- LL_DEBUGS("Windlight") << " - " << region_name << LL_ENDL;
- }
- LLDayCycleManager::preset_name_list_t days;
- LLDayCycleManager::instance().getPresetNames(days);
- for (LLDayCycleManager::preset_name_list_t::const_iterator it = days.begin(); it != days.end(); ++it)
- {
- LL_DEBUGS("Windlight") << " - " << *it << LL_ENDL;
- }
-}
-
-void LLEnvManagerNew::requestRegionSettings()
-{
- LL_DEBUGS("Windlight") << LL_ENDL;
- LLEnvironmentRequest::initiate();
-}
-
-bool LLEnvManagerNew::sendRegionSettings(const LLEnvironmentSettings& new_settings)
-{
- LLSD metadata;
-
- metadata["regionID"] = gAgent.getRegion()->getRegionID();
- // add last received update ID to outbound message so simulator can handle concurrent updates
- metadata["messageID"] = mLastReceivedID;
-
- return LLEnvironmentApply::initiateRequest(new_settings.makePacket(metadata));
-}
-
-boost::signals2::connection LLEnvManagerNew::setPreferencesChangeCallback(const prefs_change_signal_t::slot_type& cb)
-{
- return mUsePrefsChangeSignal.connect(cb);
-}
-
-boost::signals2::connection LLEnvManagerNew::setRegionSettingsChangeCallback(const region_settings_change_signal_t::slot_type& cb)
-{
- return mRegionSettingsChangeSignal.connect(cb);
-}
-
-boost::signals2::connection LLEnvManagerNew::setRegionSettingsAppliedCallback(const region_settings_applied_signal_t::slot_type& cb)
-{
- return mRegionSettingsAppliedSignal.connect(cb);
-}
-
-// static
-bool LLEnvManagerNew::canEditRegionSettings()
-{
- LLViewerRegion* region = gAgent.getRegion();
- BOOL owner_or_god = gAgent.isGodlike() || (region && region->getOwner() == gAgent.getID());
- BOOL owner_or_god_or_manager = owner_or_god || (region && region->isEstateManager());
-
- LL_DEBUGS("Windlight") << "Can edit region settings: " << (bool) owner_or_god_or_manager << LL_ENDL;
- return owner_or_god_or_manager;
-}
-
-// static
-const std::string LLEnvManagerNew::getScopeString(LLEnvKey::EScope scope)
-{
- switch(scope)
- {
- case LLEnvKey::SCOPE_LOCAL:
- return LLTrans::getString("LocalSettings");
- case LLEnvKey::SCOPE_REGION:
- return LLTrans::getString("RegionSettings");
- default:
- return " (?)";
- }
-}
-
-void LLEnvManagerNew::onRegionSettingsResponse(const LLSD& content)
-{
- // If the message was valid, grab the UUID from it and save it for next outbound update message.
- mLastReceivedID = content[0]["messageID"].asUUID();
-
- // Refresh cached region settings.
- LL_DEBUGS("Windlight") << "Received region environment settings: " << content << LL_ENDL;
- F32 sun_hour = 0; // *TODO
- LLEnvironmentSettings new_settings(content[1], content[2], content[3], sun_hour);
- mCachedRegionPrefs = new_settings;
-
- // Load region sky presets.
- LLWLParamManager::instance().refreshRegionPresets(getRegionSettings().getSkyMap());
-
- // Use the region settings if parcel settings didnt override it already
- if (!KCWindlightInterface::instance().haveParcelOverride(new_settings))
- {
- // If using server settings, update managers.
-// if (getUseRegionSettings())
-// [RLVa:KB] - Checked: 2011-08-29 (RLVa-1.4.1a) | Added: RLVa-1.4.1a
- if ( (getUseRegionSettings()) && (LLWLParamManager::getInstance()->mAnimator.getIsRunning()) )
-// [/RLVa:KB]
- {
- LL_DEBUGS("Windlight") << "Updating WL managers from prefs" << LL_ENDL;
- LLWLParamManager::getInstance()->mAnimator.stopInterpolation();
- updateManagersFromPrefs(mInterpNextChangeMessage);
- }
- //bit of a hacky override since I've repurposed many of the settings and methods here -KC
- //NOTE* It might not be a good idea to do this if under RLV_BHVR_SETENV -KC
- else if (gSavedSettings.getBOOL("UseEnvironmentFromRegionAlways")
- && !(rlv_handler_t::isEnabled() && gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)))
- {
- // reset all environmental settings to track the region defaults, make this reset 'sticky' like the other sun settings.
- LL_DEBUGS("Windlight") << "Resetting user prefs" << LL_ENDL;
- LLWLParamManager::getInstance()->mAnimator.stopInterpolation();
- setUserPrefs(getWaterPresetName(), getSkyPresetName(), getDayCycleName(), false, true, mInterpNextChangeMessage);
- }
- }
- //
-
- // Let interested parties know about the region settings update.
- mRegionSettingsChangeSignal();
-
-// FIRE-8063: Aurora-sim windlight refresh
- // reset
- //mInterpNextChangeMessage = false;
-//
-}
-
-void LLEnvManagerNew::onRegionSettingsApplyResponse(bool ok)
-{
- LL_DEBUGS("Windlight") << "Applying region settings " << (ok ? "succeeded" : "failed") << LL_ENDL;
-
- // Clear locally modified region settings because they have just been uploaded.
- mNewRegionPrefs.clear();
-
- mRegionSettingsAppliedSignal(ok);
-}
-
-//-- private methods ----------------------------------------------------------
-
-// virtual
-void LLEnvManagerNew::initSingleton()
-{
- LL_DEBUGS("Windlight") << "Initializing LLEnvManagerNew" << LL_ENDL;
-
- loadUserPrefs();
-
- // preferences loaded, can set params
- std::string preferred_day = getDayCycleName();
- if (!useDayCycle(preferred_day, LLEnvKey::SCOPE_LOCAL))
- {
- LL_WARNS() << "No day cycle named " << preferred_day << ", reverting LLWLParamManager to defaults" << LL_ENDL;
- LLWLParamManager::instance().setDefaultDay();
- }
-
- std::string sky = getSkyPresetName();
- if (!useSkyPreset(sky))
- {
- LL_WARNS() << "No sky preset named " << sky << ", falling back to defaults" << LL_ENDL;
- LLWLParamManager::instance().setDefaultSky();
-
- // *TODO: Fix user preferences accordingly.
- }
-
- LLWLParamManager::instance().resetAnimator(0.5 /*noon*/, getUseDayCycle());
-}
-
-void LLEnvManagerNew::updateSkyFromPrefs(bool interpolate /*= false*/)
-{
- bool success = true;
-
- // Sync sky with user prefs.
- if (getUseRegionSettings()) // apply region-wide settings
- {
- success = useRegionSky();
- }
- else // apply user-specified settings
- {
- if (getUseDayCycle())
- {
- success = useDayCycle(getDayCycleName(), LLEnvKey::SCOPE_LOCAL);
- }
- else
- {
- success = useSkyPreset(getSkyPresetName(), interpolate);
- }
- }
-
- // If something went wrong, fall back to defaults.
- if (!success)
- {
- // *TODO: fix user prefs
- useDefaultSky();
- }
-}
-
-void LLEnvManagerNew::updateWaterFromPrefs(bool interpolate)
-{
- LLWaterParamManager& water_mgr = LLWaterParamManager::instance();
- LLSD target_water_params;
-
- // Determine new water settings based on user prefs.
-
- {
- // Fall back to default water.
- LLWaterParamSet default_water;
- water_mgr.getParamSet("Default", default_water);
- target_water_params = default_water.getAll();
-
- // Quickprefs integration
- FloaterQuickPrefs::updateParam(QP_PARAM_WATER, "Default");
- }
-
- if (getUseRegionSettings())
- {
- // *TODO: make sure whether region settings belong to the current region?
- const LLSD& region_water_params = getRegionSettings().getWaterParams();
- if (region_water_params.size() != 0) // region has no water settings
- {
- LL_DEBUGS("Windlight") << "Applying region water" << LL_ENDL;
- target_water_params = region_water_params;
-
- // Quickprefs integration
- FloaterQuickPrefs::updateParam(QP_PARAM_WATER, PRESET_NAME_REGION_DEFAULT);
- }
- else
- {
- LL_DEBUGS("Windlight") << "Applying default water" << LL_ENDL;
- }
- }
- else
- {
- std::string water = getWaterPresetName();
- LL_DEBUGS("Windlight") << "Applying water preset [" << water << "]" << LL_ENDL;
- LLWaterParamSet params;
- if (!water_mgr.getParamSet(water, params))
- {
- LL_WARNS() << "No water preset named " << water << ", falling back to defaults" << LL_ENDL;
- water_mgr.getParamSet("Default", params);
-
- // *TODO: Fix user preferences accordingly.
- }
- // Quickprefs integration
- else
- {
- FloaterQuickPrefs::updateParam(QP_PARAM_WATER, water);
- }
- // Quickprefs integration
-
- target_water_params = params.getAll();
- }
-
- // Sync water with user prefs.
- water_mgr.applyParams(target_water_params, interpolate);
-}
-
-void LLEnvManagerNew::updateManagersFromPrefs(bool interpolate)
-{
- LL_DEBUGS("Windlight")< Quickprefs integration
- FloaterQuickPrefs::updateParam(QP_PARAM_SKY, PRESET_NAME_REGION_DEFAULT);
-
- LL_DEBUGS("Windlight") << "Applying region sky" << LL_ENDL;
-
- // *TODO: Support fixed sky from region. Just do sky reset for now.
- if (region_settings.getSkyMap().size() == 1)
- {
- // Region is set to fixed sky. Reset.
- useSkyParams(region_settings.getSkyMap().beginMap()->second);
- }
- return useDayCycleParams(
- region_settings.getWLDayCycle(),
- LLEnvKey::SCOPE_REGION,
- region_settings.getDayTime());
-}
-
-bool LLEnvManagerNew::useRegionWater()
-{
- const LLEnvironmentSettings& region_settings = getRegionSettings();
- const LLSD& region_water = region_settings.getWaterParams();
-
- // If region is set to defaults,
- if (region_water.size() == 0)
- {
- // well... apply the default water settings.
- return useDefaultWater();
- }
-
- // Quickprefs integration
- FloaterQuickPrefs::updateParam(QP_PARAM_WATER, LLSD(PRESET_NAME_REGION_DEFAULT));
-
- // Otherwise apply region water.
- LL_DEBUGS("Windlight") << "Applying region water" << LL_ENDL;
- return useWaterParams(region_water);
-}
-
-bool LLEnvManagerNew::useDefaultSky()
-{
- return useDayCycle("Default", LLEnvKey::SCOPE_LOCAL);
-}
-
-bool LLEnvManagerNew::useDefaultWater()
-{
- return useWaterPreset("Default");
-}
-
-
-void LLEnvManagerNew::onRegionChange()
-{
- // Avoid duplicating region setting requests
- // by checking whether the region is actually changing.
- LLViewerRegion* regionp = gAgent.getRegion();
- LLUUID region_uuid = regionp ? regionp->getRegionID() : LLUUID::null;
- if (region_uuid != mCurRegionUUID)
- {
- // Clear locally modified region settings.
- mNewRegionPrefs.clear();
-
- // *TODO: clear environment settings of the previous region?
-
- // Request environment settings of the new region.
- mCurRegionUUID = region_uuid;
- // for region crossings, interpolate the change; for teleports, don't
- mInterpNextChangeMessage = (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE);
- LL_DEBUGS("Windlight") << (mInterpNextChangeMessage ? "Crossed" : "Teleported")
- << " to new region: " << region_uuid
- << LL_ENDL;
- requestRegionSettings();
- }
- else
- {
- LL_DEBUGS("Windlight") << "disregarding region change; interp: "
- << (mInterpNextChangeMessage ? "true" : "false")
- << " regionp: " << regionp
- << " old: " << mCurRegionUUID
- << " new: " << region_uuid
- << LL_ENDL;
- }
-}
-
-// FIRE-8063: Aurora-sim windlight refresh
-class WindLightRefresh : public LLHTTPNode
-{
- /*virtual*/ void post(
- LLHTTPNode::ResponsePtr response,
- const LLSD& context,
- const LLSD& input) const
- {
- if (!input || !context || !input.isMap() || !input.has("body")) {
- LL_INFOS() << "malformed WindLightRefresh!" << LL_ENDL;
- return;
- }
-
- //std::string dump = input["body"].asString();
- //LL_WARNS() << dump << LL_ENDL;
-
- LLSD body = input["body"];
- LLEnvManagerNew *env = &LLEnvManagerNew::instance();
-
- LLViewerRegion* regionp = gAgent.getRegion();
- LLUUID region_uuid = regionp ? regionp->getRegionID() : LLUUID::null;
-
- env->mNewRegionPrefs.clear();
- env->mCurRegionUUID = region_uuid;
-
- if(body.has("Interpolate")) {
- if(body["Interpolate"].asInteger() == 1) {
- env->mInterpNextChangeMessage = true;
- }
- else {
- env->mInterpNextChangeMessage = false;
- }
- }
- else {
- env->mInterpNextChangeMessage = true;
- }
- LL_INFOS() << "Windlight Refresh , interpolate:" << env->mInterpNextChangeMessage << LL_ENDL;
- env->requestRegionSettings();
-
- // Ansa: This cause the windlight editor and others to update since the windlight has changed!
- gAgent.changeRegion();
- }
-};
-
-LLHTTPRegistration
-gHTTPRegistrationWindLightRefresh(
- "/message/WindLightRefresh");
-// FIRE-8063: Aurora-sim windlight refresh
diff --git a/indra/newview/llenvmanager.h b/indra/newview/llenvmanager.h
deleted file mode 100644
index 96bcc771c7..0000000000
--- a/indra/newview/llenvmanager.h
+++ /dev/null
@@ -1,361 +0,0 @@
-/**
- * @file llenvmanager.h
- * @brief Declaration of classes managing WindLight and water settings.
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLENVMANAGER_H
-#define LL_LLENVMANAGER_H
-
-#include "llmemory.h"
-#include "llsd.h"
-
-class LLWLParamManager;
-class LLWaterParamManager;
-class LLWLAnimator;
-// FIRE-8063: Aurora-sim windlight refresh
-class WindLightRefresh;
-//
-
-// generic key
-struct LLEnvKey
-{
-public:
- // Note: enum ordering is important; for example, a region-level floater (1) will see local and region (all values that are <=)
- typedef enum e_scope
- {
- SCOPE_LOCAL, // 0
- SCOPE_REGION//, // 1
- // SCOPE_ESTATE, // 2
- // etc.
- } EScope;
-};
-
-struct LLWLParamKey : LLEnvKey
-{
-public:
- // scope and source of a param set (WL sky preset)
- std::string name;
- EScope scope;
-
- // for conversion from LLSD
- static const int NAME_IDX = 0;
- static const int SCOPE_IDX = 1;
-
- inline LLWLParamKey(const std::string& n, EScope s)
- : name(n), scope(s)
- {
- }
-
- inline LLWLParamKey(LLSD llsd)
- : name(llsd[NAME_IDX].asString()), scope(EScope(llsd[SCOPE_IDX].asInteger()))
- {
- }
-
- inline LLWLParamKey() // NOT really valid, just so std::maps can return a default of some sort
- : name(""), scope(SCOPE_LOCAL)
- {
- }
-
- inline LLWLParamKey(std::string& stringVal)
- {
- size_t len = stringVal.length();
- if (len > 0)
- {
- name = stringVal.substr(0, len - 1);
- scope = (EScope) atoi(stringVal.substr(len - 1, len).c_str());
- }
- }
-
- inline std::string toStringVal() const
- {
- std::stringstream str;
- str << name << scope;
- return str.str();
- }
-
- inline LLSD toLLSD() const
- {
- LLSD llsd = LLSD::emptyArray();
- llsd.append(LLSD(name));
- llsd.append(LLSD(scope));
- return llsd;
- }
-
- inline void fromLLSD(const LLSD& llsd)
- {
- name = llsd[NAME_IDX].asString();
- scope = EScope(llsd[SCOPE_IDX].asInteger());
- }
-
- inline bool operator <(const LLWLParamKey other) const
- {
- if (name < other.name)
- {
- return true;
- }
- else if (name > other.name)
- {
- return false;
- }
- else
- {
- return scope < other.scope;
- }
- }
-
- inline bool operator ==(const LLWLParamKey other) const
- {
- return (name == other.name) && (scope == other.scope);
- }
-
- std::string toString() const;
-};
-
-class LLEnvironmentSettings
-{
-public:
- LLEnvironmentSettings() :
- mWLDayCycle(LLSD::emptyMap()),
- mSkyMap(LLSD::emptyMap()),
- mWaterParams(LLSD::emptyMap()),
- mDayTime(0.f)
- {}
- LLEnvironmentSettings(const LLSD& dayCycle, const LLSD& skyMap, const LLSD& waterParams, F64 dayTime) :
- mWLDayCycle(dayCycle),
- mSkyMap(skyMap),
- mWaterParams(waterParams),
- mDayTime(dayTime)
- {}
- ~LLEnvironmentSettings() {}
-
- void saveParams(const LLSD& dayCycle, const LLSD& skyMap, const LLSD& waterParams, F64 dayTime)
- {
- mWLDayCycle = dayCycle;
- mSkyMap = skyMap;
- mWaterParams = waterParams;
- mDayTime = dayTime;
- }
-
- const LLSD& getWLDayCycle() const
- {
- return mWLDayCycle;
- }
-
- const LLSD& getWaterParams() const
- {
- return mWaterParams;
- }
-
- const LLSD& getSkyMap() const
- {
- return mSkyMap;
- }
-
- F64 getDayTime() const
- {
- return mDayTime;
- }
-
- bool isEmpty() const
- {
- return mWLDayCycle.size() == 0;
- }
-
- void clear()
- {
- *this = LLEnvironmentSettings();
- }
-
- LLSD makePacket(const LLSD& metadata) const
- {
- LLSD full_packet = LLSD::emptyArray();
-
- // 0: metadata
- full_packet.append(metadata);
-
- // 1: day cycle
- full_packet.append(mWLDayCycle);
-
- // 2: map of sky setting names to sky settings (as LLSD)
- full_packet.append(mSkyMap);
-
- // 3: water params
- full_packet.append(mWaterParams);
-
- return full_packet;
- }
-
-private:
- LLSD mWLDayCycle, mWaterParams, mSkyMap;
- F64 mDayTime;
-};
-
-/**
- * User environment preferences.
- */
-class LLEnvPrefs
-{
-public:
- LLEnvPrefs() : mUseRegionSettings(true), mUseDayCycle(true) {}
-
- bool getUseRegionSettings() const { return mUseRegionSettings; }
- bool getUseDayCycle() const { return mUseDayCycle; }
- bool getUseFixedSky() const { return !getUseDayCycle(); }
-
- std::string getWaterPresetName() const;
- std::string getSkyPresetName() const;
- std::string getDayCycleName() const;
-
- void setUseRegionSettings(bool val);
- void setUseWaterPreset(const std::string& name);
- void setUseSkyPreset(const std::string& name);
- void setUseDayCycle(const std::string& name);
-
- bool mUseRegionSettings;
- bool mUseDayCycle;
- std::string mWaterPresetName;
- std::string mSkyPresetName;
- std::string mDayCycleName;
-};
-
-/**
- * Setting:
- * 1. Use region settings.
- * 2. Use my setting: + |
- */
-class LLEnvManagerNew : public LLSingleton
-{
- LLSINGLETON(LLEnvManagerNew);
- LOG_CLASS(LLEnvManagerNew);
-public:
- typedef boost::signals2::signal prefs_change_signal_t;
- typedef boost::signals2::signal region_settings_change_signal_t;
- typedef boost::signals2::signal region_settings_applied_signal_t;
-
- // getters to access user env. preferences
- bool getUseRegionSettings() const;
- bool getUseDayCycle() const;
- bool getUseFixedSky() const;
- std::string getWaterPresetName() const;
- std::string getSkyPresetName() const;
- std::string getDayCycleName() const;
-
- /// @return cached env. settings of the current region.
- const LLEnvironmentSettings& getRegionSettings() const;
-
- /**
- * Set new region settings without uploading them to the region.
- *
- * The override will be reset when the changes are applied to the region (=uploaded)
- * or user teleports to another region.
- */
- void setRegionSettings(const LLEnvironmentSettings& new_settings);
-
- // Change environment w/o changing user preferences.
- bool usePrefs();
- bool useDefaults();
- bool useRegionSettings();
- bool useWaterPreset(const std::string& name);
- bool useWaterParams(const LLSD& params);
- bool useSkyPreset(const std::string& name, bool interpolate = false);
- bool useSkyParams(const LLSD& params);
- bool useDayCycle(const std::string& name, LLEnvKey::EScope scope);
- bool useDayCycleParams(const LLSD& params, LLEnvKey::EScope scope, F32 time = 0.5);
-
- // setters for user env. preferences
- void setUseRegionSettings(bool val, bool interpolate = false);
- void setUseWaterPreset(const std::string& name, bool interpolate = false);
- void setUseSkyPreset(const std::string& name, bool interpolate = false);
- void setUseDayCycle(const std::string& name, bool interpolate = false);
- void setUserPrefs(
- const std::string& water_preset,
- const std::string& sky_preset,
- const std::string& day_cycle_preset,
- bool use_fixed_sky,
- // Allow interpolation
- //bool use_region_settings);
- bool use_region_settings,
- bool interpolate = false);
- //
-
- // debugging methods
- void dumpUserPrefs();
- void dumpPresets();
-
- // Misc.
- void requestRegionSettings();
- bool sendRegionSettings(const LLEnvironmentSettings& new_settings);
- boost::signals2::connection setPreferencesChangeCallback(const prefs_change_signal_t::slot_type& cb);
- boost::signals2::connection setRegionSettingsChangeCallback(const region_settings_change_signal_t::slot_type& cb);
- boost::signals2::connection setRegionSettingsAppliedCallback(const region_settings_applied_signal_t::slot_type& cb);
-
- static bool canEditRegionSettings(); /// @return true if we have access to editing region environment
- static const std::string getScopeString(LLEnvKey::EScope scope);
-
- // Public callbacks.
- void onRegionSettingsResponse(const LLSD& content);
- void onRegionSettingsApplyResponse(bool ok);
-
-private:
- /*virtual*/ void initSingleton();
-
- void loadUserPrefs();
- void saveUserPrefs();
-
- void updateSkyFromPrefs(bool interpolate = false);
- void updateWaterFromPrefs(bool interpolate);
- void updateManagersFromPrefs(bool interpolate);
-
-public:
- bool useRegionSky();
- bool useRegionWater();
-
-private:
-// FIRE-8063: Aurora-sim windlight refresh
- friend class WindLightRefresh;
-//
- bool useDefaultSky();
- bool useDefaultWater();
-
- void onRegionChange();
-
- /// Emitted when user environment preferences change.
- prefs_change_signal_t mUsePrefsChangeSignal;
-
- /// Emitted when region environment settings update comes.
- region_settings_change_signal_t mRegionSettingsChangeSignal;
-
- /// Emitted when agent region changes. Move to LLAgent?
- region_settings_applied_signal_t mRegionSettingsAppliedSignal;
-
- LLEnvPrefs mUserPrefs; /// User environment preferences.
- LLEnvironmentSettings mCachedRegionPrefs; /// Cached region environment settings.
- LLEnvironmentSettings mNewRegionPrefs; /// Not-yet-uploaded modified region env. settings.
- bool mInterpNextChangeMessage; /// Interpolate env. settings on next region change.
- LLUUID mCurRegionUUID; /// To avoid duplicated region env. settings requests.
- LLUUID mLastReceivedID; /// Id of last received region env. settings.
-};
-
-#endif // LL_LLENVMANAGER_H
-
diff --git a/indra/newview/llestateinfomodel.cpp b/indra/newview/llestateinfomodel.cpp
index 95d40be913..4fdb860592 100644
--- a/indra/newview/llestateinfomodel.cpp
+++ b/indra/newview/llestateinfomodel.cpp
@@ -73,6 +73,7 @@ bool LLEstateInfoModel::getDenyAnonymous() const { return getFlag(REGION_FLAGS
bool LLEstateInfoModel::getDenyAgeUnverified() const { return getFlag(REGION_FLAGS_DENY_AGEUNVERIFIED); }
bool LLEstateInfoModel::getAllowVoiceChat() const { return getFlag(REGION_FLAGS_ALLOW_VOICE); }
bool LLEstateInfoModel::getAllowAccessOverride() const { return getFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE); }
+bool LLEstateInfoModel::getAllowEnvironmentOverride() const { return getFlag(REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE); }
void LLEstateInfoModel::setUseFixedSun(bool val) { setFlag(REGION_FLAGS_SUN_FIXED, val); }
void LLEstateInfoModel::setIsExternallyVisible(bool val) { setFlag(REGION_FLAGS_EXTERNALLY_VISIBLE, val); }
@@ -81,6 +82,7 @@ void LLEstateInfoModel::setDenyAnonymous(bool val) { setFlag(REGION_FLAGS_DENY
void LLEstateInfoModel::setDenyAgeUnverified(bool val) { setFlag(REGION_FLAGS_DENY_AGEUNVERIFIED, val); }
void LLEstateInfoModel::setAllowVoiceChat(bool val) { setFlag(REGION_FLAGS_ALLOW_VOICE, val); }
void LLEstateInfoModel::setAllowAccessOverride(bool val) { setFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE, val); }
+void LLEstateInfoModel::setAllowEnvironmentOverride(bool val) { setFlag(REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE, val); }
void LLEstateInfoModel::update(const strings_t& strings)
{
@@ -222,6 +224,7 @@ std::string LLEstateInfoModel::getInfoDump()
dump["deny_age_unverified" ] = getDenyAgeUnverified();
dump["allow_voice_chat" ] = getAllowVoiceChat();
dump["override_public_access"] = getAllowAccessOverride();
+ dump["override_environment"] = getAllowEnvironmentOverride();
std::stringstream dump_str;
dump_str << dump;
diff --git a/indra/newview/llestateinfomodel.h b/indra/newview/llestateinfomodel.h
index 0082b5b1f4..d6f00c573c 100644
--- a/indra/newview/llestateinfomodel.h
+++ b/indra/newview/llestateinfomodel.h
@@ -56,6 +56,7 @@ public:
bool getDenyAgeUnverified() const;
bool getAllowVoiceChat() const;
bool getAllowAccessOverride() const;
+ bool getAllowEnvironmentOverride() const;
const std::string& getName() const { return mName; }
const LLUUID& getOwnerID() const { return mOwnerID; }
@@ -70,6 +71,7 @@ public:
void setDenyAgeUnverified(bool val);
void setAllowVoiceChat(bool val);
void setAllowAccessOverride(bool val);
+ void setAllowEnvironmentOverride(bool val);
void setSunHour(F32 sun_hour) { mSunHour = sun_hour; }
diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index 35c72ac068..a51d9a4a2c 100644
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -278,7 +278,7 @@ namespace Details
!result.get("events") ||
!result.get("id"))
{
- LL_WARNS("LLEventPollImpl") << " <" << counter << "> received event poll with no events or id key: " << LLSDXMLStreamer(result) << LL_ENDL;
+ LL_WARNS("LLEventPollImpl") << " <" << counter << "> received event poll with no events or id key: " << result << LL_ENDL;
continue;
}
@@ -291,7 +291,7 @@ namespace Details
}
// was LL_INFOS() but now that CoarseRegionUpdate is TCP @ 1/second, it'd be too verbose for viewer logs. -MG
- LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> " << events.size() << "events (id " << LLSDXMLStreamer(acknowledge) << ")" << LL_ENDL;
+ LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> " << events.size() << "events (id " << acknowledge << ")" << LL_ENDL;
LLSD::array_const_iterator i = events.beginArray();
LLSD::array_const_iterator end = events.endArray();
diff --git a/indra/newview/llexperiencelog.h b/indra/newview/llexperiencelog.h
index 09e0cd8821..5cc5bf685f 100644
--- a/indra/newview/llexperiencelog.h
+++ b/indra/newview/llexperiencelog.h
@@ -62,10 +62,9 @@ public:
static std::string getPermissionString(const LLSD& message, const std::string& base);
void setEventsToSave(LLSD new_events){mEventsToSave = new_events; }
bool isNotExpired(std::string& date);
-protected:
void handleExperienceMessage(LLSD& message);
-
+protected:
void loadEvents();
void saveEvents();
void eraseExpired();
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 5f6003c69b..d780afd596 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -171,7 +171,8 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
mImportanceToCamera = 0.f ;
mBoundingSphereRadius = 0.0f ;
- mHasMedia = FALSE ;
+ mHasMedia = false ;
+ mIsMediaAllowed = true;
// [SL:KB] - Patch: Render-TextureToggle (Catznip-4.0)
mShowDiffTexture = true;
@@ -318,6 +319,11 @@ void LLFace::setDiffuseMap(LLViewerTexture* tex)
setTexture(LLRender::DIFFUSE_MAP, tex);
}
+void LLFace::setAlternateDiffuseMap(LLViewerTexture* tex)
+{
+ setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, tex);
+}
+
void LLFace::setNormalMap(LLViewerTexture* tex)
{
setTexture(LLRender::NORMAL_MAP, tex);
@@ -396,16 +402,20 @@ void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture)
return;
}
- llassert(mTexture[ch].notNull());
-
- new_texture->addTextureStats(mTexture[ch]->getMaxVirtualSize()) ;
+ if (mTexture[ch].notNull())
+ {
+ new_texture->addTextureStats(mTexture[ch]->getMaxVirtualSize()) ;
+ }
if (ch == LLRender::DIFFUSE_MAP)
{
- getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
+ if (getViewerObject())
+ {
+ getViewerObject()->changeTEImage(mTEOffset, new_texture);
+ }
}
- setTexture(ch, new_texture) ;
+ setTexture(ch, new_texture);
dirtyTexture();
}
@@ -1506,17 +1516,16 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (shiny_in_alpha)
{
-
- static const GLfloat alpha[4] =
+ static const GLfloat SHININESS_TO_ALPHA[4] =
{
- 0.00f,
+ 0.0000f,
0.25f,
0.5f,
0.75f
};
llassert(tep->getShiny() <= 3);
- color.mV[3] = U8 (alpha[tep->getShiny()] * 255);
+ color.mV[3] = U8 (SHININESS_TO_ALPHA[tep->getShiny()] * 255);
}
}
}
@@ -1802,7 +1811,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
// that emboss mapping always shows up on the upward faces of cubes when
// it's noon (since a lot of builders build with the sun forced to noon).
LLVector3 sun_ray = gSky.mVOSkyp->mBumpSunDir;
- LLVector3 moon_ray = gSky.getMoonDirection();
+ LLVector3 moon_ray = gSky.mVOSkyp->getMoon().getDirection();
LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray;
bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV);
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 6649f991f9..bf2f3ca343 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -105,6 +105,7 @@ public:
void setDiffuseMap(LLViewerTexture* tex);
void setNormalMap(LLViewerTexture* tex);
void setSpecularMap(LLViewerTexture* tex);
+ void setAlternateDiffuseMap(LLViewerTexture* tex);
void switchTexture(U32 ch, LLViewerTexture* new_texture);
void dirtyTexture();
LLXformMatrix* getXform() const { return mXform; }
@@ -220,6 +221,9 @@ public:
void setHasMedia(bool has_media) { mHasMedia = has_media ;}
BOOL hasMedia() const ;
+ void setMediaAllowed(bool is_media_allowed) { mIsMediaAllowed = is_media_allowed; }
+ BOOL isMediaAllowed() const { return mIsMediaAllowed; }
+
BOOL switchTexture() ;
// [SL:KB] - Patch: Render-TextureToggle (Catznip-4.0)
@@ -299,6 +303,7 @@ private:
F32 mImportanceToCamera ;
F32 mBoundingSphereRadius ;
bool mHasMedia ;
+ bool mIsMediaAllowed;
// [SL:KB] - Patch: Render-TextureToggle (Catznip-4.0)
mutable bool mShowDiffTexture;
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 21e7e0ac2d..a2e28d6975 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -627,36 +627,36 @@ void LLFeatureManager::applyFeatures(bool skipFeatures)
void LLFeatureManager::setGraphicsLevel(U32 level, bool skipFeatures)
{
- LLViewerShaderMgr::sSkipReload = true;
+ LLViewerShaderMgr::sSkipReload = true;
- applyBaseMasks();
+ applyBaseMasks();
- // if we're passed an invalid level, default to "Low"
- std::string features(isValidGraphicsLevel(level)? getNameForGraphicsLevel(level) : "Low");
- if (features == "Low")
- {
+ // if we're passed an invalid level, default to "Low"
+ std::string features(isValidGraphicsLevel(level)? getNameForGraphicsLevel(level) : "Low");
+ if (features == "Low")
+ {
#if LL_DARWIN
- // This Mac-specific change is to insure that we force 'Basic Shaders' for all Mac
- // systems which support them instead of falling back to fixed-function unnecessarily
- // MAINT-2157
- if (gGLManager.mGLVersion < 2.1f)
+ // This Mac-specific change is to insure that we force 'Basic Shaders' for all Mac
+ // systems which support them instead of falling back to fixed-function unnecessarily
+ // MAINT-2157
+ if (gGLManager.mGLVersion < 2.1f)
#else
- // only use fixed function by default if GL version < 3.0 or this is an intel graphics chip
- if (gGLManager.mGLVersion < 3.f || gGLManager.mIsIntel)
+ // only use fixed function by default if GL version < 3.0 or this is an intel graphics chip
+ if (gGLManager.mGLVersion < 3.f || gGLManager.mIsIntel)
#endif
- {
+ {
// same as Low, but with "Basic Shaders" disabled
- features = "LowFixedFunction";
- }
- }
+ features = "LowFixedFunction";
+ }
+ }
- maskFeatures(features);
+ maskFeatures(features);
- applyFeatures(skipFeatures);
+ applyFeatures(skipFeatures);
- LLViewerShaderMgr::sSkipReload = false;
- LLViewerShaderMgr::instance()->setShaders();
- gPipeline.refreshCachedSettings();
+ LLViewerShaderMgr::sSkipReload = false;
+ LLViewerShaderMgr::instance()->setShaders();
+ gPipeline.refreshCachedSettings();
}
void LLFeatureManager::applyBaseMasks()
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 194e5dca52..1aa794cab9 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -520,85 +520,8 @@ void LLFloaterAvatarPicker::populateFriend()
void LLFloaterAvatarPicker::drawFrustum()
{
- if(mFrustumOrigin.get())
- {
- LLView * frustumOrigin = mFrustumOrigin.get();
- LLRect origin_rect;
- frustumOrigin->localRectToOtherView(frustumOrigin->getLocalRect(), &origin_rect, this);
- // draw context cone connecting color picker with color swatch in parent floater
- LLRect local_rect = getLocalRect();
- if (hasFocus() && frustumOrigin->isInVisibleChain() && mContextConeOpacity > 0.001f)
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLEnable(GL_CULL_FACE);
- // Remove QUADS rendering mode
- //gGL.begin(LLRender::QUADS);
- //{
- // gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- // gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
- // gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
- // gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- // gGL.vertex2i(local_rect.mRight, local_rect.mTop);
- // gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
-
- // gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- // gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
- // gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
- // gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- // gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
- // gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
-
- // gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- // gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
- // gGL.vertex2i(local_rect.mRight, local_rect.mTop);
- // gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- // gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
- // gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
-
- // gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- // gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
- // gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
- // gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- // gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
- // gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
- //}
- //gGL.end();
- gGL.begin(LLRender::TRIANGLE_STRIP);
- {
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mRight, local_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
- }
- gGL.end();
- //
- }
-
- if (gFocusMgr.childHasMouseCapture(getDragHandle()))
- {
- mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));
- }
- else
- {
- mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));
- }
- }
+ static LLCachedControl max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, mFrustumOrigin.get(), mContextConeFadeTime, mContextConeInAlpha, mContextConeOutAlpha);
}
void LLFloaterAvatarPicker::draw()
diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp
index f2040bc760..a1a06706bc 100644
--- a/indra/newview/llfloaterbulkpermission.cpp
+++ b/indra/newview/llfloaterbulkpermission.cpp
@@ -75,6 +75,7 @@ BOOL LLFloaterBulkPermission::postBuild()
mBulkChangeIncludeScripts = gSavedSettings.getBOOL("BulkChangeIncludeScripts");
mBulkChangeIncludeSounds = gSavedSettings.getBOOL("BulkChangeIncludeSounds");
mBulkChangeIncludeTextures = gSavedSettings.getBOOL("BulkChangeIncludeTextures");
+ mBulkChangeIncludeSettings = gSavedSettings.getBOOL("BulkChangeIncludeSettings");
mBulkChangeShareWithGroup = gSavedSettings.getBOOL("BulkChangeShareWithGroup");
mBulkChangeEveryoneCopy = gSavedSettings.getBOOL("BulkChangeEveryoneCopy");
mBulkChangeNextOwnerModify = gSavedSettings.getBOOL("BulkChangeNextOwnerModify");
@@ -186,6 +187,7 @@ void LLFloaterBulkPermission::onCloseBtn()
gSavedSettings.setBOOL("BulkChangeIncludeScripts", mBulkChangeIncludeScripts);
gSavedSettings.setBOOL("BulkChangeIncludeSounds", mBulkChangeIncludeSounds);
gSavedSettings.setBOOL("BulkChangeIncludeTextures", mBulkChangeIncludeTextures);
+ gSavedSettings.setBOOL("BulkChangeIncludeSettings", mBulkChangeIncludeSettings);
gSavedSettings.setBOOL("BulkChangeShareWithGroup", mBulkChangeShareWithGroup);
gSavedSettings.setBOOL("BulkChangeEveryoneCopy", mBulkChangeEveryoneCopy);
gSavedSettings.setBOOL("BulkChangeNextOwnerModify", mBulkChangeNextOwnerModify);
@@ -281,6 +283,7 @@ void LLFloaterBulkPermission::doCheckUncheckAll(BOOL check)
gSavedSettings.setBOOL("BulkChangeIncludeScripts" , check);
gSavedSettings.setBOOL("BulkChangeIncludeSounds" , check);
gSavedSettings.setBOOL("BulkChangeIncludeTextures" , check);
+ gSavedSettings.setBOOL("BulkChangeIncludeSettings" , check);
}
@@ -302,6 +305,7 @@ void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, LLInve
( asstype == LLAssetType::AT_OBJECT && gSavedSettings.getBOOL("BulkChangeIncludeObjects" )) ||
( asstype == LLAssetType::AT_LSL_TEXT && gSavedSettings.getBOOL("BulkChangeIncludeScripts" )) ||
( asstype == LLAssetType::AT_SOUND && gSavedSettings.getBOOL("BulkChangeIncludeSounds" )) ||
+ ( asstype == LLAssetType::AT_SETTINGS && gSavedSettings.getBOOL("BulkChangeIncludeSettings" )) ||
( asstype == LLAssetType::AT_TEXTURE && gSavedSettings.getBOOL("BulkChangeIncludeTextures" )))
{
LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
@@ -333,7 +337,12 @@ void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, LLInve
//|| something else // for next owner perms
)
{
- perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("BulkChange"));
+ U32 mask_next = LLFloaterPerms::getNextOwnerPerms("BulkChange");
+ if (asstype == LLAssetType::AT_SETTINGS)
+ {
+ mask_next |= PERM_COPY;
+ }
+ perm.setMaskNext(mask_next);
perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("BulkChange"));
perm.setMaskGroup(LLFloaterPerms::getGroupPerms("BulkChange"));
new_item->setPermissions(perm); // here's the beef
diff --git a/indra/newview/llfloaterbulkpermission.h b/indra/newview/llfloaterbulkpermission.h
index 0c042c3ee3..1afc876bba 100644
--- a/indra/newview/llfloaterbulkpermission.h
+++ b/indra/newview/llfloaterbulkpermission.h
@@ -102,6 +102,7 @@ private:
bool mBulkChangeIncludeScripts;
bool mBulkChangeIncludeSounds;
bool mBulkChangeIncludeTextures;
+ bool mBulkChangeIncludeSettings;
bool mBulkChangeShareWithGroup;
bool mBulkChangeEveryoneCopy;
bool mBulkChangeNextOwnerModify;
diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp
index fa1667de73..e530eb4bbf 100644
--- a/indra/newview/llfloaterbuy.cpp
+++ b/indra/newview/llfloaterbuy.cpp
@@ -244,7 +244,7 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,
BOOL item_is_multi = FALSE;
if (( inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED
|| inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS)
- && !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK))
+ && !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK))
{
item_is_multi = TRUE;
}
diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp
index abc23ceb39..a06371a603 100644
--- a/indra/newview/llfloaterbuycontents.cpp
+++ b/indra/newview/llfloaterbuycontents.cpp
@@ -219,7 +219,7 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,
BOOL item_is_multi = FALSE;
if ((inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED
|| inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS)
- && !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK))
+ && !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK))
{
item_is_multi = TRUE;
}
diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index 7bba967af7..12572f8ad6 100644
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/indra/newview/llfloatercolorpicker.cpp
@@ -498,82 +498,8 @@ BOOL LLFloaterColorPicker::isColorChanged()
//
void LLFloaterColorPicker::draw()
{
- LLRect swatch_rect;
- mSwatch->localRectToOtherView(mSwatch->getLocalRect(), &swatch_rect, this);
- // draw context cone connecting color picker with color swatch in parent floater
- LLRect local_rect = getLocalRect();
- if (hasFocus() && mSwatch->isInVisibleChain() && mContextConeOpacity > 0.001f)
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLEnable(GL_CULL_FACE);
- // Remove QUADS rendering mode
- //gGL.begin(LLRender::QUADS);
- //{
- // gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- // gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
- // gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop);
- // gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- // gGL.vertex2i(local_rect.mRight, local_rect.mTop);
- // gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
-
- // gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- // gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
- // gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
- // gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- // gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom);
- // gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
-
- // gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- // gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
- // gGL.vertex2i(local_rect.mRight, local_rect.mTop);
- // gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- // gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop);
- // gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom);
-
- // gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- // gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
- // gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
- // gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- // gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom);
- // gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom);
- //}
- //gGL.end();
- gGL.begin(LLRender::TRIANGLE_STRIP);
- {
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mRight, local_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
- }
- gGL.end();
- //
- }
-
- if (gFocusMgr.childHasMouseCapture(getDragHandle()))
- {
- mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"),
- LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));
- }
- else
- {
- mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));
- }
+ static LLCachedControl max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, mSwatch, mContextConeFadeTime, mContextConeInAlpha, mContextConeOutAlpha);
mPipetteBtn->setToggleState(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance());
mApplyImmediateCheck->setEnabled(mActive && mCanApplyImmediately);
diff --git a/indra/newview/llfloaterdeleteenvpreset.cpp b/indra/newview/llfloaterdeleteenvpreset.cpp
deleted file mode 100644
index bb11c813b4..0000000000
--- a/indra/newview/llfloaterdeleteenvpreset.cpp
+++ /dev/null
@@ -1,285 +0,0 @@
-/**
- * @file llfloaterdeleteenvpreset.cpp
- * @brief Floater to delete a water / sky / day cycle preset.
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloaterdeleteenvpreset.h"
-
-// libs
-#include "llbutton.h"
-#include "llcombobox.h"
-#include "llnotificationsutil.h"
-
-// newview
-#include "lldaycyclemanager.h"
-#include "llwaterparammanager.h"
-
-static bool confirmation_callback(const LLSD& notification, const LLSD& response, boost::function cb)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option == 0)
- {
- cb();
- }
- return false;
-
-}
-
-LLFloaterDeleteEnvPreset::LLFloaterDeleteEnvPreset(const LLSD &key)
-: LLFloater(key)
-, mPresetCombo(NULL)
-{
-}
-
-// virtual
-BOOL LLFloaterDeleteEnvPreset::postBuild()
-{
- mPresetCombo = getChild("preset_combo");
- mPresetCombo->setCommitCallback(boost::bind(&LLFloaterDeleteEnvPreset::postPopulate, this));
-
- getChild("delete")->setCommitCallback(boost::bind(&LLFloaterDeleteEnvPreset::onBtnDelete, this));
- getChild("cancel")->setCommitCallback(boost::bind(&LLFloaterDeleteEnvPreset::onBtnCancel, this));
-
- // Listen to user preferences change, in which case we need to rebuild the presets list
- // to disable the [new] current preset.
- LLEnvManagerNew::instance().setPreferencesChangeCallback(boost::bind(&LLFloaterDeleteEnvPreset::populatePresetsList, this));
-
- // Listen to presets addition/removal.
- LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLFloaterDeleteEnvPreset::populateDayCyclesList, this));
- LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterDeleteEnvPreset::populateSkyPresetsList, this));
- LLWaterParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterDeleteEnvPreset::populateWaterPresetsList, this));
-
- return TRUE;
-}
-
-// virtual
-void LLFloaterDeleteEnvPreset::onOpen(const LLSD& key)
-{
- std::string param = key.asString();
- std::string floater_title = getString(std::string("title_") + param);
- std::string combo_label = getString(std::string("label_" + param));
-
- // Update floater title.
- setTitle(floater_title);
-
- // Update the combobox label.
- getChild("label")->setValue(combo_label);
-
- // Populate the combobox.
- populatePresetsList();
-}
-
-void LLFloaterDeleteEnvPreset::onBtnDelete()
-{
- std::string param = mKey.asString();
- std::string preset_name = mPresetCombo->getValue().asString();
- boost::function confirm_cb;
-
- if (param == "water")
- {
- // Don't allow deleting system presets.
- if (LLWaterParamManager::instance().isSystemPreset(preset_name))
- {
- LLNotificationsUtil::add("WLNoEditDefault");
- return;
- }
-
- confirm_cb = boost::bind(&LLFloaterDeleteEnvPreset::onDeleteWaterPresetConfirmation, this);
- }
- else if (param == "sky")
- {
- // Don't allow deleting presets referenced by local day cycles.
- if (LLDayCycleManager::instance().isSkyPresetReferenced(preset_name))
- {
- LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", getString("msg_sky_is_referenced")));
- return;
- }
-
- LLWLParamManager& wl_mgr = LLWLParamManager::instance();
-
- // Don't allow deleting system presets.
- if (wl_mgr.isSystemPreset(preset_name))
- {
- LLNotificationsUtil::add("WLNoEditDefault");
- return;
- }
-
- confirm_cb = boost::bind(&LLFloaterDeleteEnvPreset::onDeleteSkyPresetConfirmation, this);
- }
- else if (param == "day_cycle")
- {
- LLDayCycleManager& day_mgr = LLDayCycleManager::instance();
-
- // Don't allow deleting system presets.
- if (day_mgr.isSystemPreset(preset_name))
- {
- LLNotificationsUtil::add("WLNoEditDefault");
- return;
- }
-
- confirm_cb = boost::bind(&LLFloaterDeleteEnvPreset::onDeleteDayCycleConfirmation, this);
- }
- else
- {
- LL_WARNS() << "Unrecognized key" << LL_ENDL;
- }
-
- LLSD args;
- args["MESSAGE"] = getString("msg_confirm_deletion");
- LLNotificationsUtil::add("GenericAlertYesCancel", args, LLSD(),
- boost::bind(&confirmation_callback, _1, _2, confirm_cb));
-}
-
-void LLFloaterDeleteEnvPreset::onBtnCancel()
-{
- closeFloater();
-}
-
-void LLFloaterDeleteEnvPreset::populatePresetsList()
-{
- std::string param = mKey.asString();
-
- if (param == "water")
- {
- populateWaterPresetsList();
- }
- else if (param == "sky")
- {
- populateSkyPresetsList();
- }
- else if (param == "day_cycle")
- {
- populateDayCyclesList();
- }
- else
- {
- LL_WARNS() << "Unrecognized key" << LL_ENDL;
- }
-}
-
-void LLFloaterDeleteEnvPreset::populateWaterPresetsList()
-{
- if (mKey.asString() != "water") return;
-
- mPresetCombo->removeall();
-
- std::string cur_preset;
- LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
- if (!env_mgr.getUseRegionSettings())
- {
- cur_preset = env_mgr.getWaterPresetName();
- }
-
- LLWaterParamManager::preset_name_list_t presets;
- LLWaterParamManager::instance().getUserPresetNames(presets); // list only user presets
- for (LLWaterParamManager::preset_name_list_t::const_iterator it = presets.begin(); it != presets.end(); ++it)
- {
- std::string name = *it;
-
- bool enabled = (name != cur_preset); // don't allow deleting current preset
- mPresetCombo->add(name, ADD_BOTTOM, enabled);
- }
-
- postPopulate();
-}
-
-void LLFloaterDeleteEnvPreset::populateSkyPresetsList()
-{
- if (mKey.asString() != "sky") return;
-
- mPresetCombo->removeall();
-
- std::string cur_preset;
- LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
- if (!env_mgr.getUseRegionSettings() && env_mgr.getUseFixedSky())
- {
- cur_preset = env_mgr.getSkyPresetName();
- }
-
- LLWLParamManager::preset_name_list_t user_presets;
- LLWLParamManager::instance().getUserPresetNames(user_presets);
- for (LLWLParamManager::preset_name_list_t::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it)
- {
- const std::string& name = *it;
- mPresetCombo->add(name, ADD_BOTTOM, /*enabled = */ name != cur_preset);
- }
-
- postPopulate();
-}
-
-void LLFloaterDeleteEnvPreset::populateDayCyclesList()
-{
- if (mKey.asString() != "day_cycle") return;
-
- mPresetCombo->removeall();
-
- std::string cur_day;
- LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
- if (!env_mgr.getUseRegionSettings() && env_mgr.getUseDayCycle())
- {
- cur_day = env_mgr.getDayCycleName();
- }
-
- LLDayCycleManager& day_mgr = LLDayCycleManager::instance();
- LLDayCycleManager::preset_name_list_t user_days;
- day_mgr.getUserPresetNames(user_days); // list only user presets
- for (LLDayCycleManager::preset_name_list_t::const_iterator it = user_days.begin(); it != user_days.end(); ++it)
- {
- const std::string& name = *it;
- mPresetCombo->add(name, ADD_BOTTOM, name != cur_day);
- }
-
- postPopulate();
-}
-
-void LLFloaterDeleteEnvPreset::postPopulate()
-{
- // Handle empty list and empty selection.
- bool has_selection = mPresetCombo->getItemCount() > 0 && mPresetCombo->getSelectedValue().isDefined();
-
- if (!has_selection)
- {
- mPresetCombo->setLabel(getString("combo_label"));
- }
-
- getChild("delete")->setEnabled(has_selection);
-}
-
-void LLFloaterDeleteEnvPreset::onDeleteDayCycleConfirmation()
-{
- LLDayCycleManager::instance().deletePreset(mPresetCombo->getValue().asString());
-}
-
-void LLFloaterDeleteEnvPreset::onDeleteSkyPresetConfirmation()
-{
- LLWLParamKey key(mPresetCombo->getValue().asString(), LLEnvKey::SCOPE_LOCAL);
- LLWLParamManager::instance().removeParamSet(key, true);
-}
-
-void LLFloaterDeleteEnvPreset::onDeleteWaterPresetConfirmation()
-{
- LLWaterParamManager::instance().removeParamSet(mPresetCombo->getValue().asString(), true);
-}
diff --git a/indra/newview/llfloatereditdaycycle.cpp b/indra/newview/llfloatereditdaycycle.cpp
deleted file mode 100644
index 5c0991b0b3..0000000000
--- a/indra/newview/llfloatereditdaycycle.cpp
+++ /dev/null
@@ -1,825 +0,0 @@
-/**
- * @file llfloatereditdaycycle.cpp
- * @brief Floater to create or edit a day cycle
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloatereditdaycycle.h"
-
-// libs
-#include "llbutton.h"
-#include "llcheckboxctrl.h"
-#include "llcombobox.h"
-#include "llloadingindicator.h"
-#include "llmultisliderctrl.h"
-#include "llnotifications.h"
-#include "llnotificationsutil.h"
-#include "llspinctrl.h"
-#include "lltimectrl.h"
-
-// newview
-#include "llagent.h"
-#include "lldaycyclemanager.h"
-#include "llenvmanager.h"
-#include "llregioninfomodel.h"
-#include "llviewerregion.h"
-#include "llwlparammanager.h"
-
-const F32 LLFloaterEditDayCycle::sHoursPerDay = 24.0f;
-
-LLFloaterEditDayCycle::LLFloaterEditDayCycle(const LLSD &key)
-: LLFloater(key)
-, mDayCycleNameEditor(NULL)
-, mDayCyclesCombo(NULL)
-, mTimeSlider(NULL)
-, mKeysSlider(NULL)
-, mSkyPresetsCombo(NULL)
-, mTimeCtrl(NULL)
-, mMakeDefaultCheckBox(NULL)
-, mSaveButton(NULL)
-{
-}
-
-// virtual
-BOOL LLFloaterEditDayCycle::postBuild()
-{
- mDayCycleNameEditor = getChild("day_cycle_name");
- mDayCyclesCombo = getChild("day_cycle_combo");
-
- mTimeSlider = getChild("WLTimeSlider");
- mKeysSlider = getChild("WLDayCycleKeys");
- mSkyPresetsCombo = getChild("WLSkyPresets");
- mTimeCtrl = getChild("time");
- mSaveButton = getChild("save");
- mMakeDefaultCheckBox = getChild("make_default_cb");
-
- initCallbacks();
-
- // add the time slider
- mTimeSlider->addSlider();
-
- return TRUE;
-}
-
-// virtual
-void LLFloaterEditDayCycle::onOpen(const LLSD& key)
-{
- bool new_day = isNewDay();
- std::string param = key.asString();
- std::string floater_title = getString(std::string("title_") + param);
- std::string hint = getString(std::string("hint_" + param));
-
- // Update floater title.
- setTitle(floater_title);
-
- // Update the hint at the top.
- getChild("hint")->setValue(hint);
-
- // Hide the hint to the right of the combo if we're invoked to create a new preset.
- getChildView("note")->setVisible(!new_day);
-
- // Switch between the day cycle presets combobox and day cycle name input field.
- mDayCyclesCombo->setVisible(!new_day);
- mDayCycleNameEditor->setVisible(new_day);
-
- // TODO: Make sure only one instance of the floater exists?
-
- reset();
-}
-
-// virtual
-void LLFloaterEditDayCycle::onClose(bool app_quitting)
-{
- if (!app_quitting) // there's no point to change environment if we're quitting
- {
- LLEnvManagerNew::instance().usePrefs(); // revert changes made to current day cycle
- }
-}
-
-// virtual
-void LLFloaterEditDayCycle::draw()
-{
- syncTimeSlider();
- LLFloater::draw();
-}
-
-void LLFloaterEditDayCycle::initCallbacks(void)
-{
- mDayCycleNameEditor->setKeystrokeCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleNameEdited, this), NULL);
- mDayCyclesCombo->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleSelected, this));
- mDayCyclesCombo->setTextEntryCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleNameEdited, this));
- mTimeSlider->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onTimeSliderMoved, this));
- mKeysSlider->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onKeyTimeMoved, this));
- mTimeCtrl->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onKeyTimeChanged, this));
- mSkyPresetsCombo->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onKeyPresetChanged, this));
-
- getChild("WLAddKey")->setClickedCallback(boost::bind(&LLFloaterEditDayCycle::onAddKey, this));
- getChild("WLDeleteKey")->setClickedCallback(boost::bind(&LLFloaterEditDayCycle::onDeleteKey, this));
-
- mSaveButton->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onBtnSave, this));
- mSaveButton->setRightMouseDownCallback(boost::bind(&LLFloaterEditDayCycle::dumpTrack, this));
- getChild("cancel")->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onBtnCancel, this));
-
- // Connect to env manager events.
- LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
- env_mgr.setRegionSettingsChangeCallback(boost::bind(&LLFloaterEditDayCycle::onRegionSettingsChange, this));
- gAgent.addRegionChangedCallback(boost::bind(&LLFloaterEditDayCycle::onRegionChange, this));
- env_mgr.setRegionSettingsAppliedCallback(boost::bind(&LLFloaterEditDayCycle::onRegionSettingsApplied, this, _1));
-
- // Connect to day cycle manager events.
- LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleListChange, this));
-
- // Connect to sky preset list changes.
- LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEditDayCycle::onSkyPresetListChange, this));
-
- // Connect to region info updates.
- LLRegionInfoModel::instance().setUpdateCallback(boost::bind(&LLFloaterEditDayCycle::onRegionInfoUpdate, this));
-}
-
-void LLFloaterEditDayCycle::syncTimeSlider()
-{
- // set time
- mTimeSlider->setCurSliderValue((F32)LLWLParamManager::getInstance()->mAnimator.getDayTime() * sHoursPerDay);
-}
-
-void LLFloaterEditDayCycle::loadTrack()
-{
- // clear the slider
- mKeysSlider->clear();
- mSliderToKey.clear();
-
- // add sliders
-
- LL_DEBUGS() << "Adding " << LLWLParamManager::getInstance()->mDay.mTimeMap.size() << " keys to slider" << LL_ENDL;
-
- LLWLDayCycle& cur_dayp = LLWLParamManager::instance().mDay;
- for (std::map::iterator it = cur_dayp.mTimeMap.begin(); it != cur_dayp.mTimeMap.end(); ++it)
- {
- addSliderKey(it->first * sHoursPerDay, it->second);
- }
-
- // set drop-down menu to match preset of currently-selected keyframe (one is automatically selected initially)
- const std::string& cur_sldr = mKeysSlider->getCurSlider();
- if (strlen(cur_sldr.c_str()) > 0) // only do this if there is a curSldr, otherwise we put an invalid entry into the map
- {
- mSkyPresetsCombo->selectByValue(mSliderToKey[cur_sldr].keyframe.toStringVal());
- }
-
- syncTimeSlider();
-}
-
-void LLFloaterEditDayCycle::applyTrack()
-{
- LL_DEBUGS() << "Applying track (" << mSliderToKey.size() << ")" << LL_ENDL;
-
- // if no keys, do nothing
- if (mSliderToKey.size() == 0)
- {
- LL_DEBUGS() << "No keys, not syncing" << LL_ENDL;
- return;
- }
-
- llassert_always(mSliderToKey.size() == mKeysSlider->getValue().size());
-
- // create a new animation track
- LLWLParamManager::getInstance()->mDay.clearKeyframes();
-
- // add the keys one by one
- for (std::map::iterator it = mSliderToKey.begin();
- it != mSliderToKey.end(); ++it)
- {
- LLWLParamManager::getInstance()->mDay.addKeyframe(it->second.time / sHoursPerDay,
- it->second.keyframe);
- }
-
- // set the param manager's track to the new one
- LLWLParamManager::getInstance()->resetAnimator(
- mTimeSlider->getCurSliderValue() / sHoursPerDay, false);
-
- LLWLParamManager::getInstance()->mAnimator.update(
- LLWLParamManager::getInstance()->mCurParams);
-}
-
-void LLFloaterEditDayCycle::refreshSkyPresetsList()
-{
- // Don't allow selecting region skies for a local day cycle,
- // because thus we may end up with invalid day cycle.
- bool include_region_skies = getSelectedDayCycle().scope == LLEnvKey::SCOPE_REGION;
-
- mSkyPresetsCombo->removeall();
-
- LLWLParamManager::preset_name_list_t region_presets;
- LLWLParamManager::preset_name_list_t user_presets, sys_presets;
- LLWLParamManager::instance().getPresetNames(region_presets, user_presets, sys_presets);
-
- if (include_region_skies)
- {
- // Add region presets.
- for (LLWLParamManager::preset_name_list_t::const_iterator it = region_presets.begin(); it != region_presets.end(); ++it)
- {
- std::string preset_name = *it;
- std::string item_title = preset_name + " (" + getRegionName() + ")";
- mSkyPresetsCombo->add(preset_name, LLWLParamKey(*it, LLEnvKey::SCOPE_REGION).toStringVal());
- }
-
- if (!region_presets.empty())
- {
- mSkyPresetsCombo->addSeparator();
- }
- }
-
- // Add user presets.
- for (LLWLParamManager::preset_name_list_t::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it)
- {
- mSkyPresetsCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toStringVal());
- }
-
- if (!user_presets.empty())
- {
- mSkyPresetsCombo->addSeparator();
- }
-
- // Add system presets.
- for (LLWLParamManager::preset_name_list_t::const_iterator it = sys_presets.begin(); it != sys_presets.end(); ++it)
- {
- mSkyPresetsCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toStringVal());
- }
-
- // set defaults on combo boxes
- mSkyPresetsCombo->selectFirstItem();
-}
-
-void LLFloaterEditDayCycle::refreshDayCyclesList()
-{
- llassert(isNewDay() == false);
-
- mDayCyclesCombo->removeall();
-
-#if 0 // Disable editing existing day cycle until the workflow is clear enough.
- const LLSD& region_day = LLEnvManagerNew::instance().getRegionSettings().getWLDayCycle();
- if (region_day.size() > 0)
- {
- LLWLParamKey key(getRegionName(), LLEnvKey::SCOPE_REGION);
- mDayCyclesCombo->add(key.name, key.toLLSD());
- mDayCyclesCombo->addSeparator();
- }
-#endif
-
- LLDayCycleManager::preset_name_list_t user_days, sys_days;
- LLDayCycleManager::instance().getPresetNames(user_days, sys_days);
-
- // Add user days.
- for (LLDayCycleManager::preset_name_list_t::const_iterator it = user_days.begin(); it != user_days.end(); ++it)
- {
- mDayCyclesCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toLLSD());
- }
-
- if (user_days.size() > 0)
- {
- mDayCyclesCombo->addSeparator();
- }
-
- // Add system days.
- for (LLDayCycleManager::preset_name_list_t::const_iterator it = sys_days.begin(); it != sys_days.end(); ++it)
- {
- mDayCyclesCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toLLSD());
- }
-
- mDayCyclesCombo->setLabel(getString("combo_label"));
-}
-
-void LLFloaterEditDayCycle::onTimeSliderMoved()
-{
- /// get the slider value
- F32 val = mTimeSlider->getCurSliderValue() / sHoursPerDay;
-
- // set the value, turn off animation
- LLWLParamManager::getInstance()->mAnimator.setDayTime((F64)val);
- LLWLParamManager::getInstance()->mAnimator.deactivate();
-
- // then call update once
- LLWLParamManager::getInstance()->mAnimator.update(
- LLWLParamManager::getInstance()->mCurParams);
-}
-
-void LLFloaterEditDayCycle::onKeyTimeMoved()
-{
- if (mKeysSlider->getValue().size() == 0)
- {
- return;
- }
-
- // make sure we have a slider
- const std::string& cur_sldr = mKeysSlider->getCurSlider();
- if (cur_sldr == "")
- {
- return;
- }
-
- F32 time24 = mKeysSlider->getCurSliderValue();
-
- // check to see if a key exists
- LLWLParamKey key = mSliderToKey[cur_sldr].keyframe;
- LL_DEBUGS() << "Setting key time: " << time24 << LL_ENDL;
- mSliderToKey[cur_sldr].time = time24;
-
- // if it exists, turn on check box
- mSkyPresetsCombo->selectByValue(key.toStringVal());
-
- mTimeCtrl->setTime24(time24);
-
- applyTrack();
-}
-
-void LLFloaterEditDayCycle::onKeyTimeChanged()
-{
- // if no keys, skipped
- if (mSliderToKey.size() == 0)
- {
- return;
- }
-
- F32 time24 = mTimeCtrl->getTime24();
-
- const std::string& cur_sldr = mKeysSlider->getCurSlider();
- mKeysSlider->setCurSliderValue(time24, TRUE);
- F32 time = mKeysSlider->getCurSliderValue() / sHoursPerDay;
-
- // now set the key's time in the sliderToKey map
- LL_DEBUGS() << "Setting key time: " << time << LL_ENDL;
- mSliderToKey[cur_sldr].time = time;
-
- applyTrack();
-}
-
-void LLFloaterEditDayCycle::onKeyPresetChanged()
-{
- // do nothing if no sliders
- if (mKeysSlider->getValue().size() == 0)
- {
- return;
- }
-
- // change the map
-
- std::string stringVal = mSkyPresetsCombo->getSelectedValue().asString();
- LLWLParamKey new_key(stringVal);
- llassert(!new_key.name.empty());
- const std::string& cur_sldr = mKeysSlider->getCurSlider();
-
- // if null, don't use
- if (cur_sldr == "")
- {
- return;
- }
-
- mSliderToKey[cur_sldr].keyframe = new_key;
-
- // Apply changes to current day cycle.
- applyTrack();
-}
-
-void LLFloaterEditDayCycle::onAddKey()
-{
- llassert_always(mSliderToKey.size() == mKeysSlider->getValue().size());
-
- S32 max_sliders;
- LLEnvKey::EScope scope = LLEnvKey::SCOPE_LOCAL; // *TODO: editing region day cycle
- switch (scope)
- {
- case LLEnvKey::SCOPE_LOCAL:
- max_sliders = 20; // *HACK this should be LLWLPacketScrubber::MAX_LOCAL_KEY_FRAMES;
- break;
- case LLEnvKey::SCOPE_REGION:
- max_sliders = 12; // *HACK this should be LLWLPacketScrubber::MAX_REGION_KEY_FRAMES;
- break;
- default:
- max_sliders = (S32) mKeysSlider->getMaxValue();
- break;
- }
-
- if ((S32)mSliderToKey.size() >= max_sliders)
- {
- LLSD args;
- args["SCOPE"] = LLEnvManagerNew::getScopeString(scope);
- args["MAX"] = max_sliders;
- LLNotificationsUtil::add("DayCycleTooManyKeyframes", args, LLSD(), LLNotificationFunctorRegistry::instance().DONOTHING);
- return;
- }
-
- // add the slider key
- std::string key_val = mSkyPresetsCombo->getSelectedValue().asString();
- LLWLParamKey sky_params(key_val);
- llassert(!sky_params.name.empty());
-
- F32 time = mTimeSlider->getCurSliderValue();
- addSliderKey(time, sky_params);
-
- // apply the change to current day cycles
- applyTrack();
-}
-
-void LLFloaterEditDayCycle::addSliderKey(F32 time, LLWLParamKey keyframe)
-{
- // make a slider
- const std::string& sldr_name = mKeysSlider->addSlider(time);
- if (sldr_name.empty())
- {
- return;
- }
-
- // set the key
- SliderKey newKey(keyframe, mKeysSlider->getCurSliderValue());
-
- llassert_always(sldr_name != LLStringUtil::null);
-
- // add to map
- mSliderToKey.insert(std::pair(sldr_name, newKey));
-
- llassert_always(mSliderToKey.size() == mKeysSlider->getValue().size());
-}
-
-LLWLParamKey LLFloaterEditDayCycle::getSelectedDayCycle()
-{
- LLWLParamKey dc_key;
-
- if (mDayCycleNameEditor->getVisible())
- {
- dc_key.name = mDayCycleNameEditor->getText();
- dc_key.scope = LLEnvKey::SCOPE_LOCAL;
- }
- else
- {
- LLSD combo_val = mDayCyclesCombo->getValue();
-
- if (!combo_val.isArray()) // manually typed text
- {
- dc_key.name = combo_val.asString();
- dc_key.scope = LLEnvKey::SCOPE_LOCAL;
- }
- else
- {
- dc_key.fromLLSD(combo_val);
- }
- }
-
- return dc_key;
-}
-
-bool LLFloaterEditDayCycle::isNewDay() const
-{
- return mKey.asString() == "new";
-}
-
-void LLFloaterEditDayCycle::dumpTrack()
-{
- LL_DEBUGS("Windlight") << "Dumping day cycle" << LL_ENDL;
-
- LLWLDayCycle& cur_dayp = LLWLParamManager::instance().mDay;
- for (std::map::iterator it = cur_dayp.mTimeMap.begin(); it != cur_dayp.mTimeMap.end(); ++it)
- {
- F32 time = it->first * 24.0f;
- S32 h = (S32) time;
- S32 m = (S32) ((time - h) * 60.0f);
- LL_DEBUGS("Windlight") << llformat("(%.3f) %02d:%02d", time, h, m) << " => " << it->second.name << LL_ENDL;
- }
-}
-
-void LLFloaterEditDayCycle::enableEditing(bool enable)
-{
- mSkyPresetsCombo->setEnabled(enable);
- mTimeCtrl->setEnabled(enable);
- getChild("day_cycle_slider_panel")->setCtrlsEnabled(enable);
- mSaveButton->setEnabled(enable);
- mMakeDefaultCheckBox->setEnabled(enable);
-}
-
-void LLFloaterEditDayCycle::reset()
-{
- // clear the slider
- mKeysSlider->clear();
- mSliderToKey.clear();
-
- refreshSkyPresetsList();
-
- if (isNewDay())
- {
- mDayCycleNameEditor->setValue(LLSD());
- F32 time = 0.5f * sHoursPerDay;
- mSaveButton->setEnabled(FALSE); // will be enabled as soon as users enters a name
- mTimeSlider->setCurSliderValue(time);
-
- addSliderKey(time, LLWLParamKey("Default", LLEnvKey::SCOPE_LOCAL));
- onKeyTimeMoved(); // update the time control and sky sky combo
-
- applyTrack();
- }
- else
- {
- refreshDayCyclesList();
-
- // Disable controls until a day cycle to edit is selected.
- enableEditing(false);
- }
-}
-
-void LLFloaterEditDayCycle::saveRegionDayCycle()
-{
- LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
- LLWLDayCycle& cur_dayp = LLWLParamManager::instance().mDay; // the day cycle being edited
-
- // Get current day cycle and the sky preset it references.
- LLSD day_cycle = cur_dayp.asLLSD();
- LLSD sky_map;
- cur_dayp.getSkyMap(sky_map);
-
- // Apply it to the region.
- LLEnvironmentSettings new_region_settings;
- new_region_settings.saveParams(day_cycle, sky_map, env_mgr.getRegionSettings().getWaterParams(), 0.0f);
-
-#if 1
- LLEnvManagerNew::instance().setRegionSettings(new_region_settings);
-#else // Temporary disabled ability to upload new region settings from the Day Cycle Editor.
- if (!LLEnvManagerNew::instance().sendRegionSettings(new_region_settings))
- {
- LL_WARNS() << "Error applying region environment settings" << LL_ENDL;
- return;
- }
-
- setApplyProgress(true);
-#endif
-}
-
-void LLFloaterEditDayCycle::setApplyProgress(bool started)
-{
- LLLoadingIndicator* indicator = getChild("progress_indicator");
-
- indicator->setVisible(started);
-
- if (started)
- {
- indicator->start();
- }
- else
- {
- indicator->stop();
- }
-}
-
-bool LLFloaterEditDayCycle::getApplyProgress() const
-{
- return getChild("progress_indicator")->getVisible();
-}
-
-void LLFloaterEditDayCycle::onDeleteKey()
-{
- if (mSliderToKey.size() == 0)
- {
- return;
- }
- else if (mSliderToKey.size() == 1)
- {
- LLNotifications::instance().add("EnvCannotDeleteLastDayCycleKey", LLSD(), LLSD());
- return;
- }
-
- // delete from map
- const std::string& sldr_name = mKeysSlider->getCurSlider();
- std::map::iterator mIt = mSliderToKey.find(sldr_name);
- mSliderToKey.erase(mIt);
-
- mKeysSlider->deleteCurSlider();
-
- if (mSliderToKey.size() == 0)
- {
- return;
- }
-
- const std::string& name = mKeysSlider->getCurSlider();
- mSkyPresetsCombo->selectByValue(mSliderToKey[name].keyframe.toStringVal());
- F32 time24 = mSliderToKey[name].time;
-
- mTimeCtrl->setTime24(time24);
-
- applyTrack();
-}
-
-void LLFloaterEditDayCycle::onRegionSettingsChange()
-{
- LL_DEBUGS("Windlight") << "Region settings changed" << LL_ENDL;
-
- if (getApplyProgress()) // our region settings have being applied
- {
- setApplyProgress(false);
-
- // Change preference if requested.
- if (mMakeDefaultCheckBox->getValue())
- {
- LL_DEBUGS("Windlight") << "Changed environment preference to region settings" << LL_ENDL;
- LLEnvManagerNew::instance().setUseRegionSettings(true);
- }
-
- closeFloater();
- }
-}
-
-void LLFloaterEditDayCycle::onRegionChange()
-{
- LL_DEBUGS("Windlight") << "Region changed" << LL_ENDL;
-
- // If we're editing the region day cycle
- if (getSelectedDayCycle().scope == LLEnvKey::SCOPE_REGION)
- {
- reset(); // undoes all unsaved changes
- }
-}
-
-void LLFloaterEditDayCycle::onRegionSettingsApplied(bool success)
-{
- LL_DEBUGS("Windlight") << "Region settings applied: " << success << LL_ENDL;
-
- if (!success)
- {
- // stop progress indicator
- setApplyProgress(false);
- }
-}
-
-void LLFloaterEditDayCycle::onRegionInfoUpdate()
-{
- LL_DEBUGS("Windlight") << "Region info updated" << LL_ENDL;
- bool can_edit = true;
-
- // If we've selected the region day cycle for editing.
- if (getSelectedDayCycle().scope == LLEnvKey::SCOPE_REGION)
- {
- // check whether we have the access
- can_edit = LLEnvManagerNew::canEditRegionSettings();
- }
-
- enableEditing(can_edit);
-}
-
-void LLFloaterEditDayCycle::onDayCycleNameEdited()
-{
- // Disable saving a day cycle having empty name.
- LLWLParamKey key = getSelectedDayCycle();
- mSaveButton->setEnabled(!key.name.empty());
-}
-
-void LLFloaterEditDayCycle::onDayCycleSelected()
-{
- LLSD day_data;
- LLWLParamKey dc_key = getSelectedDayCycle();
- bool can_edit = true;
-
- if (dc_key.scope == LLEnvKey::SCOPE_LOCAL)
- {
- if (!LLDayCycleManager::instance().getPreset(dc_key.name, day_data))
- {
- LL_WARNS() << "No day cycle named " << dc_key.name << LL_ENDL;
- return;
- }
- }
- else
- {
- day_data = LLEnvManagerNew::instance().getRegionSettings().getWLDayCycle();
- if (day_data.size() == 0)
- {
- LL_WARNS() << "Empty region day cycle" << LL_ENDL;
- llassert(day_data.size() > 0);
- return;
- }
-
- can_edit = LLEnvManagerNew::canEditRegionSettings();
- }
-
- // We may need to add or remove region skies from the list.
- refreshSkyPresetsList();
-
- F32 slider_time = mTimeSlider->getCurSliderValue() / sHoursPerDay;
- LLWLParamManager::instance().applyDayCycleParams(day_data, dc_key.scope, slider_time);
- loadTrack();
-
- enableEditing(can_edit);
-}
-
-void LLFloaterEditDayCycle::onBtnSave()
-{
- LLDayCycleManager& day_mgr = LLDayCycleManager::instance();
- LLWLParamKey selected_day = getSelectedDayCycle();
-
- if (selected_day.scope == LLEnvKey::SCOPE_REGION)
- {
- saveRegionDayCycle();
- closeFloater();
- return;
- }
-
- std::string name = selected_day.name;
- if (name.empty())
- {
- // *TODO: show an alert
- LL_WARNS() << "Empty day cycle name" << LL_ENDL;
- return;
- }
-
- // Don't allow overwriting system presets.
- if (day_mgr.isSystemPreset(name))
- {
- LLNotificationsUtil::add("WLNoEditDefault");
- return;
- }
-
- // Save, ask for confirmation for overwriting an existing preset.
- if (day_mgr.presetExists(name))
- {
- LLNotificationsUtil::add("WLSavePresetAlert", LLSD(), LLSD(), boost::bind(&LLFloaterEditDayCycle::onSaveAnswer, this, _1, _2));
- }
- else
- {
- // new preset, hence no confirmation needed
- onSaveConfirmed();
- }
-}
-
-void LLFloaterEditDayCycle::onBtnCancel()
-{
- closeFloater();
-}
-
-bool LLFloaterEditDayCycle::onSaveAnswer(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-
- // If they choose save, do it. Otherwise, don't do anything
- if (option == 0)
- {
- onSaveConfirmed();
- }
-
- return false;
-}
-
-void LLFloaterEditDayCycle::onSaveConfirmed()
-{
- std::string name = getSelectedDayCycle().name;
-
- // Save preset.
- LLSD data = LLWLParamManager::instance().mDay.asLLSD();
- LL_DEBUGS("Windlight") << "Saving day cycle " << name << ": " << data << LL_ENDL;
- LLDayCycleManager::instance().savePreset(name, data);
-
- // Change preference if requested.
- if (mMakeDefaultCheckBox->getValue())
- {
- LL_DEBUGS("Windlight") << name << " is now the new preferred day cycle" << LL_ENDL;
- LLEnvManagerNew::instance().setUseDayCycle(name);
- }
-
- closeFloater();
-}
-
-void LLFloaterEditDayCycle::onDayCycleListChange()
-{
- if (!isNewDay())
- {
- refreshDayCyclesList();
- }
-}
-
-void LLFloaterEditDayCycle::onSkyPresetListChange()
-{
- refreshSkyPresetsList();
-
- // Refresh sliders from the currently visible day cycle.
- loadTrack();
-}
-
-// static
-std::string LLFloaterEditDayCycle::getRegionName()
-{
- return gAgent.getRegion() ? gAgent.getRegion()->getName() : LLTrans::getString("Unknown");
-}
diff --git a/indra/newview/llfloatereditdaycycle.h b/indra/newview/llfloatereditdaycycle.h
deleted file mode 100644
index e6e4fe39c1..0000000000
--- a/indra/newview/llfloatereditdaycycle.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/**
- * @file llfloatereditdaycycle.h
- * @brief Floater to create or edit a day cycle
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLFLOATEREDITDAYCYCLE_H
-#define LL_LLFLOATEREDITDAYCYCLE_H
-
-#include "llfloater.h"
-
-#include "llwlparammanager.h" // for LLWLParamKey
-
-class LLCheckBoxCtrl;
-class LLComboBox;
-class LLLineEditor;
-class LLMultiSliderCtrl;
-class LLTimeCtrl;
-
-/**
- * Floater for creating or editing a day cycle.
- */
-class LLFloaterEditDayCycle : public LLFloater
-{
- LOG_CLASS(LLFloaterEditDayCycle);
-
-public:
- LLFloaterEditDayCycle(const LLSD &key);
-
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void onOpen(const LLSD& key);
- /*virtual*/ void onClose(bool app_quitting);
- /*virtual*/ void draw();
-
-private:
-
- /// sync the time slider with day cycle structure
- void syncTimeSlider();
-
- // makes sure key slider has what's in day cycle
- void loadTrack();
-
- /// makes sure day cycle data structure has what's in menu
- void applyTrack();
-
- /// refresh the sky presets combobox
- void refreshSkyPresetsList();
-
- /// refresh the day cycle combobox
- void refreshDayCyclesList();
-
- /// add a slider to the track
- void addSliderKey(F32 time, LLWLParamKey keyframe);
-
- void initCallbacks();
- LLWLParamKey getSelectedDayCycle();
- bool isNewDay() const;
- void dumpTrack();
- void enableEditing(bool enable);
- void reset();
- void saveRegionDayCycle();
-
- void setApplyProgress(bool started);
- bool getApplyProgress() const;
-
- void onTimeSliderMoved(); /// time slider moved
- void onKeyTimeMoved(); /// a key frame moved
- void onKeyTimeChanged(); /// a key frame's time changed
- void onKeyPresetChanged(); /// sky preset selected
- void onAddKey(); /// new key added on slider
- void onDeleteKey(); /// a key frame deleted
-
- void onRegionSettingsChange();
- void onRegionChange();
- void onRegionSettingsApplied(bool success);
- void onRegionInfoUpdate();
-
- void onDayCycleNameEdited();
- void onDayCycleSelected();
- void onBtnSave();
- void onBtnCancel();
-
- bool onSaveAnswer(const LLSD& notification, const LLSD& response);
- void onSaveConfirmed();
-
- void onDayCycleListChange();
- void onSkyPresetListChange();
-
- static std::string getRegionName();
-
- /// convenience class for holding keyframes mapped to sliders
- struct SliderKey
- {
- public:
- SliderKey(LLWLParamKey kf, F32 t) : keyframe(kf), time(t) {}
- SliderKey() : keyframe(), time(0.f) {} // Don't use this default constructor
-
- LLWLParamKey keyframe;
- F32 time;
- };
-
- static const F32 sHoursPerDay;
-
- LLLineEditor* mDayCycleNameEditor;
- LLComboBox* mDayCyclesCombo;
- LLMultiSliderCtrl* mTimeSlider;
- LLMultiSliderCtrl* mKeysSlider;
- LLComboBox* mSkyPresetsCombo;
- LLTimeCtrl* mTimeCtrl;
- LLCheckBoxCtrl* mMakeDefaultCheckBox;
- LLButton* mSaveButton;
-
- // map of sliders to parameters
- std::map mSliderToKey;
-};
-
-#endif // LL_LLFLOATEREDITDAYCYCLE_H
diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp
new file mode 100644
index 0000000000..ea22043de8
--- /dev/null
+++ b/indra/newview/llfloatereditextdaycycle.cpp
@@ -0,0 +1,2155 @@
+/**
+ * @file llfloatereditextdaycycle.cpp
+ * @brief Floater to create or edit a day cycle
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatereditextdaycycle.h"
+
+// libs
+#include "llbutton.h"
+#include "llcallbacklist.h"
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "llloadingindicator.h"
+#include "lllocalbitmaps.h"
+#include "llmultisliderctrl.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "llspinctrl.h"
+#include "lltimectrl.h"
+#include "lltabcontainer.h"
+#include "llfilepicker.h"
+
+#include "llsettingsvo.h"
+#include "llinventorymodel.h"
+#include "llviewerparcelmgr.h"
+
+#include "llsettingspicker.h"
+#include "lltrackpicker.h"
+
+// newview
+#include "llagent.h"
+#include "llappviewer.h" //gDisconected
+#include "llparcel.h"
+#include "llflyoutcombobtn.h" //Todo: make a proper UI element/button/panel instead
+#include "llregioninfomodel.h"
+#include "llviewermenufile.h" // LLFilePickerReplyThread
+#include "llviewerregion.h"
+#include "llpaneleditwater.h"
+#include "llpaneleditsky.h"
+
+#include "llui.h"
+
+#include "llenvironment.h"
+#include "lltrans.h"
+
+extern LLControlGroup gSavedSettings;
+
+//=========================================================================
+namespace {
+ const std::string track_tabs[] = {
+ "water_track",
+ "sky1_track",
+ "sky2_track",
+ "sky3_track",
+ "sky4_track",
+ };
+
+ const std::string ICN_LOCK_EDIT("icn_lock_edit");
+ const std::string BTN_SAVE("save_btn");
+ const std::string BTN_FLYOUT("btn_flyout");
+ const std::string BTN_CANCEL("cancel_btn");
+ const std::string BTN_ADDFRAME("add_frame");
+ const std::string BTN_DELFRAME("delete_frame");
+ const std::string BTN_IMPORT("btn_import");
+ const std::string BTN_LOADFRAME("btn_load_frame");
+ const std::string BTN_CLONETRACK("copy_track");
+ const std::string BTN_LOADTRACK("load_track");
+ const std::string BTN_CLEARTRACK("clear_track");
+ const std::string SLDR_TIME("WLTimeSlider");
+ const std::string SLDR_KEYFRAMES("WLDayCycleFrames");
+ const std::string VIEW_SKY_SETTINGS("frame_settings_sky");
+ const std::string VIEW_WATER_SETTINGS("frame_settings_water");
+ const std::string LBL_CURRENT_TIME("current_time");
+ const std::string TXT_DAY_NAME("day_cycle_name");
+ const std::string TABS_SKYS("sky_tabs");
+ const std::string TABS_WATER("water_tabs");
+
+ const std::string EVNT_DAYTRACK("DayCycle.Track");
+ const std::string EVNT_PLAY("DayCycle.PlayActions");
+
+ const std::string ACTION_PLAY("play");
+ const std::string ACTION_PAUSE("pause");
+ const std::string ACTION_FORWARD("forward");
+ const std::string ACTION_BACK("back");
+
+ // For flyout
+ const std::string XML_FLYOUTMENU_FILE("menu_save_settings.xml");
+ // From menu_save_settings.xml, consider moving into flyout since it should be supported by flyout either way
+ const std::string ACTION_SAVE("save_settings");
+ const std::string ACTION_SAVEAS("save_as_new_settings");
+ const std::string ACTION_COMMIT("commit_changes");
+ const std::string ACTION_APPLY_LOCAL("apply_local");
+ const std::string ACTION_APPLY_PARCEL("apply_parcel");
+ const std::string ACTION_APPLY_REGION("apply_region");
+
+ const F32 DAY_CYCLE_PLAY_TIME_SECONDS = 60;
+
+ const std::string STR_COMMIT_PARCEL("commit_parcel");
+ const std::string STR_COMMIT_REGION("commit_region");
+ //---------------------------------------------------------------------
+
+}
+
+//=========================================================================
+const std::string LLFloaterEditExtDayCycle::KEY_INVENTORY_ID("inventory_id");
+const std::string LLFloaterEditExtDayCycle::KEY_EDIT_CONTEXT("edit_context");
+const std::string LLFloaterEditExtDayCycle::KEY_DAY_LENGTH("day_length");
+const std::string LLFloaterEditExtDayCycle::KEY_CANMOD("canmod");
+
+const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_INVENTORY("inventory");
+const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_PARCEL("parcel");
+const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_REGION("region");
+
+//=========================================================================
+
+class LLDaySettingCopiedCallback : public LLInventoryCallback
+{
+public:
+ LLDaySettingCopiedCallback(LLHandle handle) : mHandle(handle) {}
+
+ virtual void fire(const LLUUID& inv_item_id)
+ {
+ if (!mHandle.isDead())
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
+ if (item)
+ {
+ LLFloaterEditExtDayCycle* floater = (LLFloaterEditExtDayCycle*)mHandle.get();
+ floater->onInventoryCreated(item->getAssetUUID(), inv_item_id);
+ }
+ }
+ }
+
+private:
+ LLHandle mHandle;
+};
+
+//=========================================================================
+
+LLFloaterEditExtDayCycle::LLFloaterEditExtDayCycle(const LLSD &key) :
+ LLFloater(key),
+ mFlyoutControl(nullptr),
+ mDayLength(0),
+ mCurrentTrack(1),
+ mShiftCopyEnabled(false),
+ mTimeSlider(nullptr),
+ mFramesSlider(nullptr),
+ mCurrentTimeLabel(nullptr),
+ mImportButton(nullptr),
+ mInventoryId(),
+ mInventoryItem(nullptr),
+ mLoadFrame(nullptr),
+ mSkyBlender(),
+ mWaterBlender(),
+ mScratchSky(),
+ mScratchWater(),
+ mIsPlaying(false),
+ mIsDirty(false),
+ mCanSave(false),
+ mCanCopy(false),
+ mCanMod(false),
+ mCanTrans(false),
+ mCloneTrack(nullptr),
+ mLoadTrack(nullptr),
+ mClearTrack(nullptr)
+{
+
+ mCommitCallbackRegistrar.add(EVNT_DAYTRACK, [this](LLUICtrl *ctrl, const LLSD &data) { onTrackSelectionCallback(data); });
+ mCommitCallbackRegistrar.add(EVNT_PLAY, [this](LLUICtrl *ctrl, const LLSD &data) { onPlayActionCallback(data); });
+
+ mScratchSky = LLSettingsVOSky::buildDefaultSky();
+ mScratchWater = LLSettingsVOWater::buildDefaultWater();
+
+ mEditSky = mScratchSky;
+ mEditWater = mScratchWater;
+}
+
+LLFloaterEditExtDayCycle::~LLFloaterEditExtDayCycle()
+{
+ // Todo: consider remaking mFlyoutControl into full view class that initializes intself with floater,
+ // complete with postbuild, e t c...
+ delete mFlyoutControl;
+}
+
+// virtual
+BOOL LLFloaterEditExtDayCycle::postBuild()
+{
+ getChild(TXT_DAY_NAME)->setKeystrokeCallback(boost::bind(&LLFloaterEditExtDayCycle::onCommitName, this, _1, _2), NULL);
+
+ mAddFrameButton = getChild(BTN_ADDFRAME, true);
+ mDeleteFrameButton = getChild(BTN_DELFRAME, true);
+ mTimeSlider = getChild(SLDR_TIME);
+ mFramesSlider = getChild(SLDR_KEYFRAMES);
+ mSkyTabLayoutContainer = getChild(VIEW_SKY_SETTINGS, true);
+ mWaterTabLayoutContainer = getChild(VIEW_WATER_SETTINGS, true);
+ mCurrentTimeLabel = getChild(LBL_CURRENT_TIME, true);
+ mImportButton = getChild(BTN_IMPORT, true);
+ mLoadFrame = getChild(BTN_LOADFRAME, true);
+ mCloneTrack = getChild(BTN_CLONETRACK, true);
+ mLoadTrack = getChild(BTN_LOADTRACK, true);
+ mClearTrack = getChild(BTN_CLEARTRACK, true);
+
+ mFlyoutControl = new LLFlyoutComboBtnCtrl(this, BTN_SAVE, BTN_FLYOUT, XML_FLYOUTMENU_FILE, false);
+ mFlyoutControl->setAction([this](LLUICtrl *ctrl, const LLSD &data) { onButtonApply(ctrl, data); });
+
+ getChild(BTN_CANCEL, true)->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onClickCloseBtn(); });
+ mTimeSlider->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onTimeSliderCallback(); });
+ mAddFrameButton->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onAddFrame(); });
+ mDeleteFrameButton->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onRemoveFrame(); });
+ mImportButton->setCommitCallback([this](LLUICtrl *, const LLSD &){ onButtonImport(); });
+ mLoadFrame->setCommitCallback([this](LLUICtrl *, const LLSD &){ onButtonLoadFrame(); });
+
+ mCloneTrack->setCommitCallback([this](LLUICtrl *, const LLSD&){ onCloneTrack(); });
+ mLoadTrack->setCommitCallback([this](LLUICtrl *, const LLSD&){ onLoadTrack();});
+ mClearTrack->setCommitCallback([this](LLUICtrl *, const LLSD&){ onClearTrack(); });
+
+
+ mFramesSlider->setCommitCallback([this](LLUICtrl *, const LLSD &data) { onFrameSliderCallback(data); });
+ mFramesSlider->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask){ onFrameSliderDoubleClick(x, y, mask); });
+ mFramesSlider->setMouseDownCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask){ onFrameSliderMouseDown(x, y, mask); });
+ mFramesSlider->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask){ onFrameSliderMouseUp(x, y, mask); });
+
+ mTimeSlider->addSlider(0);
+
+ LLTabContainer* tab_container = mSkyTabLayoutContainer->getChild("sky_tabs");
+ S32 tab_count = tab_container->getTabCount();
+
+ LLSettingsEditPanel *panel = nullptr;
+
+ for (S32 idx = 0; idx < tab_count; ++idx)
+ {
+ panel = static_cast(tab_container->getPanelByIndex(idx));
+ if (panel)
+ panel->setOnDirtyFlagChanged([this](LLPanel *, bool val) { onPanelDirtyFlagChanged(val); });
+ }
+
+ tab_container = mWaterTabLayoutContainer->getChild("water_tabs");
+ tab_count = tab_container->getTabCount();
+
+ for (S32 idx = 0; idx < tab_count; ++idx)
+ {
+ LLSettingsEditPanel *panel = static_cast(tab_container->getPanelByIndex(idx));
+ if (panel)
+ panel->setOnDirtyFlagChanged([this](LLPanel *, bool val) { onPanelDirtyFlagChanged(val); });
+ }
+
+ return TRUE;
+}
+
+void LLFloaterEditExtDayCycle::onOpen(const LLSD& key)
+{
+ if (!mEditDay)
+ {
+ LLEnvironment::instance().saveBeaconsState();
+ }
+ mEditDay.reset();
+ mEditContext = CONTEXT_UNKNOWN;
+ if (key.has(KEY_EDIT_CONTEXT))
+ {
+ std::string context = key[KEY_EDIT_CONTEXT].asString();
+
+ if (context == VALUE_CONTEXT_INVENTORY)
+ mEditContext = CONTEXT_INVENTORY;
+ else if (context == VALUE_CONTEXT_PARCEL)
+ mEditContext = CONTEXT_PARCEL;
+ else if (context == VALUE_CONTEXT_REGION)
+ mEditContext = CONTEXT_REGION;
+ }
+
+ if (key.has(KEY_CANMOD))
+ {
+ mCanMod = key[KEY_CANMOD].asBoolean();
+ }
+
+ if (mEditContext == CONTEXT_UNKNOWN)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Unknown editing context!" << LL_ENDL;
+ }
+
+ if (key.has(KEY_INVENTORY_ID))
+ {
+ loadInventoryItem(key[KEY_INVENTORY_ID].asUUID());
+ }
+ else
+ {
+ mCanSave = true;
+ mCanCopy = true;
+ mCanMod = true;
+ mCanTrans = true;
+ setEditDefaultDayCycle();
+ }
+
+ mDayLength.value(0);
+ if (key.has(KEY_DAY_LENGTH))
+ {
+ mDayLength.value(key[KEY_DAY_LENGTH].asReal());
+ }
+
+ // Time&Percentage labels
+ mCurrentTimeLabel->setTextArg("[PRCNT]", std::string("0"));
+ const S32 max_elm = 5;
+ if (mDayLength.value() != 0)
+ {
+ S32Hours hrs;
+ S32Minutes minutes;
+ LLSettingsDay::Seconds total;
+ LLUIString formatted_label = getString("time_label");
+ for (int i = 0; i < max_elm; i++)
+ {
+ total = ((mDayLength / (max_elm - 1)) * i);
+ hrs = total;
+ minutes = total - hrs;
+
+ formatted_label.setArg("[HH]", llformat("%d", hrs.value()));
+ formatted_label.setArg("[MM]", llformat("%d", abs(minutes.value())));
+ getChild("p" + llformat("%d", i), true)->setTextArg("[DSC]", formatted_label.getString());
+ }
+ hrs = mDayLength;
+ minutes = mDayLength - hrs;
+ formatted_label.setArg("[HH]", llformat("%d", hrs.value()));
+ formatted_label.setArg("[MM]", llformat("%d", abs(minutes.value())));
+ mCurrentTimeLabel->setTextArg("[DSC]", formatted_label.getString());
+ }
+ else
+ {
+ for (int i = 0; i < max_elm; i++)
+ {
+ getChild("p" + llformat("%d", i), true)->setTextArg("[DSC]", std::string());
+ }
+ mCurrentTimeLabel->setTextArg("[DSC]", std::string());
+ }
+
+ // Adjust Time&Percentage labels' location according to length
+ LLRect label_rect = getChild("p0", true)->getRect();
+ F32 slider_width = mFramesSlider->getRect().getWidth();
+ for (int i = 1; i < max_elm; i++)
+ {
+ LLTextBox *pcnt_label = getChild("p" + llformat("%d", i), true);
+ LLRect new_rect = pcnt_label->getRect();
+ new_rect.mLeft = label_rect.mLeft + (S32)(slider_width * (F32)i / (F32)(max_elm - 1)) - (S32)(pcnt_label->getTextPixelWidth() / 2);
+ pcnt_label->setRect(new_rect);
+ }
+
+ // Altitudes&Track labels
+ LLUIString formatted_label = getString("sky_track_label");
+ const LLEnvironment::altitude_list_t &altitudes = LLEnvironment::instance().getRegionAltitudes();
+ bool extended_env = LLEnvironment::instance().isExtendedEnvironmentEnabled();
+ bool use_altitudes = extended_env
+ && altitudes.size() > 0
+ && ((mEditContext == CONTEXT_PARCEL) || (mEditContext == CONTEXT_REGION));
+ for (S32 idx = 1; idx < 4; ++idx)
+ {
+ std::ostringstream convert;
+ if (use_altitudes)
+ {
+ convert << altitudes[idx] << "m";
+ }
+ else
+ {
+ convert << (idx + 1);
+ }
+ formatted_label.setArg("[ALT]", convert.str());
+ getChild(track_tabs[idx + 1], true)->setLabel(formatted_label.getString());
+ }
+
+ for (U32 i = 2; i < LLSettingsDay::TRACK_MAX; i++) //skies #2 through #4
+ {
+ getChild(track_tabs[i])->setEnabled(extended_env);
+ }
+
+ if (mEditContext == CONTEXT_INVENTORY)
+ {
+ mFlyoutControl->setShownBtnEnabled(true);
+ mFlyoutControl->setSelectedItem(ACTION_SAVE);
+ }
+ else if ((mEditContext == CONTEXT_REGION) || (mEditContext == CONTEXT_PARCEL))
+ {
+ std::string commit_str = (mEditContext == CONTEXT_PARCEL) ? STR_COMMIT_PARCEL : STR_COMMIT_REGION;
+ mFlyoutControl->setMenuItemLabel(ACTION_COMMIT, getString(commit_str));
+ mFlyoutControl->setShownBtnEnabled(true);
+ mFlyoutControl->setSelectedItem(ACTION_COMMIT);
+ }
+ else
+ {
+ mFlyoutControl->setShownBtnEnabled(false);
+ }
+}
+
+void LLFloaterEditExtDayCycle::onClose(bool app_quitting)
+{
+ doCloseInventoryFloater(app_quitting);
+ doCloseTrackFloater(app_quitting);
+ // there's no point to change environment if we're quitting
+ // or if we already restored environment
+ stopPlay();
+ LLEnvironment::instance().revertBeaconsState();
+ if (!app_quitting)
+ {
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_FAST);
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT);
+ mEditDay.reset();
+ }
+}
+
+void LLFloaterEditExtDayCycle::onFocusReceived()
+{
+ if (isInVisibleChain())
+ {
+ updateEditEnvironment();
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST);
+ }
+}
+
+void LLFloaterEditExtDayCycle::onFocusLost()
+{
+}
+
+
+void LLFloaterEditExtDayCycle::onVisibilityChange(BOOL new_visibility)
+{
+}
+
+void LLFloaterEditExtDayCycle::refresh()
+{
+ if (mEditDay)
+ {
+ LLLineEditor* name_field = getChild(TXT_DAY_NAME);
+ name_field->setText(mEditDay->getName());
+ name_field->setEnabled(mCanMod);
+ }
+
+
+ bool is_inventory_avail = canUseInventory();
+
+ bool show_commit = ((mEditContext == CONTEXT_PARCEL) || (mEditContext == CONTEXT_REGION));
+ bool show_apply = (mEditContext == CONTEXT_INVENTORY);
+
+ if (show_commit)
+ {
+ std::string commit_text;
+ if (mEditContext == CONTEXT_PARCEL)
+ commit_text = getString(STR_COMMIT_PARCEL);
+ else
+ commit_text = getString(STR_COMMIT_REGION);
+
+ mFlyoutControl->setMenuItemLabel(ACTION_COMMIT, commit_text);
+ }
+
+ mFlyoutControl->setMenuItemVisible(ACTION_COMMIT, show_commit);
+ mFlyoutControl->setMenuItemVisible(ACTION_SAVE, is_inventory_avail);
+ mFlyoutControl->setMenuItemVisible(ACTION_SAVEAS, is_inventory_avail);
+ mFlyoutControl->setMenuItemVisible(ACTION_APPLY_LOCAL, true);
+ mFlyoutControl->setMenuItemVisible(ACTION_APPLY_PARCEL, show_apply);
+ mFlyoutControl->setMenuItemVisible(ACTION_APPLY_REGION, show_apply);
+
+ mFlyoutControl->setMenuItemEnabled(ACTION_COMMIT, show_commit && !mCommitSignal.empty());
+ mFlyoutControl->setMenuItemEnabled(ACTION_SAVE, is_inventory_avail && mCanMod && !mInventoryId.isNull() && mCanSave);
+ mFlyoutControl->setMenuItemEnabled(ACTION_SAVEAS, is_inventory_avail && mCanCopy && mCanSave);
+ mFlyoutControl->setMenuItemEnabled(ACTION_APPLY_LOCAL, true);
+ mFlyoutControl->setMenuItemEnabled(ACTION_APPLY_PARCEL, canApplyParcel() && show_apply);
+ mFlyoutControl->setMenuItemEnabled(ACTION_APPLY_REGION, canApplyRegion() && show_apply);
+
+ mImportButton->setEnabled(mCanMod);
+
+ LLFloater::refresh();
+}
+
+
+void LLFloaterEditExtDayCycle::setEditDayCycle(const LLSettingsDay::ptr_t &pday)
+{
+ mExpectingAssetId.setNull();
+ mEditDay = pday->buildDeepCloneAndUncompress();
+
+ if (mEditDay->isTrackEmpty(LLSettingsDay::TRACK_WATER))
+ {
+ LL_WARNS("ENVDAYEDIT") << "No water frames found, generating replacement" << LL_ENDL;
+ mEditDay->setWaterAtKeyframe(LLSettingsVOWater::buildDefaultWater(), .5f);
+ }
+
+ if (mEditDay->isTrackEmpty(LLSettingsDay::TRACK_GROUND_LEVEL))
+ {
+ LL_WARNS("ENVDAYEDIT") << "No sky frames found, generating replacement" << LL_ENDL;
+ mEditDay->setSkyAtKeyframe(LLSettingsVOSky::buildDefaultSky(), .5f, LLSettingsDay::TRACK_GROUND_LEVEL);
+ }
+
+ mCanSave = !pday->getFlag(LLSettingsBase::FLAG_NOSAVE);
+ mCanCopy = !pday->getFlag(LLSettingsBase::FLAG_NOCOPY) && mCanSave;
+ mCanMod = !pday->getFlag(LLSettingsBase::FLAG_NOMOD) && mCanSave;
+ mCanTrans = !pday->getFlag(LLSettingsBase::FLAG_NOTRANS) && mCanSave;
+
+ updateEditEnvironment();
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_INSTANT);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+ synchronizeTabs();
+ updateTabs();
+ refresh();
+}
+
+
+void LLFloaterEditExtDayCycle::setEditDefaultDayCycle()
+{
+ mInventoryItem = nullptr;
+ mInventoryId.setNull();
+ mExpectingAssetId = LLSettingsDay::GetDefaultAssetId();
+ LLSettingsVOBase::getSettingsAsset(LLSettingsDay::GetDefaultAssetId(),
+ [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); });
+}
+
+std::string LLFloaterEditExtDayCycle::getEditName() const
+{
+ if (mEditDay)
+ return mEditDay->getName();
+ return "new";
+}
+
+void LLFloaterEditExtDayCycle::setEditName(const std::string &name)
+{
+ if (mEditDay)
+ mEditDay->setName(name);
+ getChild(TXT_DAY_NAME)->setText(name);
+}
+
+/* virtual */
+BOOL LLFloaterEditExtDayCycle::handleKeyUp(KEY key, MASK mask, BOOL called_from_parent)
+{
+ if (!mEditDay)
+ {
+ mShiftCopyEnabled = false;
+ }
+ else if (mask == MASK_SHIFT && mShiftCopyEnabled)
+ {
+ mShiftCopyEnabled = false;
+ std::string curslider = mFramesSlider->getCurSlider();
+ if (!curslider.empty())
+ {
+ F32 sliderpos = mFramesSlider->getCurSliderValue();
+
+ keymap_t::iterator it = mSliderKeyMap.find(curslider);
+ if (it != mSliderKeyMap.end())
+ {
+ if (mEditDay->moveTrackKeyframe(mCurrentTrack, (*it).second.mFrame, sliderpos))
+ {
+ (*it).second.mFrame = sliderpos;
+ }
+ else
+ {
+ mFramesSlider->setCurSliderValue((*it).second.mFrame);
+ }
+ }
+ else
+ {
+ LL_WARNS("ENVDAYEDIT") << "Failed to find frame " << sliderpos << " for slider " << curslider << LL_ENDL;
+ }
+ }
+ }
+ return LLFloater::handleKeyUp(key, mask, called_from_parent);
+}
+
+void LLFloaterEditExtDayCycle::onButtonApply(LLUICtrl *ctrl, const LLSD &data)
+{
+ std::string ctrl_action = ctrl->getName();
+
+ if (!mEditDay)
+ {
+ LL_WARNS("ENVDAYEDIT") << "mEditDay is null! This should never happen! Something is very very wrong" << LL_ENDL;
+ LLNotificationsUtil::add("EnvironmentApplyFailed");
+ closeFloater();
+ return;
+ }
+
+ LLSettingsDay::ptr_t dayclone = mEditDay->buildClone(); // create a compressed copy
+
+ if (!dayclone)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Unable to clone daycylce from editor." << LL_ENDL;
+ return;
+ }
+
+ // brute-force local texture scan
+ for (U32 i = 0; i <= LLSettingsDay::TRACK_MAX; i++)
+ {
+ LLSettingsDay::CycleTrack_t &day_track = dayclone->getCycleTrack(i);
+
+ LLSettingsDay::CycleTrack_t::iterator iter = day_track.begin();
+ LLSettingsDay::CycleTrack_t::iterator end = day_track.end();
+ S32 frame_num = 0;
+
+ while (iter != end)
+ {
+ frame_num++;
+ std::string desc;
+ bool is_local = false; // because getString can be empty
+ if (i == LLSettingsDay::TRACK_WATER)
+ {
+ LLSettingsWater::ptr_t water = std::static_pointer_cast(iter->second);
+ if (water)
+ {
+ // LLViewerFetchedTexture and check for FTT_LOCAL_FILE or check LLLocalBitmapMgr
+ if (LLLocalBitmapMgr::getInstance()->isLocal(water->getNormalMapID()))
+ {
+ desc = LLTrans::getString("EnvironmentNormalMap");
+ is_local = true;
+ }
+ else if (LLLocalBitmapMgr::getInstance()->isLocal(water->getTransparentTextureID()))
+ {
+ desc = LLTrans::getString("EnvironmentTransparent");
+ is_local = true;
+ }
+ }
+ }
+ else
+ {
+ LLSettingsSky::ptr_t sky = std::static_pointer_cast(iter->second);
+ if (sky)
+ {
+ if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getSunTextureId()))
+ {
+ desc = LLTrans::getString("EnvironmentSun");
+ is_local = true;
+ }
+ else if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getMoonTextureId()))
+ {
+ desc = LLTrans::getString("EnvironmentMoon");
+ is_local = true;
+ }
+ else if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getCloudNoiseTextureId()))
+ {
+ desc = LLTrans::getString("EnvironmentCloudNoise");
+ is_local = true;
+ }
+ else if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getBloomTextureId()))
+ {
+ desc = LLTrans::getString("EnvironmentBloom");
+ is_local = true;
+ }
+ }
+ }
+
+ if (is_local)
+ {
+ LLSD args;
+ LLButton* button = getChild(track_tabs[i], true);
+ args["TRACK"] = button->getCurrentLabel();
+ args["FRAME"] = iter->first * 100; // %
+ args["FIELD"] = desc;
+ args["FRAMENO"] = frame_num;
+ LLNotificationsUtil::add("WLLocalTextureDayBlock", args);
+ return;
+ }
+ iter++;
+ }
+ }
+
+ if (ctrl_action == ACTION_SAVE)
+ {
+ doApplyUpdateInventory(dayclone);
+ }
+ else if (ctrl_action == ACTION_SAVEAS)
+ {
+ LLSD args;
+ args["DESC"] = dayclone->getName();
+ LLNotificationsUtil::add("SaveSettingAs", args, LLSD(), boost::bind(&LLFloaterEditExtDayCycle::onSaveAsCommit, this, _1, _2, dayclone));
+ }
+ else if ((ctrl_action == ACTION_APPLY_LOCAL) ||
+ (ctrl_action == ACTION_APPLY_PARCEL) ||
+ (ctrl_action == ACTION_APPLY_REGION))
+ {
+ doApplyEnvironment(ctrl_action, dayclone);
+ }
+ else if (ctrl_action == ACTION_COMMIT)
+ {
+ doApplyCommit(dayclone);
+ }
+ else
+ {
+ LL_WARNS("ENVDAYEDIT") << "Unknown settings action '" << ctrl_action << "'" << LL_ENDL;
+ }
+}
+
+void LLFloaterEditExtDayCycle::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsDay::ptr_t &day)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 == option)
+ {
+ std::string settings_name = response["message"].asString();
+
+ LLInventoryObject::correctInventoryName(settings_name);
+ if (settings_name.empty())
+ {
+ // Ideally notification should disable 'OK' button if name won't fit our requirements,
+ // for now either display notification, or use some default name
+ settings_name = "Unnamed";
+ }
+
+ if (mCanMod)
+ {
+ doApplyCreateNewInventory(day, settings_name);
+ }
+ else if (mInventoryItem)
+ {
+ const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ LLUUID parent_id = mInventoryItem->getParentUUID();
+ if (marketplacelistings_id == parent_id)
+ {
+ parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
+ }
+
+ LLPointer cb = new LLDaySettingCopiedCallback(getHandle());
+ copy_inventory_item(
+ gAgent.getID(),
+ mInventoryItem->getPermissions().getOwner(),
+ mInventoryItem->getUUID(),
+ parent_id,
+ settings_name,
+ cb);
+ }
+ else
+ {
+ LL_WARNS() << "Failed to copy day setting" << LL_ENDL;
+ }
+ }
+}
+
+void LLFloaterEditExtDayCycle::onClickCloseBtn(bool app_quitting /*= false*/)
+{
+ if (!app_quitting)
+ checkAndConfirmSettingsLoss([this](){ closeFloater(); clearDirtyFlag(); });
+ else
+ closeFloater();
+}
+
+void LLFloaterEditExtDayCycle::onButtonImport()
+{
+ checkAndConfirmSettingsLoss([this]() { doImportFromDisk(); });
+}
+
+void LLFloaterEditExtDayCycle::onButtonLoadFrame()
+{
+ doOpenInventoryFloater((mCurrentTrack == LLSettingsDay::TRACK_WATER) ? LLSettingsType::ST_WATER : LLSettingsType::ST_SKY, LLUUID::null);
+}
+
+void LLFloaterEditExtDayCycle::onAddFrame()
+{
+ LLSettingsBase::Seconds frame(mTimeSlider->getCurSliderValue());
+ LLSettingsBase::ptr_t setting;
+ if (!mEditDay)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame while waiting for day(asset) to load." << LL_ENDL;
+ return;
+ }
+ if ((mEditDay->getSettingsNearKeyframe(frame, mCurrentTrack, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR)).second)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame too close to existing frame." << LL_ENDL;
+ return;
+ }
+ if (!mFramesSlider->canAddSliders())
+ {
+ // Shouldn't happen, button should be disabled
+ LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame when slider is full." << LL_ENDL;
+ return;
+ }
+
+ if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
+ {
+ // scratch water should always have the current water settings.
+ LLSettingsWater::ptr_t water(mScratchWater->buildClone());
+ setting = water;
+ mEditDay->setWaterAtKeyframe( std::static_pointer_cast(setting), frame);
+ }
+ else
+ {
+ // scratch sky should always have the current sky settings.
+ LLSettingsSky::ptr_t sky(mScratchSky->buildClone());
+ setting = sky;
+ mEditDay->setSkyAtKeyframe(sky, frame, mCurrentTrack);
+ }
+ setDirtyFlag();
+ addSliderFrame(frame, setting);
+ updateTabs();
+}
+
+void LLFloaterEditExtDayCycle::onRemoveFrame()
+{
+ std::string sldr_key = mFramesSlider->getCurSlider();
+ if (sldr_key.empty())
+ {
+ return;
+ }
+ setDirtyFlag();
+ removeCurrentSliderFrame();
+ updateTabs();
+}
+
+
+void LLFloaterEditExtDayCycle::onCloneTrack()
+{
+ if (!mEditDay)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to copy track while waiting for day(asset) to load." << LL_ENDL;
+ return;
+ }
+ const LLEnvironment::altitude_list_t &altitudes = LLEnvironment::instance().getRegionAltitudes();
+ bool use_altitudes = altitudes.size() > 0 && ((mEditContext == CONTEXT_PARCEL) || (mEditContext == CONTEXT_REGION));
+
+ LLSD args = LLSD::emptyArray();
+
+ S32 populated_counter = 0;
+ for (U32 i = 1; i < LLSettingsDay::TRACK_MAX; i++)
+ {
+ LLSD track;
+ track["id"] = LLSD::Integer(i);
+ bool populated = (!mEditDay->isTrackEmpty(i)) && (i != mCurrentTrack);
+ track["enabled"] = populated;
+ if (populated)
+ {
+ populated_counter++;
+ }
+ if (use_altitudes)
+ {
+ track["altitude"] = altitudes[i - 1];
+ }
+ args.append(track);
+ }
+
+ if (populated_counter > 0)
+ {
+ doOpenTrackFloater(args);
+ }
+ else
+ {
+ // Should not happen
+ LL_WARNS("ENVDAYEDIT") << "Tried to copy tracks, but there are no available sources" << LL_ENDL;
+ }
+}
+
+
+void LLFloaterEditExtDayCycle::onLoadTrack()
+{
+ LLUUID curitemId = mInventoryId;
+
+ if (mCurrentEdit && curitemId.notNull())
+ {
+ curitemId = LLFloaterSettingsPicker::findItemID(mCurrentEdit->getAssetId(), false, false);
+ }
+
+ doOpenInventoryFloater(LLSettingsType::ST_DAYCYCLE, curitemId);
+}
+
+
+void LLFloaterEditExtDayCycle::onClearTrack()
+{
+ if (!mEditDay)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to clear track while waiting for day(asset) to load." << LL_ENDL;
+ return;
+ }
+
+ if (mCurrentTrack > 1)
+ mEditDay->getCycleTrack(mCurrentTrack).clear();
+ else
+ {
+ LLSettingsDay::CycleTrack_t &track(mEditDay->getCycleTrack(mCurrentTrack));
+
+ auto first = track.begin();
+ auto last = track.end();
+ ++first;
+ track.erase(first, last);
+ }
+
+ updateEditEnvironment();
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_INSTANT);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+ synchronizeTabs();
+ updateTabs();
+ refresh();
+}
+
+void LLFloaterEditExtDayCycle::onCommitName(class LLLineEditor* caller, void* user_data)
+{
+ if (!mEditDay)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to rename day while waiting for day(asset) to load." << LL_ENDL;
+ return;
+ }
+
+ mEditDay->setName(caller->getText());
+}
+
+void LLFloaterEditExtDayCycle::onTrackSelectionCallback(const LLSD& user_data)
+{
+ U32 track_index = user_data.asInteger(); // 1-5
+ selectTrack(track_index);
+}
+
+void LLFloaterEditExtDayCycle::onPlayActionCallback(const LLSD& user_data)
+{
+ std::string action = user_data.asString();
+
+ F32 frame = mTimeSlider->getCurSliderValue();
+
+ if (action == ACTION_PLAY)
+ {
+ startPlay();
+ }
+ else if (action == ACTION_PAUSE)
+ {
+ stopPlay();
+ }
+ else if (mSliderKeyMap.size() != 0)
+ {
+ F32 new_frame = 0;
+ if (action == ACTION_FORWARD)
+ {
+ new_frame = mEditDay->getUpperBoundFrame(mCurrentTrack, frame + (mTimeSlider->getIncrement() / 2));
+ }
+ else if (action == ACTION_BACK)
+ {
+ new_frame = mEditDay->getLowerBoundFrame(mCurrentTrack, frame - (mTimeSlider->getIncrement() / 2));
+ }
+ selectFrame(new_frame, 0.0f);
+ stopPlay();
+ }
+}
+
+void LLFloaterEditExtDayCycle::onFrameSliderCallback(const LLSD &data)
+{
+ std::string curslider = mFramesSlider->getCurSlider();
+
+ if (!curslider.empty() && mEditDay)
+ {
+ F32 sliderpos = mFramesSlider->getCurSliderValue();
+
+ keymap_t::iterator it = mSliderKeyMap.find(curslider);
+ if (it != mSliderKeyMap.end())
+ {
+ if (gKeyboard->currentMask(TRUE) == MASK_SHIFT && mShiftCopyEnabled && mCanMod)
+ {
+ // don't move the point/frame as long as shift is pressed and user is attempting to copy
+ // handleKeyUp will do the move if user releases key too early.
+ if (!(mEditDay->getSettingsNearKeyframe(sliderpos, mCurrentTrack, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR)).second)
+ {
+ LL_DEBUGS("ENVDAYEDIT") << "Copying frame from " << it->second.mFrame << " to " << sliderpos << LL_ENDL;
+ LLSettingsBase::ptr_t new_settings;
+
+ // mEditDay still remembers old position, add copy at new position
+ if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
+ {
+ LLSettingsWaterPtr_t water_ptr = std::dynamic_pointer_cast(it->second.pSettings)->buildClone();
+ mEditDay->setWaterAtKeyframe(water_ptr, sliderpos);
+ new_settings = water_ptr;
+ }
+ else
+ {
+ LLSettingsSkyPtr_t sky_ptr = std::dynamic_pointer_cast(it->second.pSettings)->buildClone();
+ mEditDay->setSkyAtKeyframe(sky_ptr, sliderpos, mCurrentTrack);
+ new_settings = sky_ptr;
+ }
+ // mSliderKeyMap still remembers old position, for simplicity, just move it to be identical to slider
+ F32 old_frame = it->second.mFrame;
+ it->second.mFrame = sliderpos;
+ // slider already moved old frame, create new one in old place
+ addSliderFrame(old_frame, new_settings, false /*because we are going to reselect new one*/);
+ // reselect new frame
+ mFramesSlider->setCurSlider(it->first);
+ mShiftCopyEnabled = false;
+ setDirtyFlag();
+ }
+ }
+ else
+ {
+ // slider rounds values to nearest increments, changes can be substanntial (half increment)
+ if (abs(mFramesSlider->getNearestIncrement((*it).second.mFrame) - sliderpos) < F_APPROXIMATELY_ZERO)
+ {
+ // same value
+ mFramesSlider->setCurSliderValue((*it).second.mFrame);
+ }
+ else if (mEditDay->moveTrackKeyframe(mCurrentTrack, (*it).second.mFrame, sliderpos) && mCanMod)
+ {
+ (*it).second.mFrame = sliderpos;
+ setDirtyFlag();
+ }
+ else
+ {
+ // same value, wrong track, no such value, no mod
+ mFramesSlider->setCurSliderValue((*it).second.mFrame);
+ }
+
+ mShiftCopyEnabled = false;
+ }
+ }
+ }
+}
+
+void LLFloaterEditExtDayCycle::onFrameSliderDoubleClick(S32 x, S32 y, MASK mask)
+{
+ stopPlay();
+ onAddFrame();
+}
+
+void LLFloaterEditExtDayCycle::onFrameSliderMouseDown(S32 x, S32 y, MASK mask)
+{
+ stopPlay();
+ F32 sliderpos = mFramesSlider->getSliderValueFromPos(x, y);
+
+ std::string slidername = mFramesSlider->getCurSlider();
+
+ mShiftCopyEnabled = !slidername.empty() && gKeyboard->currentMask(TRUE) == MASK_SHIFT;
+
+ if (!slidername.empty())
+ {
+ LLRect thumb_rect = mFramesSlider->getSliderThumbRect(slidername);
+ if ((x >= thumb_rect.mRight) || (x <= thumb_rect.mLeft))
+ {
+ mFramesSlider->resetCurSlider();
+ }
+ }
+
+ mTimeSlider->setCurSliderValue(sliderpos);
+
+ updateTabs();
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+}
+
+void LLFloaterEditExtDayCycle::onFrameSliderMouseUp(S32 x, S32 y, MASK mask)
+{
+ // Only happens when clicking on empty space of frameslider, not on specific frame
+ F32 sliderpos = mFramesSlider->getSliderValueFromPos(x, y);
+
+ mTimeSlider->setCurSliderValue(sliderpos);
+ selectFrame(sliderpos, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
+}
+
+
+void LLFloaterEditExtDayCycle::onPanelDirtyFlagChanged(bool value)
+{
+ if (value)
+ setDirtyFlag();
+}
+
+void LLFloaterEditExtDayCycle::checkAndConfirmSettingsLoss(on_confirm_fn cb)
+{
+ if (isDirty())
+ {
+ LLSD args(LLSDMap("TYPE", mEditDay->getSettingsType())
+ ("NAME", mEditDay->getName()));
+
+ // create and show confirmation textbox
+ LLNotificationsUtil::add("SettingsConfirmLoss", args, LLSD(),
+ [cb](const LLSD¬if, const LLSD&resp)
+ {
+ S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+ if (opt == 0)
+ cb();
+ });
+ }
+ else if (cb)
+ {
+ cb();
+ }
+}
+
+void LLFloaterEditExtDayCycle::onTimeSliderCallback()
+{
+ stopPlay();
+ selectFrame(mTimeSlider->getCurSliderValue(), LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
+}
+
+void LLFloaterEditExtDayCycle::cloneTrack(U32 source_index, U32 dest_index)
+{
+ cloneTrack(mEditDay, source_index, dest_index);
+}
+
+void LLFloaterEditExtDayCycle::cloneTrack(const LLSettingsDay::ptr_t &source_day, U32 source_index, U32 dest_index)
+{
+ if ((source_index == LLSettingsDay::TRACK_WATER || dest_index == LLSettingsDay::TRACK_WATER) && (source_index != dest_index))
+ { // one of the tracks is a water track, the other is not
+ LLSD args;
+
+ LL_WARNS() << "Can not import water track into sky track or vice versa" << LL_ENDL;
+
+ LLButton* button = getChild(track_tabs[source_index], true);
+ args["TRACK1"] = button->getCurrentLabel();
+ button = getChild(track_tabs[dest_index], true);
+ args["TRACK2"] = button->getCurrentLabel();
+
+ LLNotificationsUtil::add("TrackLoadMismatch", args);
+ return;
+ }
+
+ // don't use replaceCycleTrack because we will end up with references, but we need to clone
+
+ // hold on to a backup of the
+ LLSettingsDay::CycleTrack_t backup_track = mEditDay->getCycleTrack(dest_index);
+
+ mEditDay->clearCycleTrack(dest_index); // because source can be empty
+ LLSettingsDay::CycleTrack_t source_track = source_day->getCycleTrack(source_index);
+ S32 addcount(0);
+ for (auto &track_frame : source_track)
+ {
+ LLSettingsBase::ptr_t pframe = track_frame.second;
+ LLSettingsBase::ptr_t pframeclone = pframe->buildDerivedClone();
+ if (pframeclone)
+ {
+ ++addcount;
+ mEditDay->setSettingsAtKeyframe(pframeclone, track_frame.first, dest_index);
+ }
+ }
+
+ if (!addcount)
+ { // nothing was actually added. Restore the old track and issue a warning.
+ mEditDay->replaceCycleTrack(dest_index, backup_track);
+
+ LLSD args;
+ LLButton* button = getChild(track_tabs[dest_index], true);
+ args["TRACK"] = button->getCurrentLabel();
+
+ LLNotificationsUtil::add("TrackLoadFailed", args);
+ }
+ setDirtyFlag();
+
+ updateSlider();
+ updateTabs();
+ updateButtons();
+}
+
+void LLFloaterEditExtDayCycle::selectTrack(U32 track_index, bool force )
+{
+ if (track_index < LLSettingsDay::TRACK_MAX)
+ mCurrentTrack = track_index;
+
+ LLButton* button = getChild(track_tabs[mCurrentTrack], true);
+ if (button->getToggleState() && !force)
+ {
+ return;
+ }
+
+ for (U32 i = 0; i < LLSettingsDay::TRACK_MAX; i++) // use max value
+ {
+ getChild(track_tabs[i], true)->setToggleState(i == mCurrentTrack);
+ }
+
+ bool show_water = (mCurrentTrack == LLSettingsDay::TRACK_WATER);
+ mSkyTabLayoutContainer->setVisible(!show_water);
+ mWaterTabLayoutContainer->setVisible(show_water);
+
+ updateSlider();
+ updateLabels();
+}
+
+void LLFloaterEditExtDayCycle::selectFrame(F32 frame, F32 slop_factor)
+{
+ mFramesSlider->resetCurSlider();
+
+ keymap_t::iterator iter = mSliderKeyMap.begin();
+ keymap_t::iterator end_iter = mSliderKeyMap.end();
+ while (iter != end_iter)
+ {
+ F32 keyframe = iter->second.mFrame;
+ F32 frame_dif = fabs(keyframe - frame);
+ if (frame_dif <= slop_factor)
+ {
+ keymap_t::iterator next_iter = std::next(iter);
+ if ((frame_dif != 0) && (next_iter != end_iter))
+ {
+ if (fabs(next_iter->second.mFrame - frame) < frame_dif)
+ {
+ mFramesSlider->setCurSlider(next_iter->first);
+ frame = next_iter->second.mFrame;
+ break;
+ }
+ }
+ mFramesSlider->setCurSlider(iter->first);
+ frame = iter->second.mFrame;
+ break;
+ }
+ iter++;
+ }
+
+ mTimeSlider->setCurSliderValue(frame);
+ // block or update tabs according to new selection
+ updateTabs();
+// LLEnvironment::instance().updateEnvironment();
+}
+
+void LLFloaterEditExtDayCycle::clearTabs()
+{
+ // Note: If this doesn't look good, init panels with default settings. It might be better looking
+ if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
+ {
+ const LLSettingsWaterPtr_t p_water = LLSettingsWaterPtr_t(NULL);
+ updateWaterTabs(p_water);
+ }
+ else
+ {
+ const LLSettingsSkyPtr_t p_sky = LLSettingsSkyPtr_t(NULL);
+ updateSkyTabs(p_sky);
+ }
+ updateButtons();
+ updateTimeAndLabel();
+}
+
+void LLFloaterEditExtDayCycle::updateTabs()
+{
+ reblendSettings();
+ synchronizeTabs();
+
+ updateButtons();
+ updateTimeAndLabel();
+}
+
+void LLFloaterEditExtDayCycle::updateWaterTabs(const LLSettingsWaterPtr_t &p_water)
+{
+ LLView* tab_container = mWaterTabLayoutContainer->getChild(TABS_WATER); //can't extract panels directly, since it is in 'tuple'
+ LLPanelSettingsWaterMainTab* panel = dynamic_cast(tab_container->findChildView("water_panel"));
+ if (panel)
+ {
+ panel->setWater(p_water);
+ }
+}
+
+void LLFloaterEditExtDayCycle::updateSkyTabs(const LLSettingsSkyPtr_t &p_sky)
+{
+ LLTabContainer* tab_container = mSkyTabLayoutContainer->getChild(TABS_SKYS); //can't extract panels directly, since they are in 'tuple'
+
+ LLPanelSettingsSky* panel;
+ panel = dynamic_cast(tab_container->findChildView("atmosphere_panel"));
+ if (panel)
+ {
+ panel->setSky(p_sky);
+ }
+ panel = dynamic_cast(tab_container->findChildView("clouds_panel"));
+ if (panel)
+ {
+ panel->setSky(p_sky);
+ }
+ panel = dynamic_cast(tab_container->findChildView("moon_panel"));
+ if (panel)
+ {
+ panel->setSky(p_sky);
+ }
+}
+
+void LLFloaterEditExtDayCycle::updateLabels()
+{
+ std::string label_arg = (mCurrentTrack == LLSettingsDay::TRACK_WATER) ? "water_label" : "sky_label";
+
+ mAddFrameButton->setLabelArg("[FRAME]", getString(label_arg));
+ mDeleteFrameButton->setLabelArg("[FRAME]", getString(label_arg));
+ mLoadFrame->setLabelArg("[FRAME]", getString(label_arg));
+}
+
+void LLFloaterEditExtDayCycle::updateButtons()
+{
+ // This logic appears to work in reverse, the add frame button
+ // is only enabled when you're on an existing frame and disabled
+ // in all the interim positions where you'd want to add a frame...
+
+ bool can_manipulate = mEditDay && !mIsPlaying && mCanMod;
+ bool can_clone(false);
+ bool can_clear(false);
+
+ if (can_manipulate)
+ {
+ if (mCurrentTrack == 0)
+ {
+ can_clone = false;
+ }
+ else
+ {
+ for (S32 track = 1; track < LLSettingsDay::TRACK_MAX; ++track)
+ {
+ if (track == mCurrentTrack)
+ continue;
+ can_clone |= !mEditDay->getCycleTrack(track).empty();
+ }
+ }
+
+ can_clear = (mCurrentTrack > 1) ? (!mEditDay->getCycleTrack(mCurrentTrack).empty()) : (mEditDay->getCycleTrack(mCurrentTrack).size() > 1);
+ }
+
+ mCloneTrack->setEnabled(can_clone);
+ mLoadTrack->setEnabled(can_manipulate);
+ mClearTrack->setEnabled(can_clear);
+ mAddFrameButton->setEnabled(can_manipulate && isAddingFrameAllowed());
+ mDeleteFrameButton->setEnabled(can_manipulate && isRemovingFrameAllowed());
+ mLoadFrame->setEnabled(can_manipulate);
+
+ // update track buttons
+ bool extended_env = LLEnvironment::instance().isExtendedEnvironmentEnabled();
+ for (S32 track = 0; track < LLSettingsDay::TRACK_MAX; ++track)
+ {
+ LLButton* button = getChild(track_tabs[track], true);
+ button->setEnabled(extended_env);
+ button->setToggleState(track == mCurrentTrack);
+ }
+}
+
+void LLFloaterEditExtDayCycle::updateSlider()
+{
+ F32 frame_position = mTimeSlider->getCurSliderValue();
+ mFramesSlider->clear();
+ mSliderKeyMap.clear();
+
+ if (!mEditDay)
+ {
+ // floater is waiting for asset
+ return;
+ }
+
+ LLSettingsDay::CycleTrack_t track = mEditDay->getCycleTrack(mCurrentTrack);
+ for (auto &track_frame : track)
+ {
+ addSliderFrame(track_frame.first, track_frame.second, false);
+ }
+
+ if (mSliderKeyMap.size() > 0)
+ {
+ // update positions
+ mLastFrameSlider = mFramesSlider->getCurSlider();
+ }
+ else
+ {
+ // disable panels
+ clearTabs();
+ mLastFrameSlider.clear();
+ }
+
+ selectFrame(frame_position, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
+}
+
+void LLFloaterEditExtDayCycle::updateTimeAndLabel()
+{
+ F32 time = mTimeSlider->getCurSliderValue();
+ mCurrentTimeLabel->setTextArg("[PRCNT]", llformat("%.0f", time * 100));
+ if (mDayLength.value() != 0)
+ {
+ LLUIString formatted_label = getString("time_label");
+
+ LLSettingsDay::Seconds total = (mDayLength * time);
+ S32Hours hrs = total;
+ S32Minutes minutes = total - hrs;
+
+ formatted_label.setArg("[HH]", llformat("%d", hrs.value()));
+ formatted_label.setArg("[MM]", llformat("%d", abs(minutes.value())));
+ mCurrentTimeLabel->setTextArg("[DSC]", formatted_label.getString());
+ }
+ else
+ {
+ mCurrentTimeLabel->setTextArg("[DSC]", std::string());
+ }
+
+ // Update blender here:
+}
+
+void LLFloaterEditExtDayCycle::addSliderFrame(F32 frame, const LLSettingsBase::ptr_t &setting, bool update_ui)
+{
+ // multi slider distinguishes elements by key/name in string format
+ // store names to map to be able to recall dependencies
+ std::string new_slider = mFramesSlider->addSlider(frame);
+ if (!new_slider.empty())
+ {
+ mSliderKeyMap[new_slider] = FrameData(frame, setting);
+
+ if (update_ui)
+ {
+ mLastFrameSlider = new_slider;
+ mTimeSlider->setCurSliderValue(frame);
+ updateTabs();
+ }
+ }
+}
+
+void LLFloaterEditExtDayCycle::removeCurrentSliderFrame()
+{
+ std::string sldr = mFramesSlider->getCurSlider();
+ if (sldr.empty())
+ {
+ return;
+ }
+ mFramesSlider->deleteCurSlider();
+ keymap_t::iterator iter = mSliderKeyMap.find(sldr);
+ if (iter != mSliderKeyMap.end())
+ {
+ LL_DEBUGS("ENVDAYEDIT") << "Removing frame from " << iter->second.mFrame << LL_ENDL;
+ LLSettingsBase::Seconds seconds(iter->second.mFrame);
+ mEditDay->removeTrackKeyframe(mCurrentTrack, seconds);
+ mSliderKeyMap.erase(iter);
+ }
+
+ mLastFrameSlider = mFramesSlider->getCurSlider();
+ mTimeSlider->setCurSliderValue(mFramesSlider->getCurSliderValue());
+ updateTabs();
+}
+
+void LLFloaterEditExtDayCycle::removeSliderFrame(F32 frame)
+{
+ keymap_t::iterator it = std::find_if(mSliderKeyMap.begin(), mSliderKeyMap.end(),
+ [frame](const keymap_t::value_type &value) { return fabs(value.second.mFrame - frame) < LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR; });
+
+ if (it != mSliderKeyMap.end())
+ {
+ mFramesSlider->deleteSlider((*it).first);
+ mSliderKeyMap.erase(it);
+ }
+
+}
+
+//-------------------------------------------------------------------------
+
+LLFloaterEditExtDayCycle::connection_t LLFloaterEditExtDayCycle::setEditCommitSignal(LLFloaterEditExtDayCycle::edit_commit_signal_t::slot_type cb)
+{
+ return mCommitSignal.connect(cb);
+}
+
+void LLFloaterEditExtDayCycle::loadInventoryItem(const LLUUID &inventoryId, bool can_trans)
+{
+ if (inventoryId.isNull())
+ {
+ mInventoryItem = nullptr;
+ mInventoryId.setNull();
+ mCanSave = true;
+ mCanCopy = true;
+ mCanMod = true;
+ mCanTrans = true;
+ return;
+ }
+
+ mInventoryId = inventoryId;
+ LL_INFOS("ENVDAYEDIT") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL;
+ mInventoryItem = gInventory.getItem(mInventoryId);
+
+ if (!mInventoryItem)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL;
+
+ LLNotificationsUtil::add("CantFindInvItem");
+ closeFloater();
+ mInventoryId.setNull();
+ mInventoryItem = nullptr;
+ return;
+ }
+
+ if (mInventoryItem->getAssetUUID().isNull())
+ {
+ LL_WARNS("ENVDAYEDIT") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" << LL_ENDL;
+
+ LLNotificationsUtil::add("UnableEditItem");
+ closeFloater();
+
+ mInventoryId.setNull();
+ mInventoryItem = nullptr;
+ return;
+ }
+
+ mCanSave = true;
+ mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID());
+ mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID());
+ mCanTrans = can_trans && mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID());
+
+ mExpectingAssetId = mInventoryItem->getAssetUUID();
+ LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(),
+ [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); });
+}
+
+void LLFloaterEditExtDayCycle::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status)
+{
+ if (asset_id != mExpectingAssetId)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Expecting {" << mExpectingAssetId << "} got {" << asset_id << "} - throwing away." << LL_ENDL;
+ return;
+ }
+ mExpectingAssetId.setNull();
+ clearDirtyFlag();
+
+ if (!settings || status)
+ {
+ LLSD args;
+ args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : "Unknown";
+ LLNotificationsUtil::add("FailedToFindSettings", args);
+ closeFloater();
+ return;
+ }
+
+ if (settings->getFlag(LLSettingsBase::FLAG_NOSAVE))
+ {
+ mCanSave = false;
+ mCanCopy = false;
+ mCanMod = false;
+ mCanTrans = false;
+ }
+ else
+ {
+ if (mCanCopy)
+ settings->clearFlag(LLSettingsBase::FLAG_NOCOPY);
+ else
+ settings->setFlag(LLSettingsBase::FLAG_NOCOPY);
+
+ if (mCanMod)
+ settings->clearFlag(LLSettingsBase::FLAG_NOMOD);
+ else
+ settings->setFlag(LLSettingsBase::FLAG_NOMOD);
+
+ if (mCanTrans)
+ settings->clearFlag(LLSettingsBase::FLAG_NOTRANS);
+ else
+ settings->setFlag(LLSettingsBase::FLAG_NOTRANS);
+
+ if (mInventoryItem)
+ settings->setName(mInventoryItem->getName());
+ }
+
+ setEditDayCycle(std::dynamic_pointer_cast(settings));
+}
+
+void LLFloaterEditExtDayCycle::updateEditEnvironment(void)
+{
+ if (!mEditDay)
+ return;
+ S32 skytrack = (mCurrentTrack) ? mCurrentTrack : 1;
+ mSkyBlender = std::make_shared(mScratchSky, mEditDay, skytrack);
+ mWaterBlender = std::make_shared(mScratchWater, mEditDay, LLSettingsDay::TRACK_WATER);
+
+ if (LLEnvironment::instance().isExtendedEnvironmentEnabled())
+ {
+ selectTrack(LLSettingsDay::TRACK_MAX, true);
+ }
+ else
+ {
+ selectTrack(1, true);
+ }
+
+ reblendSettings();
+
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, mEditSky, mEditWater);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+}
+
+void LLFloaterEditExtDayCycle::synchronizeTabs()
+{
+ // This should probably get moved into "updateTabs"
+ std::string curslider = mFramesSlider->getCurSlider();
+ bool canedit(false);
+
+ LLSettingsWater::ptr_t psettingW;
+ LLTabContainer * tabs = mWaterTabLayoutContainer->getChild(TABS_WATER);
+ if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
+ {
+ if (!mEditDay)
+ {
+ canedit = false;
+ }
+ else if (!curslider.empty())
+ {
+ canedit = !mIsPlaying;
+ // either search mEditDay or retrieve from mSliderKeyMap
+ keymap_t::iterator slider_it = mSliderKeyMap.find(curslider);
+ if (slider_it != mSliderKeyMap.end())
+ {
+ psettingW = std::static_pointer_cast(slider_it->second.pSettings);
+ }
+ }
+ mCurrentEdit = psettingW;
+ if (!psettingW)
+ {
+ canedit = false;
+ psettingW = mScratchWater;
+ }
+
+ getChild(ICN_LOCK_EDIT)->setVisible(!canedit);
+ }
+ else
+ {
+ psettingW = mScratchWater;
+ }
+ mEditWater = psettingW;
+
+ setTabsData(tabs, psettingW, canedit);
+
+ LLSettingsSky::ptr_t psettingS;
+ canedit = false;
+ tabs = mSkyTabLayoutContainer->getChild(TABS_SKYS);
+ if (mCurrentTrack != LLSettingsDay::TRACK_WATER)
+ {
+ if (!mEditDay)
+ {
+ canedit = false;
+ }
+ else if (!curslider.empty())
+ {
+ canedit = !mIsPlaying;
+ // either search mEditDay or retrieve from mSliderKeyMap
+ keymap_t::iterator slider_it = mSliderKeyMap.find(curslider);
+ if (slider_it != mSliderKeyMap.end())
+ {
+ psettingS = std::static_pointer_cast(slider_it->second.pSettings);
+ }
+ }
+ mCurrentEdit = psettingS;
+ if (!psettingS)
+ {
+ canedit = false;
+ psettingS = mScratchSky;
+ }
+
+ getChild(ICN_LOCK_EDIT)->setVisible(!canedit);
+ }
+ else
+ {
+ psettingS = mScratchSky;
+ }
+ mEditSky = psettingS;
+
+ doCloseInventoryFloater();
+ doCloseTrackFloater();
+
+ setTabsData(tabs, psettingS, canedit);
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, mEditSky, mEditWater);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+}
+
+void LLFloaterEditExtDayCycle::setTabsData(LLTabContainer * tabcontainer, const LLSettingsBase::ptr_t &settings, bool editable)
+{
+ S32 count = tabcontainer->getTabCount();
+ for (S32 idx = 0; idx < count; ++idx)
+ {
+ LLSettingsEditPanel *panel = static_cast(tabcontainer->getPanelByIndex(idx));
+ if (panel)
+ {
+ panel->setCanChangeSettings(editable & mCanMod);
+ panel->setSettings(settings);
+ }
+ }
+}
+
+
+void LLFloaterEditExtDayCycle::reblendSettings()
+{
+ F64 position = mTimeSlider->getCurSliderValue();
+
+ if ((mSkyBlender->getTrack() != mCurrentTrack) && (mCurrentTrack != LLSettingsDay::TRACK_WATER))
+ {
+ mSkyBlender->switchTrack(mCurrentTrack, position);
+ }
+ else
+ mSkyBlender->setPosition(position);
+
+ mWaterBlender->setPosition(position);
+}
+
+void LLFloaterEditExtDayCycle::doApplyCreateNewInventory(const LLSettingsDay::ptr_t &day, std::string settings_name)
+{
+ if (mInventoryItem)
+ {
+ LLUUID parent_id = mInventoryItem->getParentUUID();
+ U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner();
+ LLSettingsVOBase::createInventoryItem(day, next_owner_perm, parent_id, settings_name,
+ [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
+ }
+ else
+ {
+ LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
+ // This method knows what sort of settings object to create.
+ LLSettingsVOBase::createInventoryItem(day, parent_id, settings_name,
+ [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
+ }
+}
+
+void LLFloaterEditExtDayCycle::doApplyUpdateInventory(const LLSettingsDay::ptr_t &day)
+{
+ if (mInventoryId.isNull())
+ LLSettingsVOBase::createInventoryItem(day, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(),
+ [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
+ else
+ LLSettingsVOBase::updateInventoryItem(day, mInventoryId,
+ [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); });
+}
+
+void LLFloaterEditExtDayCycle::doApplyEnvironment(const std::string &where, const LLSettingsDay::ptr_t &day)
+{
+ U32 flags(0);
+
+ if (mInventoryItem)
+ {
+ if (!mInventoryItem->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID()))
+ flags |= LLSettingsBase::FLAG_NOMOD;
+ if (!mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
+ flags |= LLSettingsBase::FLAG_NOTRANS;
+ }
+
+ flags |= day->getFlags();
+ day->setFlag(flags);
+
+ if (where == ACTION_APPLY_LOCAL)
+ {
+ day->setName("Local"); // To distinguish and make sure there is a name. Safe, because this is a copy.
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, day);
+ }
+ else if (where == ACTION_APPLY_PARCEL)
+ {
+ LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel());
+
+ if ((!parcel) || (parcel->getLocalID() == INVALID_PARCEL_ID))
+ {
+ LL_WARNS("ENVDAYEDIT") << "Can not identify parcel. Not applying." << LL_ENDL;
+ LLNotificationsUtil::add("WLParcelApplyFail");
+ return;
+ }
+
+ if (mInventoryItem && !isDirty())
+ {
+ LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags);
+ }
+ else
+ {
+ LLEnvironment::instance().updateParcel(parcel->getLocalID(), day, -1, -1);
+ }
+ }
+ else if (where == ACTION_APPLY_REGION)
+ {
+ if (mInventoryItem && !isDirty())
+ {
+ LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags);
+ }
+ else
+ {
+ LLEnvironment::instance().updateRegion(day, -1, -1);
+ }
+ }
+ else
+ {
+ LL_WARNS("ENVDAYEDIT") << "Unknown apply '" << where << "'" << LL_ENDL;
+ return;
+ }
+
+}
+
+void LLFloaterEditExtDayCycle::doApplyCommit(LLSettingsDay::ptr_t day)
+{
+ if (!mCommitSignal.empty())
+ {
+ mCommitSignal(day);
+
+ closeFloater();
+ }
+}
+
+bool LLFloaterEditExtDayCycle::isRemovingFrameAllowed()
+{
+ if (mFramesSlider->getCurSlider().empty()) return false;
+
+ if (mCurrentTrack <= LLSettingsDay::TRACK_GROUND_LEVEL)
+ {
+ return (mSliderKeyMap.size() > 1);
+ }
+ else
+ {
+ return (mSliderKeyMap.size() > 0);
+ }
+}
+
+bool LLFloaterEditExtDayCycle::isAddingFrameAllowed()
+{
+ if (!mFramesSlider->getCurSlider().empty() || !mEditDay) return false;
+
+ LLSettingsBase::Seconds frame(mTimeSlider->getCurSliderValue());
+ if ((mEditDay->getSettingsNearKeyframe(frame, mCurrentTrack, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR)).second)
+ {
+ return false;
+ }
+ return mFramesSlider->canAddSliders();
+}
+
+void LLFloaterEditExtDayCycle::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
+{
+ LL_INFOS("ENVDAYEDIT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL;
+
+ if (inventory_id.isNull() || !results["success"].asBoolean())
+ {
+ LLNotificationsUtil::add("CantCreateInventory");
+ return;
+ }
+ onInventoryCreated(asset_id, inventory_id);
+}
+
+void LLFloaterEditExtDayCycle::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id)
+{
+ bool can_trans = true;
+ if (mInventoryItem)
+ {
+ LLPermissions perms = mInventoryItem->getPermissions();
+
+ LLInventoryItem *created_item = gInventory.getItem(mInventoryId);
+
+ if (created_item)
+ {
+ can_trans = perms.allowOperationBy(PERM_TRANSFER, gAgent.getID());
+ created_item->setPermissions(perms);
+ created_item->updateServer(false);
+ }
+ }
+
+ clearDirtyFlag();
+ setFocus(TRUE); // Call back the focus...
+ loadInventoryItem(inventory_id, can_trans);
+}
+
+void LLFloaterEditExtDayCycle::onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
+{
+ LL_WARNS("ENVDAYEDIT") << "Inventory item " << inventory_id << " has been updated with asset " << asset_id << " results are:" << results << LL_ENDL;
+
+ clearDirtyFlag();
+ if (inventory_id != mInventoryId)
+ {
+ loadInventoryItem(inventory_id);
+ }
+}
+
+void LLFloaterEditExtDayCycle::doImportFromDisk()
+{ // Load a a legacy Windlight XML from disk.
+ (new LLFilePickerReplyThread(boost::bind(&LLFloaterEditExtDayCycle::loadSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+}
+
+void LLFloaterEditExtDayCycle::loadSettingFromFile(const std::vector& filenames)
+{
+ LLSD messages;
+ if (filenames.size() < 1) return;
+ std::string filename = filenames[0];
+ LL_DEBUGS("ENVDAYEDIT") << "Selected file: " << filename << LL_ENDL;
+ LLSettingsDay::ptr_t legacyday = LLEnvironment::createDayCycleFromLegacyPreset(filename, messages);
+
+ if (!legacyday)
+ {
+ LLNotificationsUtil::add("WLImportFail", messages);
+ return;
+ }
+
+ loadInventoryItem(LLUUID::null);
+
+ mCurrentTrack = 1;
+ setDirtyFlag();
+ setEditDayCycle(legacyday);
+}
+
+bool LLFloaterEditExtDayCycle::canUseInventory() const
+{
+ return LLEnvironment::instance().isInventoryEnabled();
+}
+
+bool LLFloaterEditExtDayCycle::canApplyRegion() const
+{
+ return gAgent.canManageEstate();
+}
+
+bool LLFloaterEditExtDayCycle::canApplyParcel() const
+{
+ return LLEnvironment::instance().canAgentUpdateParcelEnvironment();
+}
+
+void LLFloaterEditExtDayCycle::startPlay()
+{
+ doCloseInventoryFloater();
+ doCloseTrackFloater();
+
+ mIsPlaying = true;
+ mFramesSlider->resetCurSlider();
+ mPlayTimer.reset();
+ mPlayTimer.start();
+ gIdleCallbacks.addFunction(onIdlePlay, this);
+ mPlayStartFrame = mTimeSlider->getCurSliderValue();
+
+ getChild("play_layout", true)->setVisible(FALSE);
+ getChild("pause_layout", true)->setVisible(TRUE);
+}
+
+void LLFloaterEditExtDayCycle::stopPlay()
+{
+ if (!mIsPlaying)
+ return;
+
+ mIsPlaying = false;
+ gIdleCallbacks.deleteFunction(onIdlePlay, this);
+ mPlayTimer.stop();
+ F32 frame = mTimeSlider->getCurSliderValue();
+ selectFrame(frame, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
+
+ getChild("play_layout", true)->setVisible(TRUE);
+ getChild("pause_layout", true)->setVisible(FALSE);
+}
+
+//static
+void LLFloaterEditExtDayCycle::onIdlePlay(void* user_data)
+{
+ if (!gDisconnected)
+ {
+ LLFloaterEditExtDayCycle* self = (LLFloaterEditExtDayCycle*)user_data;
+
+ F32 prcnt_played = self->mPlayTimer.getElapsedTimeF32() / DAY_CYCLE_PLAY_TIME_SECONDS;
+ F32 new_frame = fmod(self->mPlayStartFrame + prcnt_played, 1.f);
+
+ self->mTimeSlider->setCurSliderValue(new_frame); // will do the rounding
+ self->mSkyBlender->setPosition(new_frame);
+ self->mWaterBlender->setPosition(new_frame);
+ self->synchronizeTabs();
+ self->updateTimeAndLabel();
+ self->updateButtons();
+ }
+}
+
+
+void LLFloaterEditExtDayCycle::clearDirtyFlag()
+{
+ mIsDirty = false;
+
+ LLTabContainer* tab_container = mSkyTabLayoutContainer->getChild("sky_tabs");
+ S32 tab_count = tab_container->getTabCount();
+
+ for (S32 idx = 0; idx < tab_count; ++idx)
+ {
+ LLSettingsEditPanel *panel = static_cast(tab_container->getPanelByIndex(idx));
+ if (panel)
+ panel->clearIsDirty();
+ }
+
+ tab_container = mWaterTabLayoutContainer->getChild("water_tabs");
+ tab_count = tab_container->getTabCount();
+
+ for (S32 idx = 0; idx < tab_count; ++idx)
+ {
+ LLSettingsEditPanel *panel = static_cast(tab_container->getPanelByIndex(idx));
+ if (panel)
+ panel->clearIsDirty();
+ }
+
+}
+
+void LLFloaterEditExtDayCycle::doOpenTrackFloater(const LLSD &args)
+{
+ LLFloaterTrackPicker *picker = static_cast(mTrackFloater.get());
+
+ // Show the dialog
+ if (!picker)
+ {
+ picker = new LLFloaterTrackPicker(this);
+
+ mTrackFloater = picker->getHandle();
+
+ picker->setCommitCallback([this](LLUICtrl *, const LLSD &data){ onPickerCommitTrackId(data.asInteger()); });
+ }
+
+ picker->showPicker(args);
+}
+
+void LLFloaterEditExtDayCycle::doCloseTrackFloater(bool quitting)
+{
+ LLFloater* floaterp = mTrackFloater.get();
+
+ if (floaterp)
+ {
+ floaterp->closeFloater(quitting);
+ }
+}
+
+void LLFloaterEditExtDayCycle::onPickerCommitTrackId(U32 track_id)
+{
+ cloneTrack(track_id, mCurrentTrack);
+}
+
+void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID curritem)
+{
+// LLUI::sWindow->setCursor(UI_CURSOR_WAIT);
+ LLFloaterSettingsPicker *picker = static_cast(mInventoryFloater.get());
+
+ // Show the dialog
+ if (!picker)
+ {
+ picker = new LLFloaterSettingsPicker(this,
+ LLUUID::null);
+
+ mInventoryFloater = picker->getHandle();
+
+ picker->setCommitCallback([this](LLUICtrl *, const LLSD &data){ onPickerCommitSetting(data["ItemId"].asUUID(), data["Track"].asInteger()); });
+ }
+
+ picker->setSettingsFilter(type);
+ picker->setSettingsItemId(curritem);
+ if (type == LLSettingsType::ST_DAYCYCLE)
+ {
+ picker->setTrackMode((mCurrentTrack == LLSettingsDay::TRACK_WATER) ? LLFloaterSettingsPicker::TRACK_WATER : LLFloaterSettingsPicker::TRACK_SKY);
+ }
+ else
+ {
+ picker->setTrackMode(LLFloaterSettingsPicker::TRACK_NONE);
+ }
+ picker->openFloater();
+ picker->setFocus(TRUE);
+}
+
+void LLFloaterEditExtDayCycle::doCloseInventoryFloater(bool quitting)
+{
+ LLFloater* floaterp = mInventoryFloater.get();
+
+ if (floaterp)
+ {
+ floaterp->closeFloater(quitting);
+ }
+}
+
+void LLFloaterEditExtDayCycle::onPickerCommitSetting(LLUUID item_id, S32 track)
+{
+ LLSettingsBase::TrackPosition frame(mTimeSlider->getCurSliderValue());
+ LLViewerInventoryItem *itemp = gInventory.getItem(item_id);
+ if (itemp)
+ {
+ LLSettingsVOBase::getSettingsAsset(itemp->getAssetUUID(),
+ [this, track, frame, item_id](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoadedForInsertion(item_id, asset_id, settings, status, track, mCurrentTrack, frame); });
+ }
+}
+
+void LLFloaterEditExtDayCycle::onAssetLoadedForInsertion(LLUUID item_id, LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 source_track, S32 dest_track, LLSettingsBase::TrackPosition frame)
+{
+ std::function cb = [this, settings, frame, source_track, dest_track]()
+ {
+ if (settings->getSettingsType() == "daycycle")
+ {
+ // Load full track
+ LLSettingsDay::ptr_t pday = std::dynamic_pointer_cast(settings);
+ if (dest_track == LLSettingsDay::TRACK_WATER)
+ {
+ cloneTrack(pday, LLSettingsDay::TRACK_WATER, LLSettingsDay::TRACK_WATER);
+ }
+ else
+ {
+ cloneTrack(pday, source_track, dest_track);
+ }
+ }
+ else
+ {
+ if (!mFramesSlider->canAddSliders())
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame when slider is full." << LL_ENDL;
+ return;
+ }
+
+ // load or replace single frame
+ LLSettingsDay::CycleTrack_t::value_type nearest = mEditDay->getSettingsNearKeyframe(frame, dest_track, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
+ if (nearest.first != LLSettingsDay::INVALID_TRACKPOS)
+ { // There is already a frame near the target location. Remove it so we can put the new one in its place.
+ mEditDay->removeTrackKeyframe(dest_track, nearest.first);
+ removeSliderFrame(nearest.first);
+ }
+
+ // Don't forget to clone (we might reuse/load it couple times)
+ if (settings->getSettingsType() == "sky")
+ {
+ // Load sky to frame
+ if (dest_track != LLSettingsDay::TRACK_WATER)
+ {
+ mEditDay->setSettingsAtKeyframe(settings->buildDerivedClone(), frame, dest_track);
+ addSliderFrame(frame, settings, false);
+ }
+ else
+ {
+ LL_WARNS("ENVDAYEDIT") << "Trying to load day settings as sky" << LL_ENDL;
+ }
+ }
+ else if (settings->getSettingsType() == "water")
+ {
+ // Load water to frame
+ if (dest_track == LLSettingsDay::TRACK_WATER)
+ {
+ mEditDay->setSettingsAtKeyframe(settings->buildDerivedClone(), frame, dest_track);
+ addSliderFrame(frame, settings, false);
+ }
+ else
+ {
+ LL_WARNS("ENVDAYEDIT") << "Trying to load water settings as sky" << LL_ENDL;
+ }
+ }
+ }
+ reblendSettings();
+ synchronizeTabs();
+ };
+
+ if (!settings || status)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Could not load asset " << asset_id << " into frame. status=" << status << LL_ENDL;
+ return;
+ }
+
+ if (!mEditDay)
+ {
+ // day got reset while we were waiting for response
+ return;
+ }
+
+ LLInventoryItem *inv_item = gInventory.getItem(item_id);
+
+ if (inv_item && !inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
+ {
+ // Need to check if item is already no-transfer, otherwise make it no-transfer
+ bool no_transfer = false;
+ if (mInventoryItem)
+ {
+ no_transfer = !mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID());
+ }
+ else
+ {
+ no_transfer = mEditDay->getFlag(LLSettingsBase::FLAG_NOTRANS);
+ }
+
+ if (!no_transfer)
+ {
+ LLSD args;
+
+ // create and show confirmation textbox
+ LLNotificationsUtil::add("SettingsMakeNoTrans", args, LLSD(),
+ [this, cb](const LLSD¬if, const LLSD&resp)
+ {
+ S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+ if (opt == 0)
+ {
+ mCanTrans = false;
+ mEditDay->setFlag(LLSettingsBase::FLAG_NOTRANS);
+ cb();
+ }
+ });
+ return;
+ }
+ }
+
+ cb();
+}
diff --git a/indra/newview/llfloatereditextdaycycle.h b/indra/newview/llfloatereditextdaycycle.h
new file mode 100644
index 0000000000..b6e9fdb14f
--- /dev/null
+++ b/indra/newview/llfloatereditextdaycycle.h
@@ -0,0 +1,262 @@
+/**
+ * @file llfloatereditextdaycycle.h
+ * @brief Floater to create or edit a day cycle
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATEREDITEXTDAYCYCLE_H
+#define LL_LLFLOATEREDITEXTDAYCYCLE_H
+
+#include "llfloater.h"
+#include "llsettingsdaycycle.h"
+#include
+
+#include "llenvironment.h"
+
+class LLCheckBoxCtrl;
+class LLComboBox;
+class LLFlyoutComboBtnCtrl;
+class LLLineEditor;
+class LLMultiSliderCtrl;
+class LLTextBox;
+class LLTimeCtrl;
+class LLTabContainer;
+
+class LLInventoryItem;
+class LLDaySettingCopiedCallback;
+
+typedef std::shared_ptr LLSettingsBasePtr_t;
+
+/**
+ * Floater for creating or editing a day cycle.
+ */
+class LLFloaterEditExtDayCycle : public LLFloater
+{
+ LOG_CLASS(LLFloaterEditExtDayCycle);
+
+ friend class LLDaySettingCopiedCallback;
+
+public:
+ static const std::string KEY_INVENTORY_ID;
+ static const std::string KEY_EDIT_CONTEXT;
+ static const std::string KEY_DAY_LENGTH;
+ static const std::string KEY_CANMOD;
+
+ static const std::string VALUE_CONTEXT_INVENTORY;
+ static const std::string VALUE_CONTEXT_PARCEL;
+ static const std::string VALUE_CONTEXT_REGION;
+
+ enum edit_context_t {
+ CONTEXT_UNKNOWN,
+ CONTEXT_INVENTORY,
+ CONTEXT_PARCEL,
+ CONTEXT_REGION
+ };
+
+ typedef boost::signals2::signal edit_commit_signal_t;
+ typedef boost::signals2::connection connection_t;
+
+ LLFloaterEditExtDayCycle(const LLSD &key);
+ virtual ~LLFloaterEditExtDayCycle();
+
+ virtual BOOL postBuild() override;
+ virtual void onOpen(const LLSD& key) override;
+ virtual void onClose(bool app_quitting) override;
+ virtual void onFocusReceived() override;
+ virtual void onFocusLost() override;
+ virtual void onVisibilityChange(BOOL new_visibility) override;
+
+ connection_t setEditCommitSignal(edit_commit_signal_t::slot_type cb);
+
+ virtual void refresh() override;
+
+ void setEditDayCycle(const LLSettingsDay::ptr_t &pday);
+ void setEditDefaultDayCycle();
+ std::string getEditName() const;
+ void setEditName(const std::string &name);
+ LLUUID getEditingAssetId() { return mEditDay ? mEditDay->getAssetId() : LLUUID::null; }
+ LLUUID getEditingInventoryId() { return mInventoryId; }
+
+
+ BOOL handleKeyUp(KEY key, MASK mask, BOOL called_from_parent) override;
+
+ BOOL isDirty() const override { return getIsDirty(); }
+
+private:
+ typedef std::function on_confirm_fn;
+ F32 getCurrentFrame() const;
+
+ // flyout response/click
+ void onButtonApply(LLUICtrl *ctrl, const LLSD &data);
+ virtual void onClickCloseBtn(bool app_quitting = false) override;
+ void onButtonImport();
+ void onButtonLoadFrame();
+ void onAddFrame();
+ void onRemoveFrame();
+ void onCloneTrack();
+ void onLoadTrack();
+ void onClearTrack();
+ void onCommitName(class LLLineEditor* caller, void* user_data);
+ void onTrackSelectionCallback(const LLSD& user_data);
+ void onPlayActionCallback(const LLSD& user_data);
+ void onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsDay::ptr_t &day);
+ // time slider clicked
+ void onTimeSliderCallback();
+ // a frame moved or frame selection changed
+ void onFrameSliderCallback(const LLSD &);
+ void onFrameSliderDoubleClick(S32 x, S32 y, MASK mask);
+ void onFrameSliderMouseDown(S32 x, S32 y, MASK mask);
+ void onFrameSliderMouseUp(S32 x, S32 y, MASK mask);
+
+ void onPanelDirtyFlagChanged(bool);
+
+ void checkAndConfirmSettingsLoss(on_confirm_fn cb);
+
+ void cloneTrack(U32 source_index, U32 dest_index);
+ void cloneTrack(const LLSettingsDay::ptr_t &source_day, U32 source_index, U32 dest_index);
+ void selectTrack(U32 track_index, bool force = false);
+ void selectFrame(F32 frame, F32 slop_factor);
+ void clearTabs();
+ void updateTabs();
+ void updateWaterTabs(const LLSettingsWaterPtr_t &p_water);
+ void updateSkyTabs(const LLSettingsSkyPtr_t &p_sky);
+ void updateButtons();
+ void updateLabels();
+ void updateSlider(); //generate sliders from current track
+ void updateTimeAndLabel();
+ void addSliderFrame(F32 frame, const LLSettingsBase::ptr_t &setting, bool update_ui = true);
+ void removeCurrentSliderFrame();
+ void removeSliderFrame(F32 frame);
+
+ void loadInventoryItem(const LLUUID &inventoryId, bool can_trans = true);
+ void onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status);
+
+ void doImportFromDisk();
+ void loadSettingFromFile(const std::vector& filenames);
+ void doApplyCreateNewInventory(const LLSettingsDay::ptr_t &day, std::string settings_name);
+ void doApplyUpdateInventory(const LLSettingsDay::ptr_t &day);
+ void doApplyEnvironment(const std::string &where, const LLSettingsDay::ptr_t &day);
+ void doApplyCommit(LLSettingsDay::ptr_t day);
+ void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id);
+ void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
+ void onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
+
+ void doOpenTrackFloater(const LLSD &args);
+ void doCloseTrackFloater(bool quitting = false);
+ void onPickerCommitTrackId(U32 track_id);
+
+ void doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID curritem);
+ void doCloseInventoryFloater(bool quitting = false);
+ void onPickerCommitSetting(LLUUID item_id, S32 track);
+ void onAssetLoadedForInsertion(LLUUID item_id,
+ LLUUID asset_id,
+ LLSettingsBase::ptr_t settings,
+ S32 status,
+ S32 source_track,
+ S32 dest_track,
+ LLSettingsBase::TrackPosition dest_frame);
+
+ bool canUseInventory() const;
+ bool canApplyRegion() const;
+ bool canApplyParcel() const;
+
+ void updateEditEnvironment();
+ void synchronizeTabs();
+ void reblendSettings();
+
+ void setTabsData(LLTabContainer * tabcontainer, const LLSettingsBase::ptr_t &settings, bool editable);
+
+ // play functions
+ void startPlay();
+ void stopPlay();
+ static void onIdlePlay(void *);
+
+ bool getIsDirty() const { return mIsDirty; }
+ void setDirtyFlag() { mIsDirty = true; }
+ virtual void clearDirtyFlag();
+
+ bool isRemovingFrameAllowed();
+ bool isAddingFrameAllowed();
+
+ LLSettingsDay::ptr_t mEditDay; // edited copy
+ LLSettingsDay::Seconds mDayLength;
+ U32 mCurrentTrack;
+ std::string mLastFrameSlider;
+ bool mShiftCopyEnabled;
+
+ LLUUID mExpectingAssetId;
+
+ LLButton* mAddFrameButton;
+ LLButton* mDeleteFrameButton;
+ LLButton* mImportButton;
+ LLButton* mLoadFrame;
+ LLButton * mCloneTrack;
+ LLButton * mLoadTrack;
+ LLButton * mClearTrack;
+ LLMultiSliderCtrl* mTimeSlider;
+ LLMultiSliderCtrl* mFramesSlider;
+ LLView* mSkyTabLayoutContainer;
+ LLView* mWaterTabLayoutContainer;
+ LLTextBox* mCurrentTimeLabel;
+ LLUUID mInventoryId;
+ LLInventoryItem * mInventoryItem;
+ LLFlyoutComboBtnCtrl * mFlyoutControl;
+
+ LLHandle mInventoryFloater;
+ LLHandle mTrackFloater;
+
+ LLTrackBlenderLoopingManual::ptr_t mSkyBlender;
+ LLTrackBlenderLoopingManual::ptr_t mWaterBlender;
+ LLSettingsSky::ptr_t mScratchSky;
+ LLSettingsWater::ptr_t mScratchWater;
+ LLSettingsBase::ptr_t mCurrentEdit;
+ LLSettingsSky::ptr_t mEditSky;
+ LLSettingsWater::ptr_t mEditWater;
+
+ LLFrameTimer mPlayTimer;
+ F32 mPlayStartFrame; // an env frame
+ bool mIsPlaying;
+ bool mIsDirty;
+ bool mCanCopy;
+ bool mCanMod;
+ bool mCanTrans;
+ bool mCanSave;
+
+ edit_commit_signal_t mCommitSignal;
+
+ edit_context_t mEditContext;
+
+ // For map of sliders to parameters
+ class FrameData
+ {
+ public:
+ FrameData() : mFrame(0) {};
+ FrameData(F32 frame, LLSettingsBase::ptr_t settings) : mFrame(frame), pSettings(settings) {};
+ F32 mFrame;
+ LLSettingsBase::ptr_t pSettings;
+ };
+ typedef std::map keymap_t;
+ keymap_t mSliderKeyMap; //slider's keys vs old_frames&settings, shadows mFramesSlider
+};
+
+#endif // LL_LLFloaterEditExtDayCycle_H
diff --git a/indra/newview/llfloatereditsky.cpp b/indra/newview/llfloatereditsky.cpp
index b329f4097e..8c6d8a23ba 100644
--- a/indra/newview/llfloatereditsky.cpp
+++ b/indra/newview/llfloatereditsky.cpp
@@ -28,6 +28,8 @@
#include "llfloatereditsky.h"
+#include
+
// libs
#include "llbutton.h"
#include "llcheckboxctrl.h"
@@ -38,6 +40,7 @@
#include "llsliderctrl.h"
#include "lltabcontainer.h"
#include "lltimectrl.h"
+#include "lljoystickbutton.h"
// newview
#include "llagent.h"
@@ -45,15 +48,18 @@
#include "llregioninfomodel.h"
#include "llviewerregion.h"
-static const F32 WL_SUN_AMBIENT_SLIDER_SCALE = 3.0f;
-static const F32 WL_BLUE_HORIZON_DENSITY_SCALE = 2.0f;
-static const F32 WL_CLOUD_SLIDER_SCALE = 1.0f;
+#include "v3colorutil.h"
+#include "llenvironment.h"
+#include "llenvadapters.h"
-static F32 sun_pos_to_time24(F32 sun_pos)
+namespace
{
- return fmodf(sun_pos * 24.0f + 6, 24.0f);
+ const F32 WL_SUN_AMBIENT_SLIDER_SCALE(3.0f);
+ const F32 WL_BLUE_HORIZON_DENSITY_SCALE(2.0f);
+ const F32 WL_CLOUD_SLIDER_SCALE(1.0f);
}
+
static F32 time24_to_sun_pos(F32 time24)
{
F32 sun_pos = fmodf((time24 - 6) / 24.0f, 1.0f);
@@ -61,12 +67,13 @@ static F32 time24_to_sun_pos(F32 time24)
return sun_pos;
}
-LLFloaterEditSky::LLFloaterEditSky(const LLSD &key)
-: LLFloater(key)
-, mSkyPresetNameEditor(NULL)
-, mSkyPresetCombo(NULL)
-, mMakeDefaultCheckBox(NULL)
-, mSaveButton(NULL)
+LLFloaterEditSky::LLFloaterEditSky(const LLSD &key):
+ LLFloater(key),
+ mSkyPresetNameEditor(NULL),
+ mSkyPresetCombo(NULL),
+ mMakeDefaultCheckBox(NULL),
+ mSaveButton(NULL),
+ mSkyAdapter()
{
}
@@ -77,11 +84,14 @@ BOOL LLFloaterEditSky::postBuild()
mSkyPresetCombo = getChild("sky_preset_combo");
mMakeDefaultCheckBox = getChild("make_default_cb");
mSaveButton = getChild("save");
+ mSkyAdapter = boost::make_shared();
+
+ LLEnvironment::instance().setSkyListChange(boost::bind(&LLFloaterEditSky::onSkyPresetListChange, this));
initCallbacks();
- // Create the sun position scrubber on the slider.
- getChild