diff options
Diffstat (limited to 'indra/newview')
29 files changed, 1096 insertions, 271 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl new file mode 100644 index 0000000000..a08550d69c --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl @@ -0,0 +1,64 @@ +/**  + * @file attachmentAlphaMaskShadowF.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 float minimum_alpha; + +uniform sampler2D diffuseMap; + +VARYING vec4 post_pos; +VARYING vec2 vary_texcoord0; +VARYING float pos_w; +VARYING float target_pos_x; +VARYING vec4 vertex_color; + +void main()  +{ +	float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a * vertex_color.a; + +	if (alpha < 0.05) // treat as totally transparent +	{ +		discard; +	} + +	if (alpha < minimum_alpha) // treat as semi-transparent +	{ +	  if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25) +	  { +	    discard; +	  } +	} + +	frag_color = vec4(1,1,1,1); + +#if !DEPTH_CLAMP	 +	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); +#endif +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl new file mode 100644 index 0000000000..b54c580ce9 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl @@ -0,0 +1,68 @@ +/**  + * @file attachmentAlphaShadowF.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 float minimum_alpha; +uniform sampler2D diffuseMap; + +VARYING float pos_w; +VARYING float target_pos_x; + +#if !DEPTH_CLAMP +VARYING vec4 post_pos; +#endif + +VARYING vec2 vary_texcoord0; +VARYING vec4 vertex_color; + +void main()  +{ +	float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a * vertex_color.a; + +	if (alpha < 0.05) // treat as totally transparent +	{ +		discard; +	} + +	if (alpha < minimum_alpha) +	{ +	  if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25) +	  { +	    discard; +	  } +	} + +	frag_color = vec4(1,1,1,1); + +#if !DEPTH_CLAMP	 +	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); +#endif + +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl new file mode 100644 index 0000000000..31b93dc36a --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl @@ -0,0 +1,74 @@ +/**  + * @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; +uniform float shadow_target_width; + +ATTRIBUTE vec4 diffuse_color; +ATTRIBUTE vec3 position; +ATTRIBUTE vec3 normal; +ATTRIBUTE vec2 texcoord0; + +mat4 getObjectSkinnedTransform(); +void passTextureIndex(); + +#if !DEPTH_CLAMP +VARYING vec4 post_pos; +#endif +VARYING vec2 vary_texcoord0; +VARYING float pos_w; +VARYING float target_pos_x; +VARYING vec4 vertex_color; + +void main() +{ +	//transform vertex +	mat4 mat = getObjectSkinnedTransform(); +	 +	mat = modelview_matrix * mat; +	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; + +	vec4 p = projection_matrix * vec4(pos, 1.0); + +	pos_w = p.w; + +	target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x; + +	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; + +	vertex_color = diffuse_color; + +#if !DEPTH_CLAMP +	p.z = max(p.z, -p.w+0.01); +    post_pos = p; +	gl_Position = p; +#else +	gl_Position = p; +#endif + +	passTextureIndex(); +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl new file mode 100644 index 0000000000..b8ce54bcb1 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl @@ -0,0 +1,65 @@ +/**  + * @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$ + */ + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform float minimum_alpha; +uniform sampler2D diffuseMap; + +#if !DEPTH_CLAMP +VARYING vec4 post_pos; +#endif + +VARYING float target_pos_x; +VARYING float pos_w; +VARYING vec2 vary_texcoord0; + +void main()  +{ +	float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a; + +	if (alpha < 0.05) // treat as totally transparent +	{ +		discard; +	} + +	if (alpha < minimum_alpha) +	{ +	  if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25) +	  { +	    discard; +	  } +	} + +	frag_color = vec4(1,1,1,1); +	 +#if !DEPTH_CLAMP +	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); +#endif +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl new file mode 100644 index 0000000000..ef49b6f4e8 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl @@ -0,0 +1,68 @@ +/**  + * @file avatarAlphaShadowF.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 float minimum_alpha; + +uniform sampler2D diffuseMap; + +#if !DEPTH_CLAMP +VARYING vec4 post_pos; +#endif + +VARYING float pos_w; +VARYING float target_pos_x; +VARYING vec2 vary_texcoord0; +VARYING vec4 vertex_color; + +void main()  +{ +	float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a * vertex_color.a; + +	if (alpha < 0.05) // treat as totally transparent +	{ +		discard; +	} + +	if (alpha < minimum_alpha) // treat as semi-transparent +	{ +	  if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25) +	  { +	    discard; +	  } +	} + +	frag_color = vec4(1,1,1,1); +	 +#if !DEPTH_CLAMP +	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); +#endif + +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl new file mode 100644 index 0000000000..d1d7ece6fe --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl @@ -0,0 +1,82 @@ +/**  + * @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 texture_matrix0; +uniform mat4 projection_matrix; +uniform float shadow_target_width; + +mat4 getSkinnedTransform(); +void passTextureIndex(); + +ATTRIBUTE vec4 diffuse_color; +ATTRIBUTE vec3 position; +ATTRIBUTE vec3 normal; +ATTRIBUTE vec2 texcoord0; + +#if !DEPTH_CLAMP +VARYING vec4 post_pos; +#endif +VARYING float pos_w; +VARYING float target_pos_x; +VARYING vec2 vary_texcoord0; +VARYING vec4 vertex_color; + +void main() +{ +	vec4 pos; +	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; + +	target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x; + +	pos_w = pos.w; + +	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; + +	vertex_color = diffuse_color; +#if !DEPTH_CLAMP +	post_pos = pos; + +	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +#else +	gl_Position = pos; +#endif + +	passTextureIndex(); +} + diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 687b76c224..125c8be317 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1083,7 +1083,7 @@ bool LLAppViewer::init()  		}  	} -// don't nag developers who need to run the executable directly +// do not pester devs who need to run the executable directly to debug  #if LL_RELEASE_FOR_DOWNLOAD  	// MAINT-8305: If we're processing a SLURL, skip the launcher check.  	if (gSavedSettings.getString("CmdLineLoginLocation").empty()) diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index ef69990170..89e861bb51 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -60,6 +60,7 @@ static U32 sShaderLevel = 0;  LLGLSLShader* LLDrawPoolAvatar::sVertexProgram = NULL;  BOOL	LLDrawPoolAvatar::sSkipOpaque = FALSE;  BOOL	LLDrawPoolAvatar::sSkipTransparent = FALSE; +S32     LLDrawPoolAvatar::sShadowPass = -1;  S32 LLDrawPoolAvatar::sDiffuseChannel = 0;  F32 LLDrawPoolAvatar::sMinimumAlpha = 0.2f; @@ -403,19 +404,33 @@ void LLDrawPoolAvatar::renderPostDeferred(S32 pass)  S32 LLDrawPoolAvatar::getNumShadowPasses()  { -	return 2; +    // avatars opaque, avatar alpha, avatar alpha mask, alpha attachments, alpha mask attachments, opaque attachments... +	return NUM_SHADOW_PASSES;  }  void LLDrawPoolAvatar::beginShadowPass(S32 pass)  {  	LL_RECORD_BLOCK_TIME(FTM_SHADOW_AVATAR); -	if (pass == 0) +	if (pass == SHADOW_PASS_AVATAR_OPAQUE)  	{  		sVertexProgram = &gDeferredAvatarShadowProgram; -		//gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.2f);		 +		if ((sShaderLevel > 0))  // for hardware blending +		{ +			sRenderingSkinned = TRUE; +			sVertexProgram->bind(); +		} +		gGL.diffuseColor4f(1,1,1,1); +	} +    else if (pass == SHADOW_PASS_AVATAR_ALPHA_BLEND) +	{ +		sVertexProgram = &gDeferredAvatarAlphaShadowProgram; + +        // bind diffuse tex so we can reference the alpha channel... +        sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); +		  		if ((sShaderLevel > 0))  // for hardware blending  		{  			sRenderingSkinned = TRUE; @@ -424,7 +439,52 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)  		gGL.diffuseColor4f(1,1,1,1);  	} -	else +    else if (pass == SHADOW_PASS_AVATAR_ALPHA_MASK) +	{ +		sVertexProgram = &gDeferredAvatarAlphaMaskShadowProgram; + +        // bind diffuse tex so we can reference the alpha channel... +        sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); +		 +		if ((sShaderLevel > 0))  // for hardware blending +		{ +			sRenderingSkinned = TRUE; +			sVertexProgram->bind(); +		} + +		gGL.diffuseColor4f(1,1,1,1); +	} +    else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_BLEND) +	{ +		sVertexProgram = &gDeferredAttachmentAlphaShadowProgram; + +        // bind diffuse tex so we can reference the alpha channel... +        sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); +		 +		if ((sShaderLevel > 0))  // for hardware blending +		{ +			sRenderingSkinned = TRUE; +			sVertexProgram->bind(); +		} + +		gGL.diffuseColor4f(1,1,1,1); +	} +    else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_MASK) +	{ +		sVertexProgram = &gDeferredAttachmentAlphaMaskShadowProgram; + +        // bind diffuse tex so we can reference the alpha channel... +		sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + +		if ((sShaderLevel > 0))  // for hardware blending +		{ +			sRenderingSkinned = TRUE; +			sVertexProgram->bind(); +		} + +		gGL.diffuseColor4f(1,1,1,1); +	} +	else // SHADOW_PASS_ATTACHMENT_OPAQUE  	{  		sVertexProgram = &gDeferredAttachmentShadowProgram;  		sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); @@ -435,20 +495,19 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)  void LLDrawPoolAvatar::endShadowPass(S32 pass)  {  	LL_RECORD_BLOCK_TIME(FTM_SHADOW_AVATAR); -	if (pass == 0) -	{ -		if (sShaderLevel > 0) -		{ -			sRenderingSkinned = FALSE; -			sVertexProgram->unbind(); -		} -	} -	else + +	if (pass == SHADOW_PASS_ATTACHMENT_OPAQUE)  	{  		LLVertexBuffer::unbind(); +	} + +    if (sShaderLevel > 0) +	{			  		sVertexProgram->unbind(); -		sVertexProgram = NULL;  	} +    sVertexProgram = NULL; +    sRenderingSkinned = FALSE; +    LLDrawPoolAvatar::sShadowPass = -1;  }  void LLDrawPoolAvatar::renderShadow(S32 pass) @@ -480,16 +539,67 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)  		return;  	} -	if (pass == 0) +    LLDrawPoolAvatar::sShadowPass = pass; + +	if (pass == SHADOW_PASS_AVATAR_OPAQUE)  	{ +        LLDrawPoolAvatar::sSkipTransparent = true;  		avatarp->renderSkinned(); +        LLDrawPoolAvatar::sSkipTransparent = false;  	} -	else +    else if (pass == SHADOW_PASS_AVATAR_ALPHA_BLEND)  	{ -		for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i) -		{ -			renderRigged(avatarp, i); -		} +        LLDrawPoolAvatar::sSkipOpaque = true; +		avatarp->renderSkinned(); +        LLDrawPoolAvatar::sSkipOpaque = false; +	} +    else if (pass == SHADOW_PASS_AVATAR_ALPHA_MASK) +	{ +        LLDrawPoolAvatar::sSkipOpaque = true; +		avatarp->renderSkinned(); +        LLDrawPoolAvatar::sSkipOpaque = false; +	} +    else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_BLEND) // rigged alpha +	{ +        LLDrawPoolAvatar::sSkipOpaque = true; +        renderRigged(avatarp, RIGGED_MATERIAL_ALPHA); +        renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE); +        renderRigged(avatarp, RIGGED_ALPHA); +        renderRigged(avatarp, RIGGED_FULLBRIGHT_ALPHA); +        renderRigged(avatarp, RIGGED_GLOW); +        renderRigged(avatarp, RIGGED_SPECMAP_BLEND); +        renderRigged(avatarp, RIGGED_NORMMAP_BLEND); +        renderRigged(avatarp, RIGGED_NORMSPEC_BLEND); +        LLDrawPoolAvatar::sSkipOpaque = false; +	} +    else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_MASK) // rigged alpha mask +	{ +        LLDrawPoolAvatar::sSkipOpaque = true; +        renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_MASK); +        renderRigged(avatarp, RIGGED_NORMMAP_MASK); +        renderRigged(avatarp, RIGGED_SPECMAP_MASK); +		renderRigged(avatarp, RIGGED_NORMSPEC_MASK);     +        renderRigged(avatarp, RIGGED_GLOW); +        LLDrawPoolAvatar::sSkipOpaque = false; +	} +	else // rigged opaque (SHADOW_PASS_ATTACHMENT_OPAQUE +	{ +        LLDrawPoolAvatar::sSkipTransparent = true; +		renderRigged(avatarp, RIGGED_MATERIAL); +        renderRigged(avatarp, RIGGED_SPECMAP); +		renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE); +		renderRigged(avatarp, RIGGED_NORMMAP);		 +		renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE); +		renderRigged(avatarp, RIGGED_NORMSPEC); +		renderRigged(avatarp, RIGGED_NORMSPEC_EMISSIVE); +		renderRigged(avatarp, RIGGED_SIMPLE); +		renderRigged(avatarp, RIGGED_FULLBRIGHT); +		renderRigged(avatarp, RIGGED_SHINY); +		renderRigged(avatarp, RIGGED_FULLBRIGHT_SHINY); +		renderRigged(avatarp, RIGGED_GLOW); +		renderRigged(avatarp, RIGGED_DEFERRED_BUMP); +		renderRigged(avatarp, RIGGED_DEFERRED_SIMPLE); +        LLDrawPoolAvatar::sSkipTransparent = false;  	}  } @@ -1693,6 +1803,10 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  	for (U32 i = 0; i < mRiggedFace[type].size(); ++i)  	{  		LLFace* face = mRiggedFace[type][i]; + +        S32 offset = face->getIndicesStart(); +		U32 count = face->getIndicesCount(); +  		LLDrawable* drawable = face->getDrawable();  		if (!drawable)  		{ @@ -1737,8 +1851,81 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  		LLVertexBuffer* buff = face->getVertexBuffer(); +        const LLTextureEntry* tex_entry = face->getTextureEntry(); +		LLMaterial* mat = tex_entry ? tex_entry->getMaterialParams().get() : nullptr; + +        if (LLDrawPoolAvatar::sShadowPass >= 0) +        { +            bool is_alpha_blend = false; +            bool is_alpha_mask  = false; + +            if (mat) +            {                 +                switch (LLMaterial::eDiffuseAlphaMode(mat->getDiffuseAlphaMode())) +                { +                    case LLMaterial::DIFFUSE_ALPHA_MODE_MASK: +                    { +                        is_alpha_mask = true; +                    } +                    break; + +                    case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND: +                    { +                        is_alpha_blend = true; +                    } +                    break; + +                    case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE: +                    case LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT: +                    case LLMaterial::DIFFUSE_ALPHA_MODE_NONE: +                    default: +                        break; +                } +            } + +            if (tex_entry) +            { +                if (tex_entry->getAlpha() <= 0.99f) +                { +                    is_alpha_blend = true; +                } +            } + +            LLViewerTexture* tex = face->getTexture(LLRender::DIFFUSE_MAP); +            if (tex) +            { +                LLGLenum image_format = tex->getPrimaryFormat(); +                if (tex->getIsAlphaMask()) +                { +                    is_alpha_mask = true; +                } +                else if (!is_alpha_mask && (image_format == GL_RGBA || image_format == GL_ALPHA)) +                { +                    is_alpha_blend = true; +                } +            } + +            // if this is alpha mask content and we're doing opaques or a non-alpha-mask shadow pass... +            if (is_alpha_mask && (LLDrawPoolAvatar::sSkipTransparent || LLDrawPoolAvatar::sShadowPass != SHADOW_PASS_ATTACHMENT_ALPHA_MASK)) +            { +                return; +            } + +            // if this is alpha blend content and we're doing opaques or a non-alpha-blend shadow pass... +            if (is_alpha_blend && (LLDrawPoolAvatar::sSkipTransparent || LLDrawPoolAvatar::sShadowPass != SHADOW_PASS_ATTACHMENT_ALPHA_BLEND)) +            { +                return; +            } + +            // if this is opaque content and we're skipping opaques... +            if (!is_alpha_mask && !is_alpha_blend && LLDrawPoolAvatar::sSkipOpaque) +            { +                return; +            } +        } +  		if (buff) -		{ +		{          			if (sShaderLevel > 0)  			{                  // upload matrix palette to shader @@ -1785,18 +1972,13 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  			}  			U16 start = face->getGeomStart(); -			U16 end = start + face->getGeomCount()-1; -			S32 offset = face->getIndicesStart(); -			U32 count = face->getIndicesCount(); +			U16 end = start + face->getGeomCount()-1;			  			/*if (glow)  			{  				gGL.diffuseColor4f(0,0,0,face->getTextureEntry()->getGlow());  			}*/ -			const LLTextureEntry* te = face->getTextureEntry(); -			LLMaterial* mat = te->getMaterialParams().get(); -  			if (mat)  			{  				//order is important here LLRender::DIFFUSE_MAP should be last, becouse it change  @@ -1827,12 +2009,12 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  				if (mat->getSpecularID().isNull())  				{ -					env = te->getShiny()*0.25f; +					env = tex_entry->getShiny()*0.25f;  					col.set(env,env,env,0);  					spec = env;  				} -				BOOL fullbright = te->getFullbright(); +				BOOL fullbright = tex_entry->getFullbright();  				sVertexProgram->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, fullbright ? 1.f : 0.f);  				sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec); @@ -1840,7 +2022,8 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  				if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)  				{ -					sVertexProgram->setMinimumAlpha(mat->getAlphaMaskCutoff()/255.f); +                    F32 cutoff = mat->getAlphaMaskCutoff()/255.f; +					sVertexProgram->setMinimumAlpha(cutoff);  				}  				else  				{ diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index b9d2204052..8afe6788ff 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -55,105 +55,7 @@ public:  							LLVertexBuffer::MAP_CLOTHWEIGHT  	}; -	virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } - -	virtual S32 getVertexShaderLevel() const; - -	LLDrawPoolAvatar(); - -	static LLMatrix4& getModelView(); - -	/*virtual*/ LLDrawPool *instancePool(); - -	/*virtual*/ S32  getNumPasses(); -	/*virtual*/ void beginRenderPass(S32 pass); -	/*virtual*/ void endRenderPass(S32 pass); -	/*virtual*/ void prerender(); -	/*virtual*/ void render(S32 pass = 0); - -	/*virtual*/ S32 getNumDeferredPasses(); -	/*virtual*/ void beginDeferredPass(S32 pass); -	/*virtual*/ void endDeferredPass(S32 pass); -	/*virtual*/ void renderDeferred(S32 pass); -	 -	/*virtual*/ S32 getNumPostDeferredPasses(); -	/*virtual*/ void beginPostDeferredPass(S32 pass); -	/*virtual*/ void endPostDeferredPass(S32 pass); -	/*virtual*/ void renderPostDeferred(S32 pass); - -	/*virtual*/ S32 getNumShadowPasses(); -	/*virtual*/ void beginShadowPass(S32 pass); -	/*virtual*/ void endShadowPass(S32 pass); -	/*virtual*/ void renderShadow(S32 pass); - -	void beginRigid(); -	void beginImpostor(); -	void beginSkinned(); -	 -	void endRigid(); -	void endImpostor(); -	void endSkinned(); - -	void beginDeferredImpostor(); -	void beginDeferredRigid(); -	void beginDeferredSkinned(); -	 -	void endDeferredImpostor(); -	void endDeferredRigid(); -	void endDeferredSkinned(); -	 -	void beginPostDeferredAlpha(); -	void endPostDeferredAlpha(); - -	void beginRiggedSimple(); -	void beginRiggedFullbright(); -	void beginRiggedFullbrightShiny(); -	void beginRiggedShinySimple(); -	void beginRiggedAlpha(); -	void beginRiggedFullbrightAlpha(); -	void beginRiggedGlow(); -	void beginDeferredRiggedAlpha(); -	void beginDeferredRiggedMaterial(S32 pass); -	void beginDeferredRiggedMaterialAlpha(S32 pass); - -	void endRiggedSimple(); -	void endRiggedFullbright(); -	void endRiggedFullbrightShiny(); -	void endRiggedShinySimple(); -	void endRiggedAlpha(); -	void endRiggedFullbrightAlpha(); -	void endRiggedGlow(); -	void endDeferredRiggedAlpha(); -	void endDeferredRiggedMaterial(S32 pass); -	void endDeferredRiggedMaterialAlpha(S32 pass); - -	void beginDeferredRiggedSimple(); -	void beginDeferredRiggedBump(); -	 -	void endDeferredRiggedSimple(); -	void endDeferredRiggedBump(); -		 -	void getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face); -	void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, -									  LLFace* facep,  -									  const LLMeshSkinInfo* skin,  -									  LLVolume* volume, -									  const LLVolumeFace& vol_face); -	void updateRiggedVertexBuffers(LLVOAvatar* avatar); - -	void renderRigged(LLVOAvatar* avatar, U32 type, bool glow = false); -	void renderRiggedSimple(LLVOAvatar* avatar); -	void renderRiggedAlpha(LLVOAvatar* avatar); -	void renderRiggedFullbrightAlpha(LLVOAvatar* avatar); -	void renderRiggedFullbright(LLVOAvatar* avatar); -	void renderRiggedShinySimple(LLVOAvatar* avatar); -	void renderRiggedFullbrightShiny(LLVOAvatar* avatar); -	void renderRiggedGlow(LLVOAvatar* avatar); -	void renderDeferredRiggedSimple(LLVOAvatar* avatar); -	void renderDeferredRiggedBump(LLVOAvatar* avatar); -	void renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass); -	 -	typedef enum +    typedef enum  	{  		RIGGED_MATERIAL=0,  		RIGGED_MATERIAL_ALPHA, @@ -258,6 +160,117 @@ public:  							 LLVertexBuffer::MAP_WEIGHT4,  	} eRiggedDataMask; +typedef enum +	{ +		SHADOW_PASS_AVATAR_OPAQUE, +        SHADOW_PASS_AVATAR_ALPHA_BLEND, +        SHADOW_PASS_AVATAR_ALPHA_MASK, +        SHADOW_PASS_ATTACHMENT_ALPHA_BLEND, +        SHADOW_PASS_ATTACHMENT_ALPHA_MASK, +        SHADOW_PASS_ATTACHMENT_OPAQUE, +        NUM_SHADOW_PASSES +	} eShadowPass; + +	virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } + +	virtual S32 getVertexShaderLevel() const; + +	LLDrawPoolAvatar(); + +	static LLMatrix4& getModelView(); + +	/*virtual*/ LLDrawPool *instancePool(); + +	/*virtual*/ S32  getNumPasses(); +	/*virtual*/ void beginRenderPass(S32 pass); +	/*virtual*/ void endRenderPass(S32 pass); +	/*virtual*/ void prerender(); +	/*virtual*/ void render(S32 pass = 0); + +	/*virtual*/ S32 getNumDeferredPasses(); +	/*virtual*/ void beginDeferredPass(S32 pass); +	/*virtual*/ void endDeferredPass(S32 pass); +	/*virtual*/ void renderDeferred(S32 pass); +	 +	/*virtual*/ S32 getNumPostDeferredPasses(); +	/*virtual*/ void beginPostDeferredPass(S32 pass); +	/*virtual*/ void endPostDeferredPass(S32 pass); +	/*virtual*/ void renderPostDeferred(S32 pass); + +	/*virtual*/ S32 getNumShadowPasses(); +	/*virtual*/ void beginShadowPass(S32 pass); +	/*virtual*/ void endShadowPass(S32 pass); +	/*virtual*/ void renderShadow(S32 pass); + +	void beginRigid(); +	void beginImpostor(); +	void beginSkinned(); +	 +	void endRigid(); +	void endImpostor(); +	void endSkinned(); + +	void beginDeferredImpostor(); +	void beginDeferredRigid(); +	void beginDeferredSkinned(); +	 +	void endDeferredImpostor(); +	void endDeferredRigid(); +	void endDeferredSkinned(); +	 +	void beginPostDeferredAlpha(); +	void endPostDeferredAlpha(); + +	void beginRiggedSimple(); +	void beginRiggedFullbright(); +	void beginRiggedFullbrightShiny(); +	void beginRiggedShinySimple(); +	void beginRiggedAlpha(); +	void beginRiggedFullbrightAlpha(); +	void beginRiggedGlow(); +	void beginDeferredRiggedAlpha(); +	void beginDeferredRiggedMaterial(S32 pass); +	void beginDeferredRiggedMaterialAlpha(S32 pass); + +	void endRiggedSimple(); +	void endRiggedFullbright(); +	void endRiggedFullbrightShiny(); +	void endRiggedShinySimple(); +	void endRiggedAlpha(); +	void endRiggedFullbrightAlpha(); +	void endRiggedGlow(); +	void endDeferredRiggedAlpha(); +	void endDeferredRiggedMaterial(S32 pass); +	void endDeferredRiggedMaterialAlpha(S32 pass); + +	void beginDeferredRiggedSimple(); +	void beginDeferredRiggedBump(); +	 +	void endDeferredRiggedSimple(); +	void endDeferredRiggedBump(); +		 +	void getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face); +	void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, +									  LLFace* facep,  +									  const LLMeshSkinInfo* skin,  +									  LLVolume* volume, +									  const LLVolumeFace& vol_face); +	void updateRiggedVertexBuffers(LLVOAvatar* avatar); + +	void renderRigged(LLVOAvatar* avatar, U32 type, bool glow = false); +	void renderRiggedSimple(LLVOAvatar* avatar); +	void renderRiggedAlpha(LLVOAvatar* avatar); +	void renderRiggedFullbrightAlpha(LLVOAvatar* avatar); +	void renderRiggedFullbright(LLVOAvatar* avatar); +	void renderRiggedShinySimple(LLVOAvatar* avatar); +	void renderRiggedFullbrightShiny(LLVOAvatar* avatar); +	void renderRiggedGlow(LLVOAvatar* avatar); +	void renderDeferredRiggedSimple(LLVOAvatar* avatar); +	void renderDeferredRiggedBump(LLVOAvatar* avatar); +	void renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass); +	 +	 +  	void addRiggedFace(LLFace* facep, U32 type);  	void removeRiggedFace(LLFace* facep);  @@ -271,6 +284,7 @@ public:  	static BOOL sSkipOpaque;  	static BOOL sSkipTransparent; +    static S32  sShadowPass;  	static S32 sDiffuseChannel;  	static F32 sMinimumAlpha; diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp index 73120a0242..f46152dcec 100644 --- a/indra/newview/llhudeffectlookat.cpp +++ b/indra/newview/llhudeffectlookat.cpp @@ -495,6 +495,8 @@ void LLHUDEffectLookAt::render()  	{  		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +		LLGLDisable gls_stencil(GL_STENCIL_TEST); +  		LLVector3 target = mTargetPos + ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->mHeadp->getWorldPosition();  		gGL.matrixMode(LLRender::MM_MODELVIEW);  		gGL.pushMatrix(); diff --git a/indra/newview/llhudeffectpointat.cpp b/indra/newview/llhudeffectpointat.cpp index 44c8db19c0..cc772c8f5c 100644 --- a/indra/newview/llhudeffectpointat.cpp +++ b/indra/newview/llhudeffectpointat.cpp @@ -322,6 +322,7 @@ void LLHUDEffectPointAt::render()  	update();  	if (sDebugPointAt && mTargetType != POINTAT_TARGET_NONE)  	{ +		LLGLDisable gls_stencil(GL_STENCIL_TEST);  		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  		LLVector3 target = mTargetPos + mSourceObject->getRenderPosition(); diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp index 825c2b31be..85a878c4a2 100644 --- a/indra/newview/llhudicon.cpp +++ b/indra/newview/llhudicon.cpp @@ -80,6 +80,7 @@ void LLHUDIcon::renderIcon(BOOL for_select)  {  	LLGLSUIDefault texture_state;  	LLGLDepthTest gls_depth(GL_TRUE); +	LLGLDisable gls_stencil(GL_STENCIL_TEST);  	if (for_select)  	{  		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index c7d108b6de..81d862a827 100644 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -224,6 +224,7 @@ void LLHUDNameTag::render()  	if (sDisplayText)  	{  		LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); +		LLGLDisable gls_stencil(GL_STENCIL_TEST);  		renderText(FALSE);  	}  } diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 6b1e196182..ef3b234f50 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -102,6 +102,7 @@ void LLHUDText::render()  	if (!mOnHUDAttachment && sDisplayText)  	{  		LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); +		LLGLDisable gls_stencil(GL_STENCIL_TEST);  		renderText();  	}  } diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index bc93fa2c20..deef3dbce7 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -113,6 +113,11 @@ void LLLoginInstance::connect(LLPointer<LLCredential> credentials)  {  	std::vector<std::string> uris;  	LLGridManager::getInstance()->getLoginURIs(uris); +    if (uris.size() < 1) +    { +        LL_WARNS() << "Failed to get login URIs during connect. No connect for you!" << LL_ENDL; +        return; +    }  	connect(uris.front(), credentials);  } diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 01ce4470f0..b71e98b102 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -550,8 +550,14 @@ struct LLPanelFaceSetAlignedTEFunctor : public LLSelectedTEFunctor  			if (set_aligned)  			{  				object->setTEOffset(te, uv_offset.mV[VX], uv_offset.mV[VY]); -				object->setTEScale(te, uv_scale.mV[VX], uv_scale.mV[VY]); +                object->setTEScale(te, uv_scale.mV[VX], uv_scale.mV[VY]);  				object->setTERotation(te, uv_rot); +                LLPanelFace::LLSelectedTEMaterial::setNormalOffsetX(mPanel, uv_offset.mV[VX], te); +                LLPanelFace::LLSelectedTEMaterial::setNormalOffsetY(mPanel, uv_offset.mV[VY], te); +                LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetX(mPanel, uv_offset.mV[VX], te); +                LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetY(mPanel, uv_offset.mV[VY], te); +				LLPanelFace::LLSelectedTEMaterial::setNormalRotation(mPanel, uv_rot, te); +                LLPanelFace::LLSelectedTEMaterial::setSpecularRotation(mPanel, uv_rot, te);  			}  		}  		if (!set_aligned) @@ -599,12 +605,19 @@ struct LLPanelFaceGetIsAlignedTEFunctor : public LLSelectedTEFunctor  			tep->getOffset(&st_offset.mV[VX], &st_offset.mV[VY]);  			tep->getScale(&st_scale.mV[VX], &st_scale.mV[VY]);  			F32 st_rot = tep->getRotation(); + +            bool eq_offset_x = is_approx_equal_fraction(st_offset.mV[VX], aligned_st_offset.mV[VX], 12); +            bool eq_offset_y = is_approx_equal_fraction(st_offset.mV[VY], aligned_st_offset.mV[VY], 12); +            bool eq_scale_x  = is_approx_equal_fraction(st_scale.mV[VX], aligned_st_scale.mV[VX], 12); +            bool eq_scale_y  = is_approx_equal_fraction(st_scale.mV[VY], aligned_st_scale.mV[VY], 12); +            bool eq_rot      = is_approx_equal_fraction(st_rot, aligned_st_rot, 6); +  			// needs a fuzzy comparison, because of fp errors -			if (is_approx_equal_fraction(st_offset.mV[VX], aligned_st_offset.mV[VX], 12) &&  -				is_approx_equal_fraction(st_offset.mV[VY], aligned_st_offset.mV[VY], 12) &&  -				is_approx_equal_fraction(st_scale.mV[VX], aligned_st_scale.mV[VX], 12) && -				is_approx_equal_fraction(st_scale.mV[VY], aligned_st_scale.mV[VY], 12) && -				is_approx_equal_fraction(st_rot, aligned_st_rot, 14)) +			if (eq_offset_x &&  +				eq_offset_y &&  +				eq_scale_x && +				eq_scale_y && +				eq_rot)  			{  				return true;  			} @@ -967,9 +980,9 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)  			F32 spec_scale_s = 1.f;  			F32 norm_scale_s = 1.f; -			LLSelectedTE::getScaleS(						diff_scale_s, identical_diff_scale_s);			 -			LLSelectedTEMaterial::getSpecularRepeatX( spec_scale_s, identical_spec_scale_s); -			LLSelectedTEMaterial::getNormalRepeatX(	norm_scale_s, identical_norm_scale_s); +			LLSelectedTE::getScaleS(diff_scale_s, identical_diff_scale_s);			 +			LLSelectedTEMaterial::getSpecularRepeatX(spec_scale_s, identical_spec_scale_s); +			LLSelectedTEMaterial::getNormalRepeatX(norm_scale_s, identical_norm_scale_s);  			diff_scale_s = editable ? diff_scale_s : 1.0f;  			diff_scale_s *= identical_planar_texgen ? 2.0f : 1.0f; @@ -2051,10 +2064,10 @@ void LLPanelFace::onCommitMaterialShinyScaleY(LLUICtrl* ctrl, void* userdata)  }  //static -void LLPanelFace::syncMaterialRot(LLPanelFace* self, F32 rot) +void LLPanelFace::syncMaterialRot(LLPanelFace* self, F32 rot, int te)  { -	LLSelectedTEMaterial::setNormalRotation(self,rot * DEG_TO_RAD); -	LLSelectedTEMaterial::setSpecularRotation(self,rot * DEG_TO_RAD); +	LLSelectedTEMaterial::setNormalRotation(self,rot * DEG_TO_RAD, te); +	LLSelectedTEMaterial::setSpecularRotation(self,rot * DEG_TO_RAD, te);  	self->sendTextureInfo();  } @@ -2432,7 +2445,7 @@ void LLPanelFace::LLSelectedTE::getFace(LLFace*& face_to_return, bool& identical  			return (object->mDrawable) ? object->mDrawable->getFace(te): NULL;  		}  	} get_te_face_func; -	identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, face_to_return); +	identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, face_to_return, false, (LLFace*)nullptr);  }  void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, bool& identical_face) diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 7c084cb0ab..4937966034 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -179,7 +179,7 @@ protected:  	static void		syncRepeatY(LLPanelFace* self, F32 scaleV);  	static void		syncOffsetX(LLPanelFace* self, F32 offsetU);  	static void		syncOffsetY(LLPanelFace* self, F32 offsetV); -	static void 	syncMaterialRot(LLPanelFace* self, F32 rot); +	static void 	syncMaterialRot(LLPanelFace* self, F32 rot, int te = -1);  	static void		onCommitMaterialShinyScaleX(	LLUICtrl* ctrl, void* userdata);  	static void		onCommitMaterialShinyScaleY(	LLUICtrl* ctrl, void* userdata); @@ -252,7 +252,7 @@ private:  		typename DataType,  		typename SetValueType,  		void (LLMaterial::*MaterialEditFunc)(SetValueType data) > -	static void edit(LLPanelFace* p, DataType data) +	static void edit(LLPanelFace* p, DataType data, int te = -1)  	{  		LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc > edit(data);  		struct LLSelectedTEEditMaterial : public LLSelectedTEMaterialFunctor @@ -327,14 +327,14 @@ private:  			LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >*	_edit;  			LLPanelFace*																			_panel;  		} editor(p, &edit); -		LLSelectMgr::getInstance()->selectionSetMaterialParams(&editor); +        LLSelectMgr::getInstance()->selectionSetMaterialParams(&editor, te);  	}  	template<  		typename DataType, -		typename ReturnType, +		typename ReturnType,          		ReturnType (LLMaterial::* const MaterialGetFunc)() const  > -	static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value) +	static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value, bool has_tolerance = false, DataType tolerance = DataType())  	{  		DataType data_value;  		struct GetTEMaterialVal : public LLSelectedTEGetFunctor<DataType> @@ -359,7 +359,7 @@ private:  			}  			DataType _default;  		} GetFunc(default_value); -		identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetFunc, data_value); +		identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetFunc, data_value, has_tolerance, tolerance);  		data_to_return = data_value;  	} @@ -367,7 +367,7 @@ private:  		typename DataType,  		typename ReturnType, // some kids just have to different...  		ReturnType (LLTextureEntry::* const TEGetFunc)() const > -	static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value) +	static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value, bool has_tolerance = false, DataType tolerance = DataType())  	{  		DataType data_value;  		struct GetTEVal : public LLSelectedTEGetFunctor<DataType> @@ -381,7 +381,7 @@ private:  			}  			DataType _default;  		} GetTEValFunc(default_value); -		identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value ); +		identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value, has_tolerance, tolerance );  		data_to_return = data_value;  	} @@ -414,6 +414,7 @@ private:  	bool mUpdateInFlight;  	bool mUpdatePending; +public:  	#if defined(DEF_GET_MAT_STATE)  		#undef DEF_GET_MAT_STATE  	#endif @@ -426,29 +427,29 @@ private:  		DEF_EDIT_MAT_STATE  	#endif -	// Accessors for selected TE material state -	// -	#define DEF_GET_MAT_STATE(DataType,ReturnType,MaterialMemberFunc,DefaultValue)												\ -		static void MaterialMemberFunc(DataType& data, bool& identical)																\ -		{																																					\ -			getTEMaterialValue< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(data, identical,DefaultValue);	\ -		} - -	// Mutators for selected TE material -	// -	#define DEF_EDIT_MAT_STATE(DataType,ReturnType,MaterialMemberFunc)																\ -		static void MaterialMemberFunc(LLPanelFace* p,DataType data)																	\ -		{																																					\ -			edit< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(p,data);													\ -		} - -	// Accessors for selected TE state proper (legacy settings etc) -	// -	#define DEF_GET_TE_STATE(DataType,ReturnType,TexEntryMemberFunc,DefaultValue)													\ -		static void TexEntryMemberFunc(DataType& data, bool& identical)																\ -		{																																					\ -			getTEValue< DataType, ReturnType, &LLTextureEntry::TexEntryMemberFunc >(data, identical,DefaultValue);		\ -		} +    // Accessors for selected TE material state +    // +    #define DEF_GET_MAT_STATE(DataType,ReturnType,MaterialMemberFunc,DefaultValue,HasTolerance,Tolerance)                                           \ +        static void MaterialMemberFunc(DataType& data, bool& identical, bool has_tolerance = HasTolerance, DataType tolerance = Tolerance)          \ +        {                                                                                                                                           \ +            getTEMaterialValue< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(data, identical, DefaultValue, has_tolerance, tolerance);   \ +        } + +    // Mutators for selected TE material +    // +    #define DEF_EDIT_MAT_STATE(DataType,ReturnType,MaterialMemberFunc)                                                  \ +        static void MaterialMemberFunc(LLPanelFace* p, DataType data, int te = -1)                                      \ +        {                                                                                                               \ +            edit< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(p, data, te);                                 \ +        } + +    // Accessors for selected TE state proper (legacy settings etc) +    // +    #define DEF_GET_TE_STATE(DataType,ReturnType,TexEntryMemberFunc,DefaultValue,HasTolerance,Tolerance)                                        \ +        static void TexEntryMemberFunc(DataType& data, bool& identical, bool has_tolerance = HasTolerance, DataType tolerance = Tolerance)      \ +        {                                                                                                                                       \ +            getTEValue< DataType, ReturnType, &LLTextureEntry::TexEntryMemberFunc >(data, identical, DefaultValue, has_tolerance, tolerance);   \ +        }  	class LLSelectedTEMaterial  	{ @@ -458,19 +459,19 @@ private:  		static void getMaxNormalRepeats(F32& repeats, bool& identical);  		static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha); -		DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getNormalID,LLUUID::null) -		DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getSpecularID,LLUUID::null) -		DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatX,1.0f) -		DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatY,1.0f) -		DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetX,0.0f) -		DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetY,0.0f) -		DEF_GET_MAT_STATE(F32,F32,getSpecularRotation,0.0f) +		DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getNormalID,LLUUID::null, false, LLUUID::null) +		DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getSpecularID,LLUUID::null, false, LLUUID::null) +		DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatX,1.0f, true, 0.001f) +		DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatY,1.0f, true, 0.001f) +		DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetX,0.0f, true, 0.001f) +		DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetY,0.0f, true, 0.001f) +		DEF_GET_MAT_STATE(F32,F32,getSpecularRotation,0.0f, true, 0.001f) -		DEF_GET_MAT_STATE(F32,F32,getNormalRepeatX,1.0f) -		DEF_GET_MAT_STATE(F32,F32,getNormalRepeatY,1.0f) -		DEF_GET_MAT_STATE(F32,F32,getNormalOffsetX,0.0f) -		DEF_GET_MAT_STATE(F32,F32,getNormalOffsetY,0.0f) -		DEF_GET_MAT_STATE(F32,F32,getNormalRotation,0.0f) +		DEF_GET_MAT_STATE(F32,F32,getNormalRepeatX,1.0f, true, 0.001f) +		DEF_GET_MAT_STATE(F32,F32,getNormalRepeatY,1.0f, true, 0.001f) +		DEF_GET_MAT_STATE(F32,F32,getNormalOffsetX,0.0f, true, 0.001f) +		DEF_GET_MAT_STATE(F32,F32,getNormalOffsetY,0.0f, true, 0.001f) +		DEF_GET_MAT_STATE(F32,F32,getNormalRotation,0.0f, true, 0.001f)  		DEF_EDIT_MAT_STATE(U8,U8,setDiffuseAlphaMode);  		DEF_EDIT_MAT_STATE(U8,U8,setAlphaMaskCutoff); @@ -506,17 +507,17 @@ private:  		static void getObjectScaleT(F32& scale_t, bool& identical);  		static void getMaxDiffuseRepeats(F32& repeats, bool& identical); -		DEF_GET_TE_STATE(U8,U8,getBumpmap,0) -		DEF_GET_TE_STATE(U8,U8,getShiny,0) -		DEF_GET_TE_STATE(U8,U8,getFullbright,0) -		DEF_GET_TE_STATE(F32,F32,getRotation,0.0f) -		DEF_GET_TE_STATE(F32,F32,getOffsetS,0.0f) -		DEF_GET_TE_STATE(F32,F32,getOffsetT,0.0f) -		DEF_GET_TE_STATE(F32,F32,getScaleS,1.0f) -		DEF_GET_TE_STATE(F32,F32,getScaleT,1.0f) -		DEF_GET_TE_STATE(F32,F32,getGlow,0.0f) -		DEF_GET_TE_STATE(LLTextureEntry::e_texgen,LLTextureEntry::e_texgen,getTexGen,LLTextureEntry::TEX_GEN_DEFAULT) -		DEF_GET_TE_STATE(LLColor4,const LLColor4&,getColor,LLColor4::white)		 +		DEF_GET_TE_STATE(U8,U8,getBumpmap,0, false, 0) +		DEF_GET_TE_STATE(U8,U8,getShiny,0, false, 0) +		DEF_GET_TE_STATE(U8,U8,getFullbright,0, false, 0) +		DEF_GET_TE_STATE(F32,F32,getRotation,0.0f, true, 0.001f) +		DEF_GET_TE_STATE(F32,F32,getOffsetS,0.0f, true, 0.001f) +		DEF_GET_TE_STATE(F32,F32,getOffsetT,0.0f, true, 0.001f) +		DEF_GET_TE_STATE(F32,F32,getScaleS,1.0f, true, 0.001f) +		DEF_GET_TE_STATE(F32,F32,getScaleT,1.0f, true, 0.001f) +		DEF_GET_TE_STATE(F32,F32,getGlow,0.0f, true, 0.001f) +		DEF_GET_TE_STATE(LLTextureEntry::e_texgen,LLTextureEntry::e_texgen,getTexGen,LLTextureEntry::TEX_GEN_DEFAULT, false, LLTextureEntry::TEX_GEN_DEFAULT) +		DEF_GET_TE_STATE(LLColor4,const LLColor4&,getColor,LLColor4::white, false, LLColor4::black);  	};  }; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index ddae109030..02d73936e3 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -2080,29 +2080,33 @@ void LLSelectMgr::selectionSetGlow(F32 glow)  	mSelectedObjects->applyToObjects( &func2 );  } -void LLSelectMgr::selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func) +void LLSelectMgr::selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func, int te)  {  	struct f1 : public LLSelectedTEFunctor  	{  		LLMaterialPtr mMaterial; -		f1(LLSelectedTEMaterialFunctor* material_func) : _material_func(material_func) {} +		f1(LLSelectedTEMaterialFunctor* material_func, int te) : _material_func(material_func), _specific_te(te) {} -		bool apply(LLViewerObject* object, S32 face) +		bool apply(LLViewerObject* object, S32 te)  		{ -			if (object && object->permModify() && _material_func) -			{ -				LLTextureEntry* tep = object->getTE(face); -				if (tep) -				{ -					LLMaterialPtr current_material = tep->getMaterialParams(); -					_material_func->apply(object, face, tep, current_material); -				} -			} +            if (_specific_te == -1 || (te == _specific_te)) +            { +			    if (object && object->permModify() && _material_func) +			    { +				    LLTextureEntry* tep = object->getTE(te); +				    if (tep) +				    { +					    LLMaterialPtr current_material = tep->getMaterialParams(); +					    _material_func->apply(object, te, tep, current_material); +				    } +			    } +            }  			return true;  		}  		LLSelectedTEMaterialFunctor* _material_func; -	} func1(material_func); +        int _specific_te; +	} func1(material_func, te);  	mSelectedObjects->applyToTEs( &func1 );  	struct f2 : public LLSelectedObjectFunctor @@ -6313,7 +6317,9 @@ void LLSelectNode::renderOneWireframe(const LLColor4& color)      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); -    if (LLSelectMgr::sRenderHiddenSelections) // && gFloaterTools && gFloaterTools->getVisible()) +    bool wireframe_selection = (gFloaterTools && gFloaterTools->getVisible()) || LLSelectMgr::sRenderHiddenSelections; + +    if (LLSelectMgr::sRenderHiddenSelections)      {          gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE);          LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL); @@ -6346,8 +6352,6 @@ void LLSelectNode::renderOneWireframe(const LLColor4& color)      gGL.diffuseColor4f(color.mV[VRED] * 2, color.mV[VGREEN] * 2, color.mV[VBLUE] * 2, LLSelectMgr::sHighlightAlpha * 2);      { -        bool wireframe_selection = gFloaterTools && gFloaterTools->getVisible(); -          LLGLDisable depth(wireframe_selection ? 0 : GL_BLEND);          LLGLEnable stencil(wireframe_selection ? 0 : GL_STENCIL_TEST); @@ -7932,3 +7936,40 @@ void LLSelectMgr::sendSelectionMove()  	//saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);  } + +template<> +bool LLCheckIdenticalFunctor<F32>::same(const F32& a, const F32& b, const F32& tolerance) +{ +    F32 delta = (a - b); +    F32 abs_delta = fabs(delta); +    return abs_delta <= tolerance; +} + +#define DEF_DUMMY_CHECK_FUNCTOR(T)                                                  \ +template<>                                                                          \ +bool LLCheckIdenticalFunctor<T>::same(const T& a, const T& b, const T& tolerance)   \ +{                                                                                   \ +    (void)tolerance;                                                                \ +    return a == b;                                                                  \ +} + +DEF_DUMMY_CHECK_FUNCTOR(LLUUID) +DEF_DUMMY_CHECK_FUNCTOR(LLGLenum) +DEF_DUMMY_CHECK_FUNCTOR(LLTextureEntry) +DEF_DUMMY_CHECK_FUNCTOR(LLTextureEntry::e_texgen) +DEF_DUMMY_CHECK_FUNCTOR(bool) +DEF_DUMMY_CHECK_FUNCTOR(U8) +DEF_DUMMY_CHECK_FUNCTOR(int) +DEF_DUMMY_CHECK_FUNCTOR(LLColor4) +DEF_DUMMY_CHECK_FUNCTOR(LLMediaEntry) +DEF_DUMMY_CHECK_FUNCTOR(LLPointer<LLMaterial>) +DEF_DUMMY_CHECK_FUNCTOR(std::string) +DEF_DUMMY_CHECK_FUNCTOR(std::vector<std::string>) + +template<> +bool LLCheckIdenticalFunctor<class LLFace *>::same(class LLFace* const & a, class LLFace* const & b, class LLFace* const & tolerance)   \ +{                                                                                   \ +    (void)tolerance;                                                                \ +    return a == b;                                                                  \ +} + diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index e965dd80d5..cbe9200c4e 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -124,6 +124,11 @@ template <typename T> struct LLSelectedTEGetFunctor  	virtual T get(LLViewerObject* object, S32 te) = 0;  }; +template <typename T> struct LLCheckIdenticalFunctor +{ +	static bool same(const T& a, const T& b, const T& tolerance); +}; +  typedef enum e_send_type  {  	SEND_ONLY_ROOTS, @@ -313,7 +318,7 @@ public:  	LLViewerObject* getPrimaryObject() { return mPrimaryObject; }  	// iterate through texture entries -	template <typename T> bool getSelectedTEValue(LLSelectedTEGetFunctor<T>* func, T& res); +	template <typename T> bool getSelectedTEValue(LLSelectedTEGetFunctor<T>* func, T& res, bool has_tolerance = false, T tolerance = T());  	template <typename T> bool isMultipleTEValue(LLSelectedTEGetFunctor<T>* func, const T& ignore_value);  	S32 getNumNodes(); @@ -591,7 +596,7 @@ public:  	void selectionSetClickAction(U8 action);  	void selectionSetIncludeInSearch(bool include_in_search);  	void selectionSetGlow(const F32 glow); -	void selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func); +	void selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func, int specific_te = -1);  	void selectionRemoveMaterial();  	void selectionSetObjectPermissions(U8 perm_field, BOOL set, U32 perm_mask, BOOL override = FALSE); @@ -856,7 +861,7 @@ void dialog_refresh_all();  //-----------------------------------------------------------------------------  // getSelectedTEValue  //----------------------------------------------------------------------------- -template <typename T> bool LLObjectSelection::getSelectedTEValue(LLSelectedTEGetFunctor<T>* func, T& res) +template <typename T> bool LLObjectSelection::getSelectedTEValue(LLSelectedTEGetFunctor<T>* func, T& res, bool has_tolerance, T tolerance)  {  	bool have_first = false;  	bool have_selected = false; @@ -892,7 +897,14 @@ template <typename T> bool LLObjectSelection::getSelectedTEValue(LLSelectedTEGet  			{  				if ( value != selected_value )  				{ -					identical = false; +                    if (!has_tolerance) +                    { +					    identical = false; +                    } +                    else if (!LLCheckIdenticalFunctor<T>::same(value, selected_value, tolerance)) +                    { +                        identical = false; +                    }  				}  				if (te == selected_te)  				{ diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 1f69939c46..f8849bf997 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -60,13 +60,16 @@  #include "bufferarray.h"  #include "bufferstream.h"  #include "llcorehttputil.h" -  #include "llhttpretrypolicy.h"  bool LLTextureFetchDebugger::sDebuggerEnabled = false ; -LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > LLTextureFetch::sCacheHitRate("texture_cache_hits"); -LLTrace::EventStatHandle<F64Milliseconds > LLTextureFetch::sCacheReadLatency("texture_cache_read_latency"); +LLTrace::CountStatHandle<F64> LLTextureFetch::sCacheHit("texture_cache_hit"); +LLTrace::CountStatHandle<F64> LLTextureFetch::sCacheAttempt("texture_cache_attempt"); + +LLTrace::SampleStatHandle<F32Seconds> LLTextureFetch::sCacheReadLatency("texture_cache_read_latency"); +LLTrace::SampleStatHandle<F32Seconds> LLTextureFetch::sTexDecodeLatency("texture_decode_latency"); +LLTrace::SampleStatHandle<F32Seconds> LLTextureFetch::sTexFetchLatency("texture_fetch_latency");  //////////////////////////////////////////////////////////////////////////////  // @@ -564,15 +567,21 @@ private:  	F32 mImagePriority;  	U32 mWorkPriority;  	F32 mRequestedPriority; -	S32                         mDesiredDiscard, -								mSimRequestedDiscard, -								mRequestedDiscard, -								mLoadedDiscard, -								mDecodedDiscard; -	LLFrameTimer                mRequestedTimer, -								mFetchTimer; -	LLTimer			mCacheReadTimer; -	F32				mCacheReadTime; +	S32 mDesiredDiscard; +	S32 mSimRequestedDiscard; +	S32 mRequestedDiscard; +    S32 mLoadedDiscard; +    S32 mDecodedDiscard; +	S32 mFullWidth; +	S32 mFullHeight; +	LLFrameTimer mRequestedDeltaTimer; +	LLFrameTimer mFetchDeltaTimer; +	LLTimer mCacheReadTimer; +    LLTimer mDecodeTimer; +    LLTimer mFetchTimer; +	F32 mCacheReadTime; // time for cache read only +    F32 mDecodeTime;    // time for decode only +    F32 mFetchTime;     // total time from req to finished fetch  	LLTextureCache::handle_t    mCacheReadHandle,  								mCacheWriteHandle;  	S32                         mRequestedSize, @@ -906,6 +915,8 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,  	  mLoadedDiscard(-1),  	  mDecodedDiscard(-1),  	  mCacheReadTime(0.f), +	  mDecodeTime(0.f), +      mFetchTime(0.f),  	  mCacheReadHandle(LLTextureCache::nullHandle()),  	  mCacheWriteHandle(LLTextureCache::nullHandle()),  	  mRequestedSize(0), @@ -1167,7 +1178,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  	if (mState != DONE)  	{ -		mFetchTimer.reset(); +		mFetchDeltaTimer.reset();  	}  	if (mState == INIT) @@ -1218,7 +1229,9 @@ bool LLTextureFetchWorker::doWork(S32 param)  			}  			mFileSize = 0;  			mLoaded = FALSE;			 -			 + +            add(LLTextureFetch::sCacheAttempt, 1.0); +  			if (mUrl.compare(0, 7, "file://") == 0)  			{  				setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it @@ -1229,7 +1242,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  				CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);  				mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority,  																		  offset, size, responder); -				mCacheReadTimer.reset(); +                mCacheReadTimer.reset();                  			}  			else if ((mUrl.empty() || mFTType==FTT_SERVER_BAKE) && mFetcher->canLoadFromCache())  			{ @@ -1260,6 +1273,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  			{  				mCacheReadHandle = LLTextureCache::nullHandle();  				setState(CACHE_POST); +                add(LLTextureFetch::sCacheHit, 1.0);  				// fall through  			}  			else @@ -1297,7 +1311,6 @@ bool LLTextureFetchWorker::doWork(S32 param)  			LL_DEBUGS(LOG_TXT) << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize()  							   << " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight())  							   << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; -			record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(1));  		}  		else  		{ @@ -1315,7 +1328,6 @@ bool LLTextureFetchWorker::doWork(S32 param)  			}  			// fall through -			record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(0));  		}  	} @@ -1571,7 +1583,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  			return true; // failed  		} -		mRequestedTimer.reset(); +		mRequestedDeltaTimer.reset();  		mLoaded = FALSE;  		mGetStatus = LLCore::HttpStatus();  		mGetReason.clear(); @@ -1898,6 +1910,8 @@ bool LLTextureFetchWorker::doWork(S32 param)  				mFetcher->getFetchDebugger()->addHistoryEntry(this);  			} +            mDecodeTime = mDecodeTimer.getElapsedTimeF32(); +  			if (mDecodedDiscard < 0)  			{  				if (mCachedSize > 0 && !mInLocalCache && mRetryAttempt == 0) @@ -2002,6 +2016,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  		else  		{  			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); +            mFetchTime = mFetchTimer.getElapsedTimeF32();  			return true;  		}  	} @@ -2945,11 +2960,12 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,  			discard_level = worker->mDecodedDiscard;  			raw = worker->mRawImage;  			aux = worker->mAuxImage; -			F32Seconds cache_read_time(worker->mCacheReadTime); -			if (cache_read_time != (F32Seconds)0.f) -			{ -				record(sCacheReadLatency, cache_read_time); -			} +			sample(sTexDecodeLatency, worker->mDecodeTime); +            sample(sTexFetchLatency, worker->mFetchTime); +            sample(sCacheReadLatency, worker->mCacheReadTime); +            worker->mCacheReadTimer.reset(); +            worker->mDecodeTimer.reset(); +            worker->mFetchTimer.reset();  			res = true;  			LL_DEBUGS(LOG_TXT) << id << ": Request Finished. State: " << worker->mState << " Discard: " << discard_level << LL_ENDL;  			worker->unlockWorkMutex();									// -Mw @@ -3253,7 +3269,7 @@ void LLTextureFetch::sendRequestListToSimulators()  // 			req->setPriority(LLWorkerThread::PRIORITY_HIGH | req->mWorkPriority);  				continue;  			} -			F32 elapsed = req->mRequestedTimer.getElapsedTimeF32(); +			F32 elapsed = req->mRequestedDeltaTimer.getElapsedTimeF32();  			{  				F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority);  				if ((req->mSimRequestedDiscard != req->mDesiredDiscard) || @@ -3322,7 +3338,7 @@ void LLTextureFetch::sendRequestListToSimulators()  				req->mSentRequest = LLTextureFetchWorker::SENT_SIM;  				req->mSimRequestedDiscard = req->mDesiredDiscard;  				req->mRequestedPriority = req->mImagePriority; -				req->mRequestedTimer.reset(); +				req->mRequestedDeltaTimer.reset();  				req->unlockWorkMutex();									// -Mw  				sim_request_count++;  				if (sim_request_count >= IMAGES_PER_REQUEST) @@ -3397,7 +3413,7 @@ void LLTextureFetch::sendRequestListToSimulators()  // Locks:  Mw  bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)  { -	mRequestedTimer.reset(); +	mRequestedDeltaTimer.reset();  	if (index >= mTotalPackets)  	{  // 		LL_WARNS(LOG_TXT) << "Received Image Packet " << index << " > max: " << mTotalPackets << " for image: " << mID << LL_ENDL; @@ -3606,8 +3622,8 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r  	{  		worker->lockWorkMutex();										// +Mw  		state = worker->mState; -		fetch_dtime = worker->mFetchTimer.getElapsedTimeF32(); -		request_dtime = worker->mRequestedTimer.getElapsedTimeF32(); +		fetch_dtime = worker->mFetchDeltaTimer.getElapsedTimeF32(); +		request_dtime = worker->mRequestedDeltaTimer.getElapsedTimeF32();  		if (worker->mFileSize > 0)  		{  			if (state == LLTextureFetchWorker::LOAD_FROM_SIMULATOR) diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index cfa312ccd9..a2155bde1f 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -308,13 +308,16 @@ public:  	S32 mPacketCount;  	S32 mBadPacketCount; +    static LLTrace::CountStatHandle<F64>        sCacheHit; +    static LLTrace::CountStatHandle<F64>        sCacheAttempt; +    static LLTrace::SampleStatHandle<F32Seconds> sCacheReadLatency; +    static LLTrace::SampleStatHandle<F32Seconds> sTexDecodeLatency; +    static LLTrace::SampleStatHandle<F32Seconds> sTexFetchLatency; +  private:  	LLMutex mQueueMutex;        //to protect mRequestMap and mCommands only  	LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue. -	static LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > sCacheHitRate; -	static LLTrace::EventStatHandle<F64Milliseconds > sCacheReadLatency; -  	LLTextureCache* mTextureCache;  	LLImageDecodeThread* mImageDecodeThread; diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index d7b95db94f..0d2edc0268 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -240,9 +240,9 @@ void LLTextureBar::draw()  		{ "REQ", LLColor4::yellow },// SEND_HTTP_REQ  		{ "HTP", LLColor4::green },	// WAIT_HTTP_REQ  		{ "DEC", LLColor4::yellow },// DECODE_IMAGE -		{ "DEC", LLColor4::green }, // DECODE_IMAGE_UPDATE +		{ "DEU", LLColor4::green }, // DECODE_IMAGE_UPDATE  		{ "WRT", LLColor4::purple },// WRITE_TO_CACHE -		{ "WRT", LLColor4::orange },// WAIT_ON_WRITE +		{ "WWT", LLColor4::orange },// WAIT_ON_WRITE  		{ "END", LLColor4::red },   // DONE  #define LAST_STATE 14  		{ "CRE", LLColor4::magenta }, // LAST_STATE+1 @@ -530,6 +530,25 @@ void LLGLTexMemBar::draw()  	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,  											 text_color, LLFontGL::LEFT, LLFontGL::TOP); +    LLTrace::Recording& recording = LLViewerStats::instance().getRecording(); + +    F64 cacheHits     = recording.getSampleCount(LLTextureFetch::sCacheHit); +    F64 cacheAttempts = recording.getSampleCount(LLTextureFetch::sCacheAttempt); + +	F32 cacheHitRate = (cacheAttempts > 0.0) ? F32((cacheHits / cacheAttempts) * 100.0f) : 0.0f; + +    U32 cacheReadLatMin = U32(recording.getMin(LLTextureFetch::sCacheReadLatency).value() * 1000.0f); +    U32 cacheReadLatMed = U32(recording.getMean(LLTextureFetch::sCacheReadLatency).value() * 1000.0f); +    U32 cacheReadLatMax = U32(recording.getMax(LLTextureFetch::sCacheReadLatency).value() * 1000.0f); + +    U32 texDecodeLatMin = U32(recording.getMin(LLTextureFetch::sTexDecodeLatency).value() * 1000.0f); +    U32 texDecodeLatMed = U32(recording.getMean(LLTextureFetch::sTexDecodeLatency).value() * 1000.0f); +    U32 texDecodeLatMax = U32(recording.getMax(LLTextureFetch::sTexDecodeLatency).value() * 1000.0f); + +    U32 texFetchLatMin = U32(recording.getMin(LLTextureFetch::sTexFetchLatency).value() * 1000.0f); +    U32 texFetchLatMed = U32(recording.getMean(LLTextureFetch::sTexFetchLatency).value() * 1000.0f); +    U32 texFetchLatMax = U32(recording.getMax(LLTextureFetch::sTexFetchLatency).value() * 1000.0f); +  	text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB",  					total_mem.value(),  					max_total_mem.value(), @@ -542,7 +561,7 @@ void LLGLTexMemBar::draw()  					cache_max_usage);  	//, cache_entries, cache_max_entries -	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*5, +	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,  											 text_color, LLFontGL::LEFT, LLFontGL::TOP);  	U32 cache_read(0U), cache_write(0U), res_wait(0U); @@ -558,6 +577,21 @@ void LLGLTexMemBar::draw()  					cache_write,  					res_wait); +	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*5, +											 text_color, LLFontGL::LEFT, LLFontGL::TOP); + +    text = llformat("CacheHitRate: %3.2f Read: %d/%d/%d Decode: %d/%d/%d Fetch: %d/%d/%d", +                    cacheHitRate, +                    cacheReadLatMin, +                    cacheReadLatMed, +                    cacheReadLatMax, +                    texDecodeLatMin, +                    texDecodeLatMed, +                    texDecodeLatMax, +                    texFetchLatMin, +                    texFetchLatMed, +                    texFetchLatMax); +  	LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*4,  											 text_color, LLFontGL::LEFT, LLFontGL::TOP); @@ -640,7 +674,7 @@ BOOL LLGLTexMemBar::handleMouseDown(S32 x, S32 y, MASK mask)  LLRect LLGLTexMemBar::getRequiredRect()  {  	LLRect rect; -	rect.mTop = 68; //LLFontGL::getFontMonospace()->getLineHeight() * 6; +	rect.mTop = 78; //LLFontGL::getFontMonospace()->getLineHeight() * 6;  	return rect;  } diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index 9f6d606a22..fe8069cf03 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -484,12 +484,19 @@ void LLGridManager::getLoginURIs(const std::string& grid, std::vector<std::strin  	std::string grid_name = getGrid(grid);  	if (!grid_name.empty())  	{ -		for (LLSD::array_iterator llsd_uri = mGridList[grid_name][GRID_LOGIN_URI_VALUE].beginArray(); -			 llsd_uri != mGridList[grid_name][GRID_LOGIN_URI_VALUE].endArray(); -			 llsd_uri++) -		{ -			uris.push_back(llsd_uri->asString()); -		} +        if (mGridList[grid_name][GRID_LOGIN_URI_VALUE].isArray()) +        { +		    for (LLSD::array_iterator llsd_uri = mGridList[grid_name][GRID_LOGIN_URI_VALUE].beginArray(); +			     llsd_uri != mGridList[grid_name][GRID_LOGIN_URI_VALUE].endArray(); +			     llsd_uri++) +		    { +			    uris.push_back(llsd_uri->asString()); +		    } +        } +        else +        { +            uris.push_back(mGridList[grid_name][GRID_LOGIN_URI_VALUE].asString()); +        }  	}  	else  	{ diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index ff7647a7e4..2468aeffa2 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -212,7 +212,11 @@ LLGLSLShader			gDeferredShadowProgram;  LLGLSLShader			gDeferredShadowCubeProgram;  LLGLSLShader			gDeferredShadowAlphaMaskProgram;  LLGLSLShader			gDeferredAvatarShadowProgram; +LLGLSLShader			gDeferredAvatarAlphaShadowProgram; +LLGLSLShader			gDeferredAvatarAlphaMaskShadowProgram;  LLGLSLShader			gDeferredAttachmentShadowProgram; +LLGLSLShader			gDeferredAttachmentAlphaShadowProgram; +LLGLSLShader			gDeferredAttachmentAlphaMaskShadowProgram;  LLGLSLShader			gDeferredAlphaProgram;  LLGLSLShader			gDeferredAlphaImpostorProgram;  LLGLSLShader			gDeferredAlphaWaterProgram; @@ -1836,6 +1840,30 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		success = gDeferredAvatarShadowProgram.createShader(NULL, NULL);  	} +    if (success) +	{ +		gDeferredAvatarAlphaShadowProgram.mName = "Deferred Avatar Alpha Shadow Shader"; +		gDeferredAvatarAlphaShadowProgram.mFeatures.hasSkinning = true; +		gDeferredAvatarAlphaShadowProgram.mShaderFiles.clear(); +		gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredAvatarAlphaShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); +		gDeferredAvatarAlphaShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		success = gDeferredAvatarAlphaShadowProgram.createShader(NULL, NULL); +	} + +    if (success) +	{ +		gDeferredAvatarAlphaMaskShadowProgram.mName = "Deferred Avatar Alpha Mask Shadow Shader"; +		gDeferredAvatarAlphaMaskShadowProgram.mFeatures.hasSkinning  = true; +		gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.clear(); +		gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredAvatarAlphaMaskShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); +		gDeferredAvatarAlphaMaskShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		success = gDeferredAvatarAlphaMaskShadowProgram.createShader(NULL, NULL); +	} +  	if (success)  	{  		gDeferredAttachmentShadowProgram.mName = "Deferred Attachment Shadow Shader"; @@ -1847,6 +1875,30 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAttachmentShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredAttachmentShadowProgram.createShader(NULL, NULL);  	} +     +    if (success) +	{ +		gDeferredAttachmentAlphaShadowProgram.mName = "Deferred Attachment Alpha Shadow Shader"; +		gDeferredAttachmentAlphaShadowProgram.mFeatures.hasObjectSkinning = true; +		gDeferredAttachmentAlphaShadowProgram.mShaderFiles.clear(); +		gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredAttachmentAlphaShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); +		gDeferredAttachmentAlphaShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		success = gDeferredAttachmentAlphaShadowProgram.createShader(NULL, NULL); +	} + +    if (success) +	{ +		gDeferredAttachmentAlphaMaskShadowProgram.mName = "Deferred Attachment Alpha Mask Shadow Shader"; +		gDeferredAttachmentAlphaMaskShadowProgram.mFeatures.hasObjectSkinning = true; +		gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.clear(); +		gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER_ARB)); +		gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredAttachmentAlphaMaskShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); +		gDeferredAttachmentAlphaMaskShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +		success = gDeferredAttachmentAlphaMaskShadowProgram.createShader(NULL, NULL); +	}  	if (success)  	{ @@ -2065,6 +2117,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleNonIndexedProgram.mFeatures.hasAtmospherics = true;  		gObjectSimpleNonIndexedProgram.mFeatures.hasLighting = true;  		gObjectSimpleNonIndexedProgram.mFeatures.disableTextureIndex = true; +		gObjectSimpleNonIndexedProgram.mFeatures.hasAlphaMask = true;  		gObjectSimpleNonIndexedProgram.mShaderFiles.clear();  		gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 923aa522ad..9ba7d7f742 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -319,6 +319,10 @@ extern LLGLSLShader			gDeferredPostNoDoFProgram;  extern LLGLSLShader			gDeferredPostGammaCorrectProgram;  extern LLGLSLShader			gDeferredAvatarShadowProgram;  extern LLGLSLShader			gDeferredAttachmentShadowProgram; +extern LLGLSLShader			gDeferredAttachmentAlphaShadowProgram; +extern LLGLSLShader			gDeferredAttachmentAlphaMaskShadowProgram; +extern LLGLSLShader			gDeferredAvatarAlphaShadowProgram; +extern LLGLSLShader			gDeferredAvatarAlphaMaskShadowProgram;  extern LLGLSLShader			gDeferredAlphaProgram;  extern LLGLSLShader			gDeferredAlphaImpostorProgram;  extern LLGLSLShader			gDeferredFullbrightProgram; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 39ffbfc989..712d0883d3 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1189,9 +1189,17 @@ void LLViewerFetchedTexture::loadFromFastCache()  	}  	mInFastCacheList = FALSE; +    add(LLTextureFetch::sCacheAttempt, 1.0); + +    LLTimer fastCacheTimer;  	mRawImage = LLAppViewer::getTextureCache()->readFromFastCache(getID(), mRawDiscardLevel);  	if(mRawImage.notNull())  	{ +        F32 cachReadTime = fastCacheTimer.getElapsedTimeF32(); + +        add(LLTextureFetch::sCacheHit, 1.0); +        sample(LLTextureFetch::sCacheReadLatency, cachReadTime); +  		mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;  		mFullHeight = mRawImage->getHeight() << mRawDiscardLevel;  		setTexelsPerImage(); diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp index cb83cf8fdf..6e08a2ff12 100644 --- a/indra/newview/llvoicevisualizer.cpp +++ b/indra/newview/llvoicevisualizer.cpp @@ -356,6 +356,7 @@ void LLVoiceVisualizer::render()  		//---------------------------------------------------------------  		LLGLSPipelineAlpha alpha_blend;  		LLGLDepthTest depth(GL_TRUE, GL_FALSE); +		LLGLDisable gls_stencil(GL_STENCIL_TEST);  		//-------------------------------------------------------------  		// create coordinates of the geometry for the dot diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index e541c1054e..5699d47ad8 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2514,8 +2514,8 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl  			LLSpatialPartition* part = region->getSpatialPartition(i);  			if (part)  			{ -				if (hasRenderType(part->mDrawableType)) -				{ +				if (LLViewerRegion::PARTITION_BRIDGE == i || hasRenderType(part->mDrawableType)) +				{ //pass PARTITION BRIDGE because LLDrawable can be moved to this partition  					part->cull(camera);  				}  			} diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml index 8c769d87de..67b99ca588 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -603,11 +603,10 @@               layout="topleft"  			 label_width="205"               left="10" -             max_val="9999" -             min_val="-9999" +             max_val="360" +             min_val="-360"               name="TexRot"               width="265" /> -              <spinner               follows="left|top"               height="19" @@ -617,6 +616,7 @@               layout="topleft"               left="10"               min_val="-1" +             max_val="1"               name="TexOffsetU"               width="265" />              <spinner @@ -628,6 +628,7 @@               layout="topleft"               left="10"               min_val="-1" +             max_val="1"               name="TexOffsetV"               width="265" />              <spinner @@ -667,10 +668,9 @@  			 label_width="205"               left="10"               max_val="360" -             min_val="0" +             min_val="-360"               name="bumpyRot"               width="265" /> -              <spinner               follows="left|top"               height="19" @@ -679,7 +679,8 @@               label_width="205"               layout="topleft"               left="10" -             min_val="0" +             min_val="-1" +             max_val="1"               name="bumpyOffsetU"               width="265" />              <spinner @@ -690,7 +691,8 @@               label_width="205"               layout="topleft"               left="10" -             min_val="0" +             min_val="-1" +             max_val="1"               name="bumpyOffsetV"               width="265" />              <spinner @@ -730,10 +732,9 @@  			 label_width="205"               left="10"               max_val="360" -             min_val="0" +             min_val="-360"               name="shinyRot"               width="265" /> -              <spinner               follows="left|top"               height="19" @@ -742,7 +743,8 @@               label_width="205"               layout="topleft"               left="10" -             min_val="0" +             min_val="-1" +             max_val="1"               name="shinyOffsetU"               width="265" />              <spinner @@ -753,7 +755,8 @@               label_width="205"               layout="topleft"               left="10" -             min_val="0" +             min_val="-1" +             max_val="1"               name="shinyOffsetV"               width="265" />              <check_box  | 
