diff options
Diffstat (limited to 'indra')
25 files changed, 845 insertions, 99 deletions
diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp index 6f1e7d46b8..f188865eb0 100644 --- a/indra/llcommon/tests/llprocess_test.cpp +++ b/indra/llcommon/tests/llprocess_test.cpp @@ -969,10 +969,7 @@ namespace tut childout.getline(), "ok"); // important to get the implicit flush from std::endl py.mPy->getWritePipe().get_ostream() << "go" << std::endl; - for (i = 0; i < timeout && py.mPy->isRunning() && ! childout.contains("\n"); ++i) - { - yield(); - } + waitfor(*py.mPy); ensure("script never replied", childout.contains("\n")); ensure_equals("child didn't ack", childout.getline(), "ack"); ensure_equals("bad child termination", py.mPy->getStatus().mState, LLProcess::EXITED); diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp index 1e92847b38..bd98aa040a 100644 --- a/indra/llprimitive/llmaterial.cpp +++ b/indra/llprimitive/llmaterial.cpp @@ -51,7 +51,7 @@ #define MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD "AlphaMaskCutoff" #define MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD "DiffuseAlphaMode" -const LLColor4U LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR = LLColor4U::white; +const LLColor4U LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR(255,255,255,255); /** * Materials constants @@ -103,8 +103,8 @@ LLMaterial::LLMaterial() , mSpecularRotation(.0f) , mSpecularLightColor(LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR) , mSpecularLightExponent(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT) - , mEnvironmentIntensity(0) - , mDiffuseAlphaMode(0) + , mEnvironmentIntensity(LLMaterial::DEFAULT_ENV_INTENSITY) + , mDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) , mAlphaMaskCutoff(0) { } diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h index bedfc8f8c2..c2e49985a4 100644 --- a/indra/llprimitive/llmaterial.h +++ b/indra/llprimitive/llmaterial.h @@ -54,6 +54,7 @@ public: static const U8 DEFAULT_SPECULAR_LIGHT_EXPONENT = ((U8)(0.2f * 255)); static const LLColor4U DEFAULT_SPECULAR_LIGHT_COLOR; + static const U8 DEFAULT_ENV_INTENSITY = ((U8)(0.05f * 255)); LLMaterial(); LLMaterial(const LLSD& material_data); diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 9967c23ce8..5429489075 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -445,7 +445,9 @@ LLGLManager::LLGLManager() : mIsGFFX(FALSE), mATIOffsetVerticalLines(FALSE), mATIOldDriver(FALSE), - +#if LL_DARWIN + mIsMobileGF(FALSE), +#endif mHasRequirements(TRUE), mHasSeparateSpecularColor(FALSE), @@ -637,6 +639,13 @@ bool LLGLManager::initGL() { mIsGF3 = TRUE; } +#if LL_DARWIN + else if ((mGLRenderer.find("9400M") != std::string::npos) + || (mGLRenderer.find("9600M") != std::string::npos)) + { + mIsMobileGF = TRUE; + } +#endif } else if (mGLVendor.find("INTEL") != std::string::npos diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 1e921d1e97..767d49cbf2 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -128,6 +128,11 @@ public: BOOL mATIOffsetVerticalLines; BOOL mATIOldDriver; +#if LL_DARWIN + // Needed to distinguish problem cards on older Macs that break with Materials + BOOL mIsMobileGF; +#endif + // Whether this version of GL is good enough for SL to use BOOL mHasRequirements; diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl index 43ed41a205..ff30560adc 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl @@ -26,22 +26,28 @@ ATTRIBUTE vec4 weight4; -uniform mat4 matrixPalette[32]; +uniform mat4 matrixPalette[64]; mat4 getObjectSkinnedTransform() { - int i; - vec4 w = fract(weight4); - vec4 index = floor(weight4); - - float scale = 1.0/(w.x+w.y+w.z+w.w); - w *= scale; + float w0 = fract(weight4.x); + float w1 = fract(weight4.y); + float w2 = fract(weight4.z); + float w3 = fract(weight4.w); + + int i0 = int(floor(weight4.x)); + int i1 = int(floor(weight4.y)); + int i2 = int(floor(weight4.z)); + int i3 = int(floor(weight4.w)); + + //float scale = 1.0/(w.x+w.y+w.z+w.w); + //w *= scale; - mat4 mat = matrixPalette[int(index.x)]*w.x; - mat += matrixPalette[int(index.y)]*w.y; - mat += matrixPalette[int(index.z)]*w.z; - mat += matrixPalette[int(index.w)]*w.w; + mat4 mat = matrixPalette[i0]*w0; + mat += matrixPalette[i1]*w1; + mat += matrixPalette[i2]*w2; + mat += matrixPalette[i3]*w3; return mat; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index eb0c546af7..00717cd6a9 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -81,12 +81,10 @@ uniform vec4 specular_color; uniform float shadow_offset; -vec2 calcDirectionalLight(vec3 n, vec3 l) +vec3 calcDirectionalLight(vec3 n, vec3 l) { - vec3 refl = normalize(reflect(vary_position.xyz, n.xyz)); float a = pow(max(dot(n,l),0.0), 0.7); - refl.x = pow(pow(max(dot(refl, l), 0.0), specular_color.w * 128), 0.6); - return vec2(a, refl.x); + return vec3(a,a,a); } float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) @@ -144,8 +142,9 @@ void main() dot(normal.xyz, vary_rotation[1]), dot(normal.xyz, vary_rotation[2])); - vec2 slight = calcDirectionalLight(normal, light_position[0].xyz); - vec3 dlight = slight.x * vary_directional.rgb * vary_pointlight_col; + vec3 l = light_position[0].xyz; + vec3 dlight = calcDirectionalLight(normal, l); + dlight = dlight * vary_directional.rgb * vary_pointlight_col; vec4 col = vec4(vary_ambient + dlight, vertex_color_alpha); vec4 color = diff * col; @@ -155,13 +154,24 @@ void main() color.rgb = scaleSoftClip(color.rgb); vec3 light_col = vec3(0,0,0); +#ifdef MAC_GEFORCE_HACK + #define LIGHT_LOOP(i) \ + light_col += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, normal, light_position[i], light_direction[i], light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); + + LIGHT_LOOP(1) + LIGHT_LOOP(2) + LIGHT_LOOP(3) + LIGHT_LOOP(4) + LIGHT_LOOP(5) + LIGHT_LOOP(6) + LIGHT_LOOP(7) +#else for (int i = 2; i < 8; i++) { light_col += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, normal, light_position[i], light_direction[i], light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); } +#endif - vec3 n = normalize(reflect(vary_position.xyz, normal.xyz)); - n = vec3(dot(n, light_position[0].xyz)); color.rgb += diff.rgb * vary_pointlight_col * light_col; frag_color = color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl index 10e9670894..e872dadcc1 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl @@ -114,7 +114,10 @@ void main() vec4 diff= texture2D(diffuseMap,vary_texcoord0.xy); - vec3 dlight = calcDirectionalLight(vary_norm, light_position[0].xyz) * vary_directional.rgb * vary_pointlight_col; + vec3 n = vary_norm; + vec3 l = light_position[0].xyz; + vec3 dlight = calcDirectionalLight(n, l); + dlight = dlight * vary_directional.rgb * vary_pointlight_col; vec4 col = vec4(vary_ambient + dlight, vertex_color.a); vec4 color = diff * col; @@ -123,12 +126,23 @@ void main() color.rgb = scaleSoftClip(color.rgb); vec3 light_col = vec3(0,0,0); - +#if MAC_GEFORCE_HACK + #define LIGHT_LOOP(i) \ + light_col += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, vary_norm, light_position[i], light_direction[i], light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); + + LIGHT_LOOP(1) + LIGHT_LOOP(2) + LIGHT_LOOP(3) + LIGHT_LOOP(4) + LIGHT_LOOP(5) + LIGHT_LOOP(6) + LIGHT_LOOP(7) +#else for (int i = 2; i < 8; i++) { light_col += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, vary_norm, light_position[i], light_direction[i], light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); } - +#endif color.rgb += diff.rgb * vary_pointlight_col * light_col; frag_color = color; diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index 7bc6a9b1dd..486e806434 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -83,10 +83,10 @@ uniform mat3 env_mat; uniform vec4 specular_color; -float calcDirectionalLight(vec3 n, vec3 l) +vec3 calcDirectionalLight(vec3 n, vec3 l) { float a = pow(max(dot(n,l),0.0), 0.7); - return a; + return vec3(a,a,a); } float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) @@ -208,9 +208,9 @@ void main() { shadow = 1.0; } - #if INDEX_MODE == INDEXED + vec4 diff = diffuseLookup(vary_texcoord0.xy); #else vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy); @@ -228,7 +228,9 @@ void main() dot(normal.xyz, vary_rotation[1]), dot(normal.xyz, vary_rotation[2])); - vec3 dlight = calcDirectionalLight(normal, light_position[0].xyz) * vary_directional.rgb * vary_pointlight_col; + vec3 l = light_position[0].xyz; + vec3 dlight = calcDirectionalLight(normal, l); + dlight = dlight * vary_directional.rgb * vary_pointlight_col; vec4 col = vec4(vary_ambient + dlight *shadow, vertex_color_alpha); vec4 color = diff * col; @@ -238,12 +240,24 @@ void main() color.rgb = scaleSoftClip(color.rgb); vec3 light_col = vec3(0,0,0); +#ifdef MAC_GEFORCE_HACK + #define LIGHT_LOOP(i) \ + light_col += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, normal, light_position[i], light_direction[i], light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); + + LIGHT_LOOP(1) + LIGHT_LOOP(2) + LIGHT_LOOP(3) + LIGHT_LOOP(4) + LIGHT_LOOP(5) + LIGHT_LOOP(6) + LIGHT_LOOP(7) +#else for (int i = 2; i < 8; i++) { light_col += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, normal, light_position[i], light_direction[i], light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); } +#endif - color.rgb += diff.rgb * vary_pointlight_col * light_col; frag_color = color; diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl new file mode 100644 index 0000000000..39a5a9894d --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl @@ -0,0 +1,242 @@ +/** + * @file alphaF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#extension GL_ARB_texture_rectangle : enable + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; +uniform sampler2DRect depthMap; +uniform sampler2D diffuseMap; + +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform vec2 screen_res; + +vec3 atmosLighting(vec3 light); +vec3 scaleSoftClip(vec3 light); + +VARYING vec3 vary_ambient; +VARYING vec3 vary_directional; +VARYING vec3 vary_fragcoord; +VARYING vec3 vary_position; +VARYING vec3 vary_pointlight_col; +VARYING vec2 vary_texcoord0; +VARYING vec4 vertex_color; +VARYING vec3 vary_norm; + +uniform vec2 shadow_res; +uniform float shadow_bias; + +uniform mat4 inv_proj; + +uniform vec4 light_position[8]; +uniform vec3 light_direction[8]; +uniform vec3 light_attenuation[8]; +uniform vec3 light_diffuse[8]; + +vec3 calcDirectionalLight(vec3 n, vec3 l) +{ + float a = pow(max(dot(n,l),0.0), 0.7); + return vec3(a,a,a); +} + +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(pow(dot(n, lv), 0.7), 0.0); + } + + return da; +} + +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.xyz /= pos.w; + pos.w = 1.0; + return pos; +} + +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*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here + + float cs = shadow2D(shadowMap, stc.xyz).x; + float shadow = cs; + + shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + + return shadow*0.2; +} + + +void main() +{ + vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; + frag *= screen_res; + + float shadow = 0.0; + vec4 pos = vec4(vary_position, 1.0); + + vec4 spos = pos; + + if (spos.z > -shadow_clip.w) + { + vec4 lpos; + + vec4 near_split = shadow_clip*-0.75; + vec4 far_split = shadow_clip*-1.25; + vec4 transition_domain = near_split-far_split; + float weight = 0.0; + + if (spos.z < near_split.z) + { + lpos = shadow_matrix[3]*spos; + + float w = 1.0; + w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; + shadow += pcfShadow(shadowMap3, lpos)*w; + weight += w; + shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); + } + + if (spos.z < near_split.y && spos.z > far_split.z) + { + lpos = shadow_matrix[2]*spos; + + float w = 1.0; + w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; + w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; + shadow += pcfShadow(shadowMap2, lpos)*w; + weight += w; + } + + if (spos.z < near_split.x && spos.z > far_split.y) + { + lpos = shadow_matrix[1]*spos; + + float w = 1.0; + w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; + w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; + shadow += pcfShadow(shadowMap1, lpos)*w; + weight += w; + } + + if (spos.z > far_split.x) + { + lpos = shadow_matrix[0]*spos; + + float w = 1.0; + w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; + + shadow += pcfShadow(shadowMap0, lpos)*w; + weight += w; + } + + + shadow /= weight; + + } + else + { + shadow = 1.0; + } + vec3 n = vary_norm; + vec3 l = light_position[0].xyz; + vec3 dlight = calcDirectionalLight(n, l); + dlight = dlight * vary_directional.rgb * vary_pointlight_col; + vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy); + + vec4 col = vec4(vary_ambient + dlight*shadow, vertex_color.a); + vec4 color = diff * col; + + color.rgb = atmosLighting(color.rgb); + + color.rgb = scaleSoftClip(color.rgb); + vec3 light_col = vec3(0,0,0); + +#if MAC_GEFORCE_HACK + #define LIGHT_LOOP(i) \ + light_col += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, vary_norm, light_position[i], light_direction[i], light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); + + LIGHT_LOOP(1) + LIGHT_LOOP(2) + LIGHT_LOOP(3) + LIGHT_LOOP(4) + LIGHT_LOOP(5) + LIGHT_LOOP(6) + LIGHT_LOOP(7) +#else + for (int i = 2; i < 8; i++) + { + light_col += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, vary_norm, light_position[i], light_direction[i], light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); + } +#endif + + color.rgb += diff.rgb * vary_pointlight_col * light_col; + + frag_color = color; +} + diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl new file mode 100644 index 0000000000..566aefea6a --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl @@ -0,0 +1,248 @@ +/** + * @file alphaNonIndexedNoColorF.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 + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform float minimum_alpha; + +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; +uniform sampler2DRect depthMap; +uniform sampler2D diffuseMap; + +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform vec2 screen_res; + +vec3 atmosLighting(vec3 light); +vec3 scaleSoftClip(vec3 light); + +VARYING vec3 vary_ambient; +VARYING vec3 vary_directional; +VARYING vec3 vary_fragcoord; +VARYING vec3 vary_position; +VARYING vec3 vary_pointlight_col; +VARYING vec2 vary_texcoord0; +VARYING vec3 vary_norm; + +uniform vec2 shadow_res; + +uniform float shadow_bias; + +uniform mat4 inv_proj; + +uniform vec4 light_position[8]; +uniform vec3 light_direction[8]; +uniform vec3 light_attenuation[8]; +uniform vec3 light_diffuse[8]; + +vec3 calcDirectionalLight(vec3 n, vec3 l) +{ + float a = pow(max(dot(n,l),0.0), 0.7); + return vec3(a, a, a); +} + +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(pow(dot(n, lv), 0.7), 0.0); + } + + return da; +} + +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.xyz /= pos.w; + pos.w = 1.0; + return pos; +} + +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*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here + float cs = shadow2D(shadowMap, stc.xyz).x; + + float shadow = cs; + + shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x; + shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x; + + return shadow*0.2; +} + + +void main() +{ + vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; + frag *= screen_res; + + float shadow = 0.0; + vec4 pos = vec4(vary_position, 1.0); + + vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy); + + if (diff.a < minimum_alpha) + { + discard; + } + + vec4 spos = pos; + + if (spos.z > -shadow_clip.w) + { + vec4 lpos; + + vec4 near_split = shadow_clip*-0.75; + vec4 far_split = shadow_clip*-1.25; + vec4 transition_domain = near_split-far_split; + float weight = 0.0; + + if (spos.z < near_split.z) + { + lpos = shadow_matrix[3]*spos; + + float w = 1.0; + w -= max(spos.z-far_split.z, 0.0)/transition_domain.z; + shadow += pcfShadow(shadowMap3, lpos)*w; + weight += w; + shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); + } + + if (spos.z < near_split.y && spos.z > far_split.z) + { + lpos = shadow_matrix[2]*spos; + + float w = 1.0; + w -= max(spos.z-far_split.y, 0.0)/transition_domain.y; + w -= max(near_split.z-spos.z, 0.0)/transition_domain.z; + shadow += pcfShadow(shadowMap2, lpos)*w; + weight += w; + } + + if (spos.z < near_split.x && spos.z > far_split.y) + { + lpos = shadow_matrix[1]*spos; + + float w = 1.0; + w -= max(spos.z-far_split.x, 0.0)/transition_domain.x; + w -= max(near_split.y-spos.z, 0.0)/transition_domain.y; + shadow += pcfShadow(shadowMap1, lpos)*w; + weight += w; + } + + if (spos.z > far_split.x) + { + lpos = shadow_matrix[0]*spos; + + float w = 1.0; + w -= max(near_split.x-spos.z, 0.0)/transition_domain.x; + + shadow += pcfShadow(shadowMap0, lpos)*w; + weight += w; + } + + + shadow /= weight; + } + else + { + shadow = 1.0; + } + vec3 n = vary_norm; + vec3 l = light_position[0].xyz; + vec3 dlight = calcDirectionalLight(n, l); + dlight = dlight * vary_directional.rgb * vary_pointlight_col; + + vec4 col = vec4(vary_ambient + dlight*shadow, 1.0); + vec4 color = diff * col; + + color.rgb = atmosLighting(color.rgb); + + color.rgb = scaleSoftClip(color.rgb); + vec3 light_col = vec3(0,0,0); + +#if MAC_GEFORCE_HACK + #define LIGHT_LOOP(i) + light_col += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, vary_norm, light_position[i], light_direction[i], light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); + + LIGHT_LOOP(1) + LIGHT_LOOP(2) + LIGHT_LOOP(3) + LIGHT_LOOP(4) + LIGHT_LOOP(5) + LIGHT_LOOP(6) + LIGHT_LOOP(7) +#else + for (int i = 2; i < 8; i++) + { + light_col += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, vary_norm, light_position[i], light_direction[i], light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z); + } +#endif + color.rgb += diff.rgb * vary_pointlight_col * light_col; + + frag_color = color; +} + diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index d8d85b11c7..31b84bb258 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -253,6 +253,10 @@ void LLDrawPoolAlpha::render(S32 pass) simple_shader->setMinimumAlpha(0.33f); pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushMaskBatches(LLRenderPass::PASS_NORMMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); } if (fullbright_shader) { @@ -483,7 +487,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) current_shader = NULL; } - if (params.mMaterialID != LLMaterialID::null && current_shader == simple_shader) + if (params.mMaterial.notNull() && current_shader == simple_shader) { // I apologize in advance for not giving this its own shader. // We have a material. Supply the appropriate data here. diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index aa5687f338..0ceb7c6c45 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -274,7 +274,11 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha() void LLDrawPoolAvatar::beginDeferredRiggedAlpha() { +#if LL_DARWIN + sVertexProgram = gGLManager.mIsMobileGF ? &gDeferredSkinnedAlphaProgramMac : &gDeferredSkinnedAlphaProgram; +#else sVertexProgram = &gDeferredSkinnedAlphaProgram; +#endif gPipeline.bindDeferredShader(*sVertexProgram); sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); gPipeline.enableLightsDynamic(); diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 6e0ea78af2..1a6293c010 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -198,7 +198,11 @@ void LLDrawPoolSimple::render(S32 pass) if (LLPipeline::sRenderDeferred) { //if deferred rendering is enabled, bump faces aren't registered as simple //render bump faces here as simple so bump faces will appear under water - pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_MATERIAL, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_SPECMAP, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_NORMMAP, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_NORMSPEC, mask, TRUE, TRUE); } } else @@ -405,12 +409,20 @@ void LLDrawPoolFullbright::render(S32 pass) fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f); U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, fullbright_mask, TRUE, TRUE); } else { gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR; renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask); + pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask); + pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask); + pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask); + pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, fullbright_mask); } stop_glerror(); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 3d6acedd02..8f8b35c578 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1311,6 +1311,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { if (tep) { + LLMaterial* mat = tep->getMaterialParams().get(); + GLfloat alpha[4] = { 0.00f, @@ -1319,7 +1321,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, 0.75f }; - if (getPoolType() != LLDrawPool::POOL_ALPHA && (LLPipeline::sRenderDeferred || (LLPipeline::sRenderBump && tep->getShiny()))) + if ((!LLPipeline::sRenderDeferred || !mat) && + getPoolType() != LLDrawPool::POOL_ALPHA && + (LLPipeline::sRenderDeferred || (LLPipeline::sRenderBump && tep->getShiny()))) { color.mV[3] = U8 (alpha[tep->getShiny()] * 255); } diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp index 25e92e27d9..81284e42dd 100644 --- a/indra/newview/llmaterialmgr.cpp +++ b/indra/newview/llmaterialmgr.cpp @@ -554,8 +554,8 @@ void LLMaterialMgr::processGetQueue() postData[MATERIALS_CAP_ZIP_FIELD] = materialBinary; LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("POST", capURL, boost::bind(&LLMaterialMgr::onGetResponse, this, _1, _2, region_id)); - LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '"<< capURL << " for " << materialSize << " materials." - << "'\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL; + LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '"<< capURL << " for " << materialsData.size() << " materials." + << "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL; LLHTTPClient::post(capURL, postData, materialsResponder); } } diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 9af4bed918..f91f1f7d3a 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -291,10 +291,55 @@ void LLPanelFace::sendTexture() } LLSelectMgr::getInstance()->selectionSetImage(id); } + + mIsAlpha = FALSE; + LLGLenum image_format; + struct f2 : public LLSelectedTEGetFunctor<LLGLenum> + { + LLGLenum get(LLViewerObject* object, S32 te_index) + { + LLGLenum image_format = GL_RGB; + + LLViewerTexture* image = object->getTEImage(te_index); + if (image) image_format = image->getPrimaryFormat(); + return image_format; + } + } func2; + LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func2, image_format ); + + mIsAlpha = FALSE; + switch (image_format) + { + case GL_RGBA: + case GL_ALPHA: + { + mIsAlpha = TRUE; + } + break; + + case GL_RGB: break; + default: + { + llwarns << "Unexpected tex format in LLPanelFace...resorting to no alpha" << llendl; + } + break; + } + + LLComboBox* comboAlphaMode = getChild<LLComboBox>("combobox alphamode"); + if (comboAlphaMode) + { + U32 alpha_mode = comboAlphaMode->getCurrentIndex(); + if (mIsAlpha && (alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE)) + { + alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; + } + comboAlphaMode->selectNthItem(alpha_mode); + } + } void LLPanelFace::sendBump() -{ +{ LLComboBox* mComboBumpiness = getChild<LLComboBox>("combobox bumpiness"); if(!mComboBumpiness)return; U32 bumpiness = mComboBumpiness->getCurrentIndex(); @@ -789,7 +834,7 @@ void LLPanelFace::getState() } } alpha_get_func; - U8 alpha_mode = 1; + U8 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &alpha_get_func, alpha_mode); { @@ -798,10 +843,13 @@ void LLPanelFace::getState() if (combobox_alphamode) { - if (!mIsAlpha) - { - alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; - } + // Should never want to reflect something other than the correct state + // if it's supposed to be set to NONE, that should be enforced elsewhere + // + //if (!mIsAlpha) + //{ + // alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + //} combobox_alphamode->selectNthItem(alpha_mode); } @@ -1374,10 +1422,21 @@ void LLPanelFace::getState() getChildView("environment")->setEnabled(editable); getChild<LLUICtrl>("environment")->setTentative(!identical); getChildView("label environment")->setEnabled(editable); - getChildView("shinycolorswatch")->setEnabled(editable); getChild<LLUICtrl>("shinycolorswatch")->setTentative(!identical); getChildView("label shinycolor")->setEnabled(editable); } + // NORSPEC-94: Set default specular color to white (will get + // overwritten from material when loaded) + LLColorSwatchCtrl* mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch"); + color = LLColor4::white; + if(mShinyColorSwatch) + { + mShinyColorSwatch->setOriginal(color); + mShinyColorSwatch->set(color, TRUE); + mShinyColorSwatch->setValid(editable); + mShinyColorSwatch->setEnabled( editable ); + mShinyColorSwatch->setCanApplyImmediately( editable ); + } U8 bumpy = 0; @@ -1543,7 +1602,7 @@ void LLPanelFace::getState() { enabled = (editable && ((shiny == SHINY_TEXTURE) && !specmap_id.isNull())); identical = identical_spec_repeats; - repeats = repeats_spec; + repeats = repeats_spec * (identical_planar_texgen ? 2.0f : 1.0f); } break; @@ -1551,11 +1610,11 @@ void LLPanelFace::getState() { enabled = (editable && ((bumpy == BUMPY_TEXTURE) && !normmap_id.isNull())); identical = identical_norm_repeats; - repeats = repeats_norm; + repeats = repeats_norm * (identical_planar_texgen ? 2.0f : 1.0f); } break; } - + getChildView("rptctrl")->setEnabled(enabled); getChild<LLUICtrl>("rptctrl")->setValue(editable ? repeats : 1.0f); getChild<LLUICtrl>("rptctrl")->setTentative(!identical); @@ -1764,9 +1823,18 @@ void LLPanelFace::updateMaterial() bool identical_texgen = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, selected_texgen ); bool identical_planar_texgen = (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)); - if ((mIsAlpha && (alpha_mode != LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)) - || (bumpiness == BUMPY_TEXTURE) - || (shininess == SHINY_TEXTURE)) + LLUUID norm_map_id = getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID(); + LLUUID spec_map_id = getChild<LLTextureCtrl>("shinytexture control")->getImageAssetID(); + + bool doing_diffuse_alpha = (alpha_mode != LLMaterial::DIFFUSE_ALPHA_MODE_NONE); + bool doing_bumps = (bumpiness == BUMPY_TEXTURE) || !norm_map_id.isNull(); + bool doing_shiny = (shininess == SHINY_TEXTURE) || !spec_map_id.isNull(); + + doing_diffuse_alpha = doing_diffuse_alpha && mIsAlpha; + + if (doing_diffuse_alpha + || doing_bumps + || doing_shiny) { // The user's specified something that needs a material. bool new_material = false; @@ -1775,12 +1843,11 @@ void LLPanelFace::updateMaterial() new_material = true; mMaterial = LLMaterialPtr(new LLMaterial()); } - - mMaterial->setDiffuseAlphaMode(getChild<LLComboBox>("combobox alphamode")->getCurrentIndex()); + + mMaterial->setDiffuseAlphaMode(alpha_mode); mMaterial->setAlphaMaskCutoff((U8)(getChild<LLUICtrl>("maskcutoff")->getValue().asInteger())); - - LLUUID norm_map_id = getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID(); - if (bumpiness == BUMPY_TEXTURE) + + if (!norm_map_id.isNull()) { LL_DEBUGS("Materials") << "Setting bumpy texture, bumpiness = " << bumpiness << LL_ENDL; mMaterial->setNormalID(norm_map_id); @@ -1807,10 +1874,8 @@ void LLPanelFace::updateMaterial() mMaterial->setNormalRepeat(1.0f,1.0f); mMaterial->setNormalRotation(0.0f); } - - LLUUID spec_map_id = getChild<LLTextureCtrl>("shinytexture control")->getImageAssetID(); - if (shininess == SHINY_TEXTURE) + if (!spec_map_id.isNull()) { LL_DEBUGS("Materials") << "Setting shiny texture, shininess = " << shininess << LL_ENDL; mMaterial->setSpecularID(spec_map_id); @@ -1850,7 +1915,24 @@ void LLPanelFace::updateMaterial() } LL_DEBUGS("Materials") << "Updating material: " << mMaterial->asLLSD() << LL_ENDL; - LLSelectMgr::getInstance()->selectionSetMaterial( mMaterial ); + + LLMaterialPtr material_to_set = mMaterial; + + // If we're editing a single face and not the entire material for an object, + // we need to clone the material so that our changes to the material's settings + // don't automatically propagate to the non-selected faces + // NORSPEC-92 + // + LLObjectSelectionHandle sel = LLSelectMgr::getInstance()->getSelection(); + LLSelectNode* node = sel->getFirstNode(); + if (node) + { + if (node->getTESelectMask() != TE_SELECT_MASK_ALL) + { + material_to_set = new LLMaterial(*mMaterial); + } + } + LLSelectMgr::getInstance()->selectionSetMaterial( material_to_set ); } else { @@ -2030,7 +2112,7 @@ void LLPanelFace::onCommitBump(LLUICtrl* ctrl, void* userdata) LLComboBox* combo_bumpy = self->getChild<LLComboBox>("combobox bumpiness"); // Need 'true' here to insure that the 'Use Texture' choice is removed - // when we select something other than a spec texture + // when we select something other than a normmap texture // updateBumpyControls(combo_bumpy,self, true); self->updateMaterial(); @@ -2084,7 +2166,7 @@ void LLPanelFace::updateShinyControls(LLUICtrl* ctrl, void* userdata, bool mess_ bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled(); bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled(); U32 shiny_value = comboShiny->getCurrentIndex(); - bool show_shinyctrls = (shiny_value == SHINY_TEXTURE) && show_shininess; // Use texture + bool show_shinyctrls = (shiny_value != 0) && show_shininess; // Use texture self->getChildView("label glossiness")->setVisible(show_shinyctrls); self->getChildView("glossiness")->setVisible(show_shinyctrls); self->getChildView("label environment")->setVisible(show_shinyctrls); @@ -2288,8 +2370,38 @@ void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata) LLComboBox* combo_mattype = self->getChild<LLComboBox>("combobox mattype"); + F32 obj_scale_s = 1.0f; + F32 obj_scale_t = 1.0f; + U32 material_type = combo_mattype->getCurrentIndex(); + struct f_objscale_s : public LLSelectedTEGetFunctor<F32> + { + F32 get(LLViewerObject* object, S32 face) + { + U32 s_axis = VX; + U32 t_axis = VY; + LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); + return object->getScale().mV[s_axis]; + } + + } scale_s_func; + + struct f_objscale_t : public LLSelectedTEGetFunctor<F32> + { + F32 get(LLViewerObject* object, S32 face) + { + U32 s_axis = VX; + U32 t_axis = VY; + LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); + return object->getScale().mV[t_axis]; + } + + } scale_t_func; + + LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_s_func, obj_scale_s ); + LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_t_func, obj_scale_t ); + switch (material_type) { case MATTYPE_DIFFUSE: @@ -2302,8 +2414,8 @@ void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata) { LLUICtrl* bumpy_scale_u = self->getChild<LLUICtrl>("bumpyScaleU"); LLUICtrl* bumpy_scale_v = self->getChild<LLUICtrl>("bumpyScaleV"); - bumpy_scale_u->setValue(bumpy_scale_u->getValue().asReal() * repeats_per_meter); - bumpy_scale_v->setValue(bumpy_scale_v->getValue().asReal() * repeats_per_meter); + bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter); + bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter); self->updateMaterial(); } break; @@ -2312,8 +2424,8 @@ void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata) { LLUICtrl* shiny_scale_u = self->getChild<LLUICtrl>("shinyScaleU"); LLUICtrl* shiny_scale_v = self->getChild<LLUICtrl>("shinyScaleV"); - shiny_scale_u->setValue(shiny_scale_u->getValue().asReal() * repeats_per_meter); - shiny_scale_v->setValue(shiny_scale_v->getValue().asReal() * repeats_per_meter); + shiny_scale_u->setValue(obj_scale_s * repeats_per_meter); + shiny_scale_v->setValue(obj_scale_t * repeats_per_meter); self->updateMaterial(); } break; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 5089570319..4f58d09db3 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -104,7 +104,6 @@ const F32 SILHOUETTE_UPDATE_THRESHOLD_SQUARED = 0.02f; const S32 MAX_ACTION_QUEUE_SIZE = 20; const S32 MAX_SILS_PER_FRAME = 50; const S32 MAX_OBJECTS_PER_PACKET = 254; -const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF; // // Globals @@ -1181,7 +1180,6 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 & if (mGridMode == GRID_MODE_LOCAL && mSelectedObjects->getObjectCount()) { //LLViewerObject* root = getSelectedParentObject(mSelectedObjects->getFirstObject()); - LLBBox bbox = mSavedSelectionBBox; mGridOrigin = mSavedSelectionBBox.getCenterAgent(); mGridScale = mSavedSelectionBBox.getExtentLocal() * 0.5f; @@ -1200,7 +1198,7 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 & { mGridRotation = first_grid_object->getRenderRotation(); LLVector3 first_grid_obj_pos = first_grid_object->getRenderPosition(); - + (void)first_grid_obj_pos; LLVector4a min_extents(F32_MAX); LLVector4a max_extents(-F32_MAX); BOOL grid_changed = FALSE; diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 9d187f6272..1991b5581b 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -123,6 +123,8 @@ typedef enum e_selection_type SELECT_TYPE_HUD }ESelectType; +const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF; + // Contains information about a selected object, particularly which TEs are selected. class LLSelectNode { diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 7ec0d7df58..f42586c715 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -4639,6 +4639,7 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, mFace(NULL), mDistance(0.f), mDrawMode(LLRender::TRIANGLES), + mMaterial(NULL), mSpecColor(1.0f, 1.0f, 1.0f, 0.5f), mEnvIntensity(0.0f), mAlphaMaskCutoff(0.5f), diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 13196de1ef..426eaa1ce4 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -120,7 +120,7 @@ public: F32 mDistance; U32 mDrawMode; - LLMaterialID mMaterialID; // If this is null, the following parameters are unused. + LLMaterialPtr mMaterial; // If this is null, the following parameters are unused. LLPointer<LLViewerTexture> mSpecularMap; const LLMatrix4* mSpecularMapMatrix; LLPointer<LLViewerTexture> mNormalMap; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 45e5d4869a..eb43141c9b 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -175,6 +175,9 @@ LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram; LLGLSLShader gDeferredSkinnedDiffuseProgram; LLGLSLShader gDeferredSkinnedBumpProgram; LLGLSLShader gDeferredSkinnedAlphaProgram; +#if LL_DARWIN +LLGLSLShader gDeferredSkinnedAlphaProgramMac; +#endif LLGLSLShader gDeferredBumpProgram; LLGLSLShader gDeferredTerrainProgram; LLGLSLShader gDeferredTreeProgram; @@ -276,6 +279,9 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredSoftenProgram); mShaderList.push_back(&gDeferredAlphaProgram); mShaderList.push_back(&gDeferredSkinnedAlphaProgram); +#if LL_DARWIN + mShaderList.push_back(&gDeferredSkinnedAlphaProgramMac); +#endif mShaderList.push_back(&gDeferredFullbrightProgram); mShaderList.push_back(&gDeferredEmissiveProgram); mShaderList.push_back(&gDeferredAvatarEyesProgram); @@ -783,9 +789,6 @@ BOOL LLViewerShaderMgr::loadBasicShaders() // Load basic dependency shaders first // All of these have to load for any shaders to function -#if LL_DARWIN // Mac can't currently handle all 8 lights, - S32 sum_lights_class = 2; -#else S32 sum_lights_class = 3; // class one cards will get the lower sum lights @@ -796,14 +799,21 @@ BOOL LLViewerShaderMgr::loadBasicShaders() { sum_lights_class = 2; } -#endif // If we have sun and moon only checked, then only sum those lights. if (gPipeline.getLightingDetail() == 0) { sum_lights_class = 1; } - + +#if LL_DARWIN + // Work around driver crashes on older Macs when using deferred rendering + // NORSPEC-59 + // + if (gGLManager.mIsMobileGF) + sum_lights_class = 3; +#endif + // Use the feature table to mask out the max light level to use. Also make sure it's at least 1. S32 max_light_class = gSavedSettings.getS32("RenderShaderLightingMaxLevel"); sum_lights_class = llclamp(sum_lights_class, 1, max_light_class); @@ -1078,6 +1088,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedDiffuseProgram.unload(); gDeferredSkinnedBumpProgram.unload(); gDeferredSkinnedAlphaProgram.unload(); +#if LL_DARWIN + gDeferredSkinnedAlphaProgramMac.unload(); +#endif gDeferredBumpProgram.unload(); gDeferredImpostorProgram.unload(); gDeferredTerrainProgram.unload(); @@ -1211,6 +1224,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedAlphaProgram.addPermutation("INDEX_MODE", "2"); gDeferredSkinnedAlphaProgram.addPermutation("HAS_SKIN", "1"); gDeferredSkinnedAlphaProgram.addPermutation("IS_AVATAR_SKIN", "0"); + gDeferredSkinnedAlphaProgram.addPermutation("MAC_GEFORCE_HACK","0"); + success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL); // Hack to include uniforms for lighting without linking in lighting file @@ -1218,6 +1233,36 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = true; } +#if LL_DARWIN + if (success) + { + gDeferredSkinnedAlphaProgramMac.mName = "Deferred Skinned Alpha Shader"; + gDeferredSkinnedAlphaProgramMac.mFeatures.atmosphericHelpers = true; + gDeferredSkinnedAlphaProgramMac.mFeatures.hasObjectSkinning = true; + gDeferredSkinnedAlphaProgramMac.mFeatures.calculatesAtmospherics = true; + gDeferredSkinnedAlphaProgramMac.mFeatures.hasGamma = true; + gDeferredSkinnedAlphaProgramMac.mFeatures.hasAtmospherics = true; + gDeferredSkinnedAlphaProgramMac.mFeatures.calculatesLighting = false; + gDeferredSkinnedAlphaProgramMac.mFeatures.hasLighting = false; + gDeferredSkinnedAlphaProgramMac.mFeatures.isAlphaLighting = true; + gDeferredSkinnedAlphaProgramMac.mFeatures.disableTextureIndex = true; + gDeferredSkinnedAlphaProgramMac.mShaderFiles.clear(); + gDeferredSkinnedAlphaProgramMac.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSkinnedAlphaProgramMac.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSkinnedAlphaProgramMac.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + gDeferredSkinnedAlphaProgramMac.addPermutation("INDEX_MODE", "2"); + gDeferredSkinnedAlphaProgramMac.addPermutation("HAS_SKIN", "1"); + gDeferredSkinnedAlphaProgramMac.addPermutation("IS_AVATAR_SKIN", "0"); + gDeferredSkinnedAlphaProgramMac.addPermutation("MAC_GEFORCE_HACK","1"); + + success = gDeferredSkinnedAlphaProgramMac.createShader(NULL, NULL); + + // Hack to include uniforms for lighting without linking in lighting file + gDeferredSkinnedAlphaProgramMac.mFeatures.calculatesLighting = true; + gDeferredSkinnedAlphaProgramMac.mFeatures.hasLighting = true; + } +#endif + if (success) { gDeferredBumpProgram.mName = "Deferred Bump Shader"; @@ -1390,6 +1435,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAlphaProgram.addPermutation("INDEX_MODE", "1"); gDeferredAlphaProgram.addPermutation("HAS_SKIN", "0"); gDeferredAlphaProgram.addPermutation("IS_AVATAR_SKIN", "0"); + gDeferredAlphaProgram.addPermutation("MAC_GEFORCE_HACK","0"); success = gDeferredAlphaProgram.createShader(NULL, NULL); // Hack @@ -1563,6 +1609,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarAlphaProgram.addPermutation("INDEX_MODE", "3"); gDeferredAvatarAlphaProgram.addPermutation("HAS_SKIN", "0"); gDeferredAvatarAlphaProgram.addPermutation("IS_AVATAR_SKIN", "1"); + gDeferredAvatarAlphaProgram.addPermutation("MAC_GEFORCE_HACK","0"); success = gDeferredAvatarAlphaProgram.createShader(NULL, &mAvatarUniforms); diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index e9283d8bad..38310ed7cf 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -331,6 +331,9 @@ extern LLGLSLShader gDeferredNonIndexedDiffuseProgram; extern LLGLSLShader gDeferredSkinnedDiffuseProgram; extern LLGLSLShader gDeferredSkinnedBumpProgram; extern LLGLSLShader gDeferredSkinnedAlphaProgram; +#if LL_DARWIN +extern LLGLSLShader gDeferredSkinnedAlphaProgramMac; +#endif extern LLGLSLShader gDeferredBumpProgram; extern LLGLSLShader gDeferredTerrainProgram; extern LLGLSLShader gDeferredTreeProgram; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index a3093f069d..f861f49296 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -4362,7 +4362,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass) gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } } - + return num_indices; } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 88c9deb7a6..56aa69b25c 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3997,6 +3997,11 @@ bool can_batch_texture(LLFace* facep) return false; } + if (facep->getTextureEntry()->getMaterialParams().notNull()) + { //materials don't work with texture batching yet + return false; + } + if (facep->getTexture() && facep->getTexture()->getPrimaryFormat() == GL_ALPHA) { //can't batch invisiprims return false; @@ -4071,13 +4076,17 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U8 index = facep->getTextureIndex(); - const LLMaterialID& matid = facep->getTextureEntry()->getMaterialID(); + LLMaterial* mat = LLPipeline::sRenderDeferred ? facep->getTextureEntry()->getMaterialParams().get() : NULL; bool batchable = false; if (index < 255 && idx >= 0) { - if (index < draw_vec[idx]->mTextureList.size()) + if (mat || draw_vec[idx]->mMaterial) + { //can't batch textures when materials are present (yet) + batchable = false; + } + else if (index < draw_vec[idx]->mTextureList.size()) { if (draw_vec[idx]->mTextureList[index].isNull()) { @@ -4116,13 +4125,13 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_vec[idx]->mBump == bump && draw_vec[idx]->mTextureMatrix == tex_mat && draw_vec[idx]->mModelMatrix == model_mat && - draw_vec[idx]->mMaterialID == matid) + draw_vec[idx]->mMaterial == mat) { draw_vec[idx]->mCount += facep->getIndicesCount(); draw_vec[idx]->mEnd += facep->getGeomCount(); draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize()); - if (index >= draw_vec[idx]->mTextureList.size()) + if (index < 255 && index >= draw_vec[idx]->mTextureList.size()) { draw_vec[idx]->mTextureList.resize(index+1); draw_vec[idx]->mTextureList[index] = tex; @@ -4144,22 +4153,22 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_vec.push_back(draw_info); draw_info->mTextureMatrix = tex_mat; draw_info->mModelMatrix = model_mat; - if (facep->getTextureEntry()->getMaterialParams().notNull()) - { + if (mat) + { // We have a material. Update our draw info accordingly. - draw_info->mMaterialID = matid; + draw_info->mMaterial = mat; LLVector4 specColor; - specColor.mV[0] = facep->getTextureEntry()->getMaterialParams()->getSpecularLightColor().mV[0] * (1.f / 255.f); - specColor.mV[1] = facep->getTextureEntry()->getMaterialParams()->getSpecularLightColor().mV[1] * (1.f / 255.f); - specColor.mV[2] = facep->getTextureEntry()->getMaterialParams()->getSpecularLightColor().mV[2] * (1.f / 255.f); - specColor.mV[3] = facep->getTextureEntry()->getMaterialParams()->getSpecularLightExponent() * (1.f / 255.f); + specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f); + specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f); + specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f); + specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f); draw_info->mSpecColor = specColor; - draw_info->mEnvIntensity = facep->getTextureEntry()->getMaterialParams()->getEnvironmentIntensity() * (1.f / 255.f); - draw_info->mAlphaMaskCutoff = facep->getTextureEntry()->getMaterialParams()->getAlphaMaskCutoff() * (1.f / 255.f); - draw_info->mDiffuseAlphaMode = facep->getTextureEntry()->getMaterialParams()->getDiffuseAlphaMode(); + draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f); + draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f); + draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode(); draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset()); draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset()); - } + } else { U8 shiny = facep->getTextureEntry()->getShiny(); @@ -4476,7 +4485,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW); } - LLMaterial* mat = te->getMaterialParams().get(); + LLMaterial* mat = LLPipeline::sRenderDeferred ? te->getMaterialParams().get() : NULL; if (mat) { @@ -4933,13 +4942,13 @@ struct CompareBatchBreakerModified { return lte->getFullbright() < rte->getFullbright(); } - else if (lhs->getTexture() != rhs->getTexture()) + else if (LLPipeline::sRenderDeferred && lte->getMaterialParams() != rte->getMaterialParams()) { - return lhs->getTexture() < rhs->getTexture(); + return lte->getMaterialParams() < rte->getMaterialParams(); } else { - return lte->getMaterialParams() < rte->getMaterialParams(); + return lhs->getTexture() < rhs->getTexture(); } } }; @@ -5070,6 +5079,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: if (!can_batch_texture(facep)) { //face is bump mapped or has an animated texture matrix -- can't //batch more than 1 texture at a time + facep->setTextureIndex(0); break; } @@ -5120,6 +5130,10 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: facep->setTextureIndex(cur_tex); } } + else + { + facep->setTextureIndex(0); + } tex = texture_list[0]; } @@ -5215,8 +5229,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: index_offset += facep->getGeomCount(); indices_index += facep->getIndicesCount(); - - + //append face to appropriate render batch BOOL force_simple = facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA; |