diff options
58 files changed, 2416 insertions, 4286 deletions
| diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h index 5291a05607..2cf50e9cd2 100644 --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -78,8 +78,15 @@ public:  		mMatrix[1] = _mm_loadu_ps(src.mMatrix[1]);  		mMatrix[2] = _mm_loadu_ps(src.mMatrix[2]);  		mMatrix[3] = _mm_loadu_ps(src.mMatrix[3]); -		  	} +     +    inline void loadu(const F32* src) +    { +        mMatrix[0] = _mm_loadu_ps(src); +        mMatrix[1] = _mm_loadu_ps(src+4); +        mMatrix[2] = _mm_loadu_ps(src+8); +        mMatrix[3] = _mm_loadu_ps(src+12); +    }  	inline void loadu(const LLMatrix3& src)  	{ diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index a23b991f1d..dd37b8ce0b 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -31,6 +31,7 @@  #include "llconvexdecomposition.h"  #include "llsdserialize.h"  #include "llvector4a.h" +#include "llmd5.h"  #ifdef LL_USESYSTEMLIBS  # include <zlib.h> @@ -1451,6 +1452,8 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin)  	{  		mLockScaleIfJointPosition = false;  	} + +    updateHash();  }  LLSD LLMeshSkinInfo::asLLSD(bool include_joints, bool lock_scale_if_joint_position) const @@ -1502,6 +1505,38 @@ LLSD LLMeshSkinInfo::asLLSD(bool include_joints, bool lock_scale_if_joint_positi  	return ret;  } +void LLMeshSkinInfo::updateHash() +{ +    //  get hash of data relevant to render batches +    LLMD5 hash; + +    //mJointNames +    for (auto& name : mJointNames) +    { +        hash.update(name); +    } +     +    //mJointNums  +    hash.update((U8*)&(mJointNums[0]), sizeof(S32) * mJointNums.size()); +     +    //mInvBindMatrix +    F32* src = mInvBindMatrix[0].getF32ptr(); +     +    for (int i = 0; i < mInvBindMatrix.size() * 16; ++i) +    { +        S32 t = llround(src[i] * 10000.f); +        hash.update((U8*)&t, sizeof(S32)); +    } +    //hash.update((U8*)&(mInvBindMatrix[0]), sizeof(LLMatrix4a) * mInvBindMatrix.size()); + +    hash.finalize(); + +    U64 digest[2]; +    hash.raw_digest((U8*) digest); + +    mHash = digest[0]; +} +  LLModel::Decomposition::Decomposition(LLSD& data)  {  	fromLLSD(data); diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index cd2b6c6728..2d27592bc8 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -49,6 +49,7 @@ public:  	LLMeshSkinInfo(LLSD& data);  	void fromLLSD(LLSD& data);  	LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const; +    void updateHash();  	LLUUID mMeshID;  	std::vector<std::string> mJointNames; @@ -58,10 +59,12 @@ public:  	matrix_list_t mAlternateBindMatrix;  	LL_ALIGN_16(LLMatrix4a mBindShapeMatrix); +  	float mPelvisOffset;      bool mLockScaleIfJointPosition;      bool mInvalidJointsScrubbed;      bool mJointNumsInitialized; +    U64 mHash = 0;  } LL_ALIGN_POSTFIX(16);  LL_ALIGN_PREFIX(16) diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 08c9dd8769..2f1ce0eec9 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -970,6 +970,19 @@ void LLGLSLShader::bind()      }  } +void LLGLSLShader::bind(bool rigged) +{ +    if (rigged) +    { +        llassert(mRiggedVariant); +        mRiggedVariant->bind(); +    } +    else +    { +        bind(); +    } +} +  void LLGLSLShader::unbind()  {      LL_PROFILE_ZONE_SCOPED; diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 3b23cf1b28..6fdb789087 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -230,6 +230,8 @@ public:      BOOL link(BOOL suppress_errors = FALSE);  	void bind(); +    //helper to conditionally bind mRiggedVariant instead of this +    void bind(bool rigged);  	void unbind();  	// Unbinds any previously bound shader by explicitly binding no shader. @@ -267,7 +269,8 @@ public:  	LLShaderFeatures mFeatures;  	std::vector< std::pair< std::string, GLenum > > mShaderFiles;  	std::string mName; -	boost::unordered_map<std::string, std::string> mDefines; +    typedef std::unordered_map<std::string, std::string> defines_map_t; +	defines_map_t mDefines;  	//statistcis for profiling shader performance  	U32 mTimerQuery; @@ -285,6 +288,9 @@ public:  	std::vector<U32> mTextureMagFilter;  	std::vector<U32> mTextureMinFilter; +    // this pointer should be set to whichever shader represents this shader's rigged variant +    LLGLSLShader* mRiggedVariant = nullptr; +  private:  	void unloadInternal();  }; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index aad04beea2..0c180ed50d 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -1283,7 +1283,7 @@ void LLRender::syncLightState()  void LLRender::syncMatrices()  { -	static const U32 name[] =  +    static const U32 name[] =   	{  		LLShaderMgr::MODELVIEW_MATRIX,  		LLShaderMgr::PROJECTION_MATRIX, diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index e8c6295930..a9a4314afa 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -165,6 +165,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)  	if (features->hasObjectSkinning)  	{ +        shader->mRiggedVariant = shader;          if (!shader->attachVertexObject("avatar/objectSkinV.glsl"))  		{  			return FALSE; @@ -599,7 +600,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns, const std::string&  	}   } -GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines, S32 texture_index_channels) +GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::unordered_map<std::string, std::string>* defines, S32 texture_index_channels)  {  // endsure work-around for missing GLSL funcs gets propogated to feature shader files (e.g. srgbF.glsl) @@ -774,7 +775,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  	if (defines)  	{ -		for (boost::unordered_map<std::string,std::string>::iterator iter = defines->begin(); iter != defines->end(); ++iter) +		for (std::unordered_map<std::string,std::string>::iterator iter = defines->begin(); iter != defines->end(); ++iter)  		{  			std::string define = "#define " + iter->first + " " + iter->second + "\n";  			extra_code_text[extra_code_count++] = (GLcharARB *) strdup(define.c_str()); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 3908efd4ec..67c0d6ab10 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -264,7 +264,7 @@ public:      void dumpShaderSource(U32 shader_code_count, GLcharARB** shader_code_text);  	BOOL	linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);  	BOOL	validateProgramObject(GLhandleARB obj); -	GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1); +	GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::unordered_map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1);  	// Implemented in the application to actually point to the shader directory.  	virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index e52624d66a..485d332068 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -1833,7 +1833,7 @@ void* LLWindowWin32::createSharedContext()      S32 attribs[] =      {          WGL_CONTEXT_MAJOR_VERSION_ARB, 4, -        WGL_CONTEXT_MINOR_VERSION_ARB, 2, +        WGL_CONTEXT_MINOR_VERSION_ARB, 6,          WGL_CONTEXT_PROFILE_MASK_ARB,  LLRender::sGLCoreProfile ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,          WGL_CONTEXT_FLAGS_ARB, gDebugGL ? WGL_CONTEXT_DEBUG_BIT_ARB : 0,          0 diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index 5da13f5010..088502c017 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -247,6 +247,7 @@ public:  	// generic getter  	template<typename T> T get(const std::string& name)  	{ +        LL_PROFILE_ZONE_SCOPED;  		LLControlVariable* control = getControl(name);  		LLSD value;  		eControlType type = TYPE_COUNT; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 144323bb11..2d821b7451 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -8649,28 +8649,6 @@      </array>    </map> -    <key>RenderAlphaBatchFullbrights</key> -    <map> -      <key>Comment</key> -      <string>Render fullbright alpha content more efficiently, but with possible visual differences from prev viewers.</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>0</integer> -    </map> -    <key>RenderAlphaBatchEmissives</key> -    <map> -      <key>Comment</key> -      <string>Render emissive alpha content more efficiently, but with possible visual differences from prev viewers.</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>1</integer> -    </map>      <key>RenderAnisotropic</key>      <map>        <key>Comment</key> @@ -10145,7 +10123,7 @@        <key>Type</key>        <string>S32</string>        <key>Value</key> -      <integer>512</integer> +      <integer>4096</integer>      </map>      <key>RenderNameFadeDuration</key>      <map> diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index 506118d381..6a93bc2fd2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -105,9 +105,9 @@ void main()  	vec4 vert = vec4(position.xyz, 1.0);  	pos = (modelview_matrix * vert);  	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); -#endif +#endif //IS_AVATAR_SKIN -#endif +#endif // HAS_SKIN  #ifdef USE_INDEXED_TEX  	passTextureIndex(); diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl deleted file mode 100644 index 10144f3e16..0000000000 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl +++ /dev/null @@ -1,64 +0,0 @@ -/**  - * @file bumpV.glsl - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2007, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -uniform mat4 projection_matrix; -uniform mat4 texture_matrix0; -uniform mat4 modelview_matrix; - -ATTRIBUTE vec3 position; -ATTRIBUTE vec4 diffuse_color; -ATTRIBUTE vec3 normal; -ATTRIBUTE vec2 texcoord0; -ATTRIBUTE vec4 tangent; - -VARYING vec3 vary_mat0; -VARYING vec3 vary_mat1; -VARYING vec3 vary_mat2; -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; - -mat4 getObjectSkinnedTransform(); - -void main() -{ -	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -	 -	mat4 mat = getObjectSkinnedTransform(); -	 -	mat = modelview_matrix * mat; -	 -	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; -	 -	 -	vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz); -	vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz); -	vec3 b = cross(n, t) * tangent.w; -	 -	vary_mat0 = vec3(t.x, b.x, n.x); -	vary_mat1 = vec3(t.y, b.y, n.y); -	vary_mat2 = vec3(t.z, b.z, n.z); -	 -	gl_Position = projection_matrix*vec4(pos, 1.0); -	vertex_color = diffuse_color; -} diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl index 9f9749394e..d90891aa20 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl @@ -39,16 +39,32 @@ VARYING vec3 vary_mat2;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +uniform mat4 modelview_matrix; +#endif +  void main()  {  	//transform vertex +#ifdef HAS_SKIN +    mat4 mat = getObjectSkinnedTransform(); +	mat = modelview_matrix * mat; +	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; +	gl_Position = projection_matrix*vec4(pos, 1.0); + +	vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz); +	vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz); +#else  	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);  -	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -	  	vec3 n = normalize(normal_matrix * normal);  	vec3 t = normalize(normal_matrix * tangent.xyz); +#endif +  	vec3 b = cross(n, t) * tangent.w; -	 +	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; +  	vary_mat0 = vec3(t.x, b.x, n.x);  	vary_mat1 = vec3(t.y, b.y, n.y);  	vary_mat2 = vec3(t.z, b.z, n.z); diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl index 3c026796c8..d64bcefade 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl @@ -39,14 +39,28 @@ VARYING vec2 vary_texcoord0;  void passTextureIndex(); +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +uniform mat4 modelview_matrix; +#endif +  void main()  { -	//transform vertex +#ifdef HAS_SKIN +    mat4 mat = getObjectSkinnedTransform(); +    mat = modelview_matrix * mat; +    vec4 pos = mat * vec4(position.xyz, 1.0); +    gl_Position = projection_matrix * pos; +    vary_normal = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); +#else  	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);  +    vary_normal = normalize(normal_matrix * normal); +#endif +	  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;  	passTextureIndex(); -	vary_normal = normalize(normal_matrix * normal); -	 +  	vertex_color = diffuse_color;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl index 8f6eb79668..2c139430e7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl @@ -25,7 +25,6 @@  uniform mat3 normal_matrix;  uniform mat4 texture_matrix0; -uniform mat4 texture_matrix1;  uniform mat4 modelview_matrix;  uniform mat4 modelview_projection_matrix; @@ -47,19 +46,32 @@ VARYING vec2 vary_texcoord0;  VARYING vec3 vary_texcoord1;  VARYING vec4 vary_position; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +#endif +  void main()  {  	//transform vertex  	vec4 vert = vec4(position.xyz,1.0);  	passTextureIndex(); + +#ifdef HAS_SKIN +    mat4 mat = getObjectSkinnedTransform(); +    mat = modelview_matrix * mat; +    vec4 pos = mat * vert; +    vary_position = gl_Position = projection_matrix * pos; +	vec3 norm = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); +#else  	vec4 pos = (modelview_matrix * vert);  	vary_position = gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); -	  	vec3 norm = normalize(normal_matrix * normal); +#endif  	vec3 ref = reflect(pos.xyz, -norm);  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -	vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz; +	vary_texcoord1 = transpose(normal_matrix) * ref.xyz;  	calcAtmospherics(pos.xyz); diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl index bdf3546aa5..e71636f2c9 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl @@ -45,15 +45,26 @@ VARYING vec3 vary_position;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +#endif  void main()  {  	//transform vertex  	vec4 vert = vec4(position.xyz, 1.0); -	vec4 pos = (modelview_matrix * vert);  	passTextureIndex(); +#ifdef HAS_SKIN +    mat4 mat = getObjectSkinnedTransform(); +    mat = modelview_matrix * mat; +    vec4 pos = mat * vert; +    gl_Position = projection_matrix * pos; +#else +	vec4 pos = (modelview_matrix * vert);  	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); +#endif  #ifdef WATER_FOG  	vary_position = pos.xyz; diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskSkinnedV.glsl index 2487110624..2b17aea75a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskSkinnedV.glsl @@ -1,8 +1,9 @@  /**  - * @file diffuseSkinnedV.glsl - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * @file shadowAlphaMaskSkinnedV.glsl + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$   * Second Life Viewer Source Code - * Copyright (C) 2007, Linden Research, Inc. + * Copyright (C) 2011, Linden Research, Inc.   *    * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public @@ -22,38 +23,48 @@   * $/LicenseInfo$   */ -uniform mat4 projection_matrix;  uniform mat4 texture_matrix0;  uniform mat4 modelview_matrix; +uniform mat4 projection_matrix; +uniform float shadow_target_width;  ATTRIBUTE vec3 position;  ATTRIBUTE vec4 diffuse_color; -ATTRIBUTE vec3 normal;  ATTRIBUTE vec2 texcoord0; -VARYING vec3 vary_normal; +VARYING vec4 post_pos; +VARYING float target_pos_x;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; +void passTextureIndex(); +  mat4 getObjectSkinnedTransform();  void main()  { -	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -		 +	//transform vertex +	vec4 pre_pos = vec4(position.xyz, 1.0); +  	mat4 mat = getObjectSkinnedTransform();  	mat = modelview_matrix * mat; -	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; -	vec4 norm = vec4(position.xyz, 1.0); -	norm.xyz += normal.xyz; -	norm.xyz = (mat*norm).xyz; -	norm.xyz = normalize(norm.xyz-pos.xyz); +	vec4 pos = mat * pre_pos; +	pos = projection_matrix * pos; -	vary_normal = norm.xyz; -			 -	vertex_color = diffuse_color; +	target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x; + +	post_pos = pos; + +#if !defined(DEPTH_CLAMP) +	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +#else +	gl_Position = pos; +#endif -	gl_Position = projection_matrix*vec4(pos, 1.0); +	passTextureIndex(); + +	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; +	vertex_color = diffuse_color;  } diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowSkinnedV.glsl index df31b5a79f..bdf8e0854d 100644 --- a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowSkinnedV.glsl @@ -1,6 +1,7 @@  /**  - * @file simpleSkinnedV.glsl - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * @file shadowSkinnedV.glsl + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2007, Linden Research, Inc.   *  @@ -22,44 +23,30 @@   * $/LicenseInfo$   */ -uniform mat4 texture_matrix0;  uniform mat4 modelview_matrix;  uniform mat4 projection_matrix;  ATTRIBUTE vec3 position; -ATTRIBUTE vec3 normal; -ATTRIBUTE vec4 diffuse_color; -ATTRIBUTE vec2 texcoord0; -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; +VARYING vec4 post_pos; - -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color); -void calcAtmospherics(vec3 inPositionEye);  mat4 getObjectSkinnedTransform();  void main()  {  	//transform vertex -	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -	  	mat4 mat = getObjectSkinnedTransform();  	mat = modelview_matrix * mat; -	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; -	 -	vec4 norm = vec4(position.xyz, 1.0); -	norm.xyz += normal.xyz; -	norm.xyz = (mat*norm).xyz; -	norm.xyz = normalize(norm.xyz-pos.xyz); -		 -	calcAtmospherics(pos.xyz); +	vec4 pos = (mat*vec4(position.xyz, 1.0)); +	pos = projection_matrix*pos; + +	post_pos = pos; + +#if !defined(DEPTH_CLAMP) +	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +#else +	gl_Position = pos; +#endif -	vec4 color = calcLighting(pos.xyz, norm.xyz, diffuse_color); -	vertex_color = color; -	 -	gl_Position = projection_matrix*vec4(pos, 1.0); -	 -	  } diff --git a/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeShadowSkinnedV.glsl index 9064904191..d9ca6d3a46 100644 --- a/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeShadowSkinnedV.glsl @@ -1,7 +1,7 @@  /**  - * @file emissiveSkinnedV.glsl + * @file treeShadowV.glsl   * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ +  * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2007, Linden Research, Inc.   *  @@ -23,34 +23,31 @@   * $/LicenseInfo$   */ -uniform mat4 projection_matrix;  uniform mat4 texture_matrix0;  uniform mat4 modelview_matrix; - +uniform mat4 projection_matrix; +   ATTRIBUTE vec3 position; -ATTRIBUTE vec4 emissive;  ATTRIBUTE vec2 texcoord0; -VARYING vec4 vertex_color; +VARYING vec4 post_pos;  VARYING vec2 vary_texcoord0; - -void calcAtmospherics(vec3 inPositionEye);  mat4 getObjectSkinnedTransform();  void main()  {  	//transform vertex -	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -	 -	mat4 mat = getObjectSkinnedTransform(); +    mat4 mat = getObjectSkinnedTransform();  	mat = modelview_matrix * mat; -	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; -	vertex_color = emissive; - -	calcAtmospherics(pos.xyz); - -	gl_Position = projection_matrix*vec4(pos, 1.0); +	vec4 pos = mat * vec4(position.xyz, 1.0); +    pos = projection_matrix * pos; +	 +	post_pos = pos; +	 +	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); +	 +	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;  } diff --git a/indra/newview/app_settings/shaders/class1/interface/debugSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/interface/debugSkinnedV.glsl new file mode 100644 index 0000000000..74f22aec4f --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/debugSkinnedV.glsl @@ -0,0 +1,41 @@ +/**  + * @file debugSkinnedV.glsl + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat4 projection_matrix; +uniform mat4 modelview_matrix; + +mat4 getObjectSkinnedTransform(); + +ATTRIBUTE vec3 position; + +void main() +{ +    mat4 mat = getObjectSkinnedTransform(); +    mat = modelview_matrix * mat; +    vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; + +    gl_Position = projection_matrix*vec4(pos, 1.0); +} + diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionSkinnedV.glsl index eff75435a9..7305065a05 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/occlusionSkinnedV.glsl @@ -1,6 +1,7 @@  /**  - * @file fullbrightSkinnedV.glsl - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * @file occlusionSkinnedV.glsl + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2007, Linden Research, Inc.   *  @@ -23,35 +24,17 @@   */  uniform mat4 projection_matrix; -uniform mat4 texture_matrix0;  uniform mat4 modelview_matrix;  ATTRIBUTE vec3 position; -ATTRIBUTE vec4 diffuse_color; -ATTRIBUTE vec2 texcoord0; -void calcAtmospherics(vec3 inPositionEye);  mat4 getObjectSkinnedTransform(); -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; - -  void main()  { -	//transform vertex -	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -	  	mat4 mat = getObjectSkinnedTransform(); -	  	mat = modelview_matrix * mat;  	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; -	 -	calcAtmospherics(pos.xyz); - -	vertex_color = diffuse_color; -	  	gl_Position = projection_matrix*vec4(pos, 1.0); -		 -	  } + diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl index 5fcdf3107c..89be8195f0 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl @@ -56,5 +56,6 @@ void fullbright_lighting()  	color.rgb = pow(color.rgb, vec3(1.0/texture_gamma));  	frag_color = color; +  } diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl index a7738087dc..ee9970bc70 100644 --- a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl @@ -33,10 +33,23 @@ ATTRIBUTE vec2 texcoord1;  VARYING vec2 vary_texcoord0;  VARYING vec2 vary_texcoord1; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +uniform mat4 modelview_matrix; +#endif +  void main()  {  	//transform vertex +#ifdef HAS_SKIN +    mat4 mat = getObjectSkinnedTransform(); +    mat = modelview_matrix * mat; +    vec4 pos = mat * vec4(position.xyz, 1.0); +    gl_Position = projection_matrix * pos; +#else  	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); +#endif  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;  	vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;  } diff --git a/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl b/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl index e984deb0c8..d762239e51 100644 --- a/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl @@ -37,20 +37,30 @@ VARYING vec2 vary_texcoord0;  void calcAtmospherics(vec3 inPositionEye); - - +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +#endif  void main()  {  	//transform vertex  	passTextureIndex(); + +#ifdef HAS_SKIN +    mat4 mat = getObjectSkinnedTransform(); +    mat = modelview_matrix * mat; + +    vec4 pos = mat * vec4(position.xyz, 1.0); +    gl_Position = projection_matrix * pos; +#else  	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); +    vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0)); +#endif  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -	vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0)); +	  	calcAtmospherics(pos.xyz);  	vertex_color = emissive; - -	  } diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl deleted file mode 100644 index 1e244d9dfd..0000000000 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl +++ /dev/null @@ -1,71 +0,0 @@ -/**  - * @file shinySimpleSkinnedV.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 texture_matrix1; -uniform mat4 modelview_matrix; -uniform mat4 projection_matrix; - -ATTRIBUTE vec3 position; -ATTRIBUTE vec3 normal; -ATTRIBUTE vec4 diffuse_color; -ATTRIBUTE vec2 texcoord0; - -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; -VARYING vec3 vary_texcoord1; -VARYING vec4 vary_position; - - -void calcAtmospherics(vec3 inPositionEye); -mat4 getObjectSkinnedTransform(); - -void main() -{ -	mat4 mat = getObjectSkinnedTransform(); -	 -	mat = modelview_matrix * mat; -	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; - -    mat4 mvp = modelview_matrix * projection_matrix; -    vary_position = mvp * vec4(position, 1.0); -	 -	vec4 norm = vec4(position.xyz, 1.0); -	norm.xyz += normal.xyz; -	norm.xyz = (mat*norm).xyz; -	norm.xyz = normalize(norm.xyz-pos.xyz); -		 -	vec3 ref = reflect(pos.xyz, -norm.xyz); - -	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -	vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz; - -	calcAtmospherics(pos.xyz); - -	vertex_color = diffuse_color; -	 -	gl_Position = projection_matrix*vec4(pos, 1.0); -	 -	 -} diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl index 34bd8d445a..ace2574ac2 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl @@ -25,7 +25,6 @@  uniform mat3 normal_matrix;  uniform mat4 texture_matrix0; -uniform mat4 texture_matrix1;  uniform mat4 modelview_matrix;  uniform mat4 modelview_projection_matrix; @@ -46,20 +45,32 @@ VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0;  VARYING vec3 vary_texcoord1; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +#endif  void main()  {  	//transform vertex  	vec4 vert = vec4(position.xyz,1.0);  	passTextureIndex(); + +#ifdef HAS_SKIN +    mat4 mat = getObjectSkinnedTransform(); +    mat = modelview_matrix * mat; +    vec4 pos = mat * vert; +    gl_Position = projection_matrix * pos; +	vec3 norm = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); +#else  	vec4 pos = (modelview_matrix * vert);  	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); -	  	vec3 norm = normalize(normal_matrix * normal); +#endif  	vec3 ref = reflect(pos.xyz, -norm);  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -	vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz; +	vary_texcoord1 = transpose(normal_matrix) * ref;  	calcAtmospherics(pos.xyz); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl index fc20d3270e..5af42f1fcf 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl @@ -33,26 +33,33 @@ ATTRIBUTE vec2 texcoord0;  ATTRIBUTE vec3 normal;  ATTRIBUTE vec4 diffuse_color; -  void calcAtmospherics(vec3 inPositionEye); -  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +#endif  void main()  {  	//transform vertex  	vec4 vert = vec4(position.xyz,1.0);  	passTextureIndex(); -	vec4 pos = (modelview_matrix * vert); +#ifdef HAS_SKIN +    mat4 mat = getObjectSkinnedTransform(); +    mat = modelview_matrix * mat; +    vec4 pos = mat * vert; +    gl_Position = projection_matrix * pos; +#else +    vec4 pos = (modelview_matrix * vert);  	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); +#endif  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;  	calcAtmospherics(pos.xyz);  	vertex_color = diffuse_color; - -	  } diff --git a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl deleted file mode 100644 index 727bae19c0..0000000000 --- a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl +++ /dev/null @@ -1,66 +0,0 @@ -/**  - * @file shinySimpleSkinnedV.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 texture_matrix0; -uniform mat4 texture_matrix1; -uniform mat4 modelview_matrix; - -ATTRIBUTE vec3 position; -ATTRIBUTE vec3 normal; -ATTRIBUTE vec4 diffuse_color; -ATTRIBUTE vec2 texcoord0; - -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; -VARYING vec3 vary_texcoord1; - -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color); -void calcAtmospherics(vec3 inPositionEye); -mat4 getObjectSkinnedTransform(); - -void main() -{ -	mat4 mat = getObjectSkinnedTransform(); -	 -	mat = modelview_matrix * mat; -	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; -	 -	vec4 norm = vec4(position.xyz, 1.0); -	norm.xyz += normal.xyz; -	norm.xyz = (mat*norm).xyz; -	norm.xyz = normalize(norm.xyz-pos.xyz); -		 -	vec3 ref = reflect(pos.xyz, -norm.xyz); - -	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -	vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz; - -	calcAtmospherics(pos.xyz); - -	vec4 color = calcLighting(pos.xyz, norm.xyz, diffuse_color); -	vertex_color = color; -	 -	gl_Position = projection_matrix*vec4(pos, 1.0); -} diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl index 4ba8194d03..097e42d233 100644 --- a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl @@ -25,7 +25,6 @@  uniform mat3 normal_matrix;  uniform mat4 texture_matrix0; -uniform mat4 texture_matrix1;  uniform mat4 modelview_matrix;  uniform mat4 modelview_projection_matrix; @@ -45,19 +44,32 @@ void calcAtmospherics(vec3 inPositionEye);  uniform vec4 origin; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +#endif +  void main()  {  	//transform vertex  	vec4 vert = vec4(position.xyz,1.0);  	passTextureIndex(); + +#ifdef HAS_SKIN +    mat4 mat = getObjectSkinnedTransform(); +    mat = modelview_matrix * mat; +    vec4 pos = mat * vert; +    gl_Position = projection_matrix * pos; +	vec3 norm = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); +#else  	vec4 pos = (modelview_matrix * vert);  	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); -		  	vec3 norm = normalize(normal_matrix * normal); +#endif  	vec3 ref = reflect(pos.xyz, -norm); -	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -	vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz; +	vary_texcoord0 = (texture_matrix0*vec4(texcoord0,0,1)).xy; +	vary_texcoord1 = transpose(normal_matrix) * ref;  	calcAtmospherics(pos.xyz); diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl index 9ef7704b70..2025174f7d 100644 --- a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl @@ -44,12 +44,16 @@ void calcAtmospherics(vec3 inPositionEye);  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +uniform mat4 projection_matrix; +#endif +  void main()  {  	//transform vertex  	vec4 vert = vec4(position.xyz,1.0); -	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);  	passTextureIndex();  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0, 0, 1)).xy; @@ -58,11 +62,23 @@ void main()  	if (no_atmo == 1)  	{  		vertex_color = diffuse_color; +        gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);  	}  	else  	{ +#ifdef HAS_SKIN +        mat4 mat = getObjectSkinnedTransform(); +        mat = modelview_matrix * mat; + +        vec4 pos = mat * vert; +        vec3 norm = normalize((mat*vec4(normal.xyz+vert.xyz,1.0)).xyz-pos.xyz); + +        gl_Position = projection_matrix * pos; +#else  		vec4 pos = (modelview_matrix * vert);  		vec3 norm = normalize(normal_matrix * normal); +        gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); +#endif  		calcAtmospherics(pos.xyz); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 52ef2966ce..177558d38f 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1430,6 +1430,11 @@ bool LLAppViewer::doFrame()  {  	LL_RECORD_BLOCK_TIME(FTM_FRAME); +    if (!LLWorld::instanceExists()) +    { +        LLWorld::createInstance(); +    } +  	LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));  	LLSD newFrame; diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 502ebbd4b1..7e99b99284 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -149,21 +149,6 @@ void LLDrawable::unload()  {  	LLVOVolume *pVVol = getVOVolume();  	pVVol->setNoLOD(); - -	for (S32 i = 0; i < getNumFaces(); i++) -	{ -		LLFace* facep = getFace(i); -		if (facep->isState(LLFace::RIGGED)) -		{ -			LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*)facep->getPool(); -			if (pool) { -				pool->removeRiggedFace(facep); -			} -			facep->setVertexBuffer(NULL); -		} -		facep->clearState(LLFace::RIGGED); -	} -  	pVVol->markForUpdate(TRUE);  } diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 3e4f97e494..92a9bed504 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -50,6 +50,9 @@  #include "lldrawpoolwlsky.h"  #include "llglslshader.h"  #include "llglcommonfunc.h" +#include "llvoavatar.h" +#include "llviewershadermgr.h" +  S32 LLDrawPool::sNumDrawPools = 0; @@ -385,21 +388,43 @@ LLRenderPass::~LLRenderPass()  }  void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture) -{					 +{ +    LL_PROFILE_ZONE_SCOPED;  	LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];  	for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)	  	{  		LLDrawInfo *pparams = *k; -		if (pparams) { +		if (pparams)  +        {  			pushBatch(*pparams, mask, texture);  		}  	}  } -void LLRenderPass::renderTexture(U32 type, U32 mask, BOOL batch_textures) +void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture)  { -	pushBatches(type, mask, true, batch_textures); +    LL_PROFILE_ZONE_SCOPED; +    LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; +    LLVOAvatar* lastAvatar = nullptr; +    U64 lastMeshId = 0; +    mask |= LLVertexBuffer::MAP_WEIGHT4; + +    for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) +    { +        LLDrawInfo* pparams = *k; +        if (pparams)  +        { +            if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash) +            { +                uploadMatrixPalette(*pparams); +                lastAvatar = pparams->mAvatar; +                lastMeshId = pparams->mSkinInfo->mHash; +            } + +            pushBatch(*pparams, mask, texture); +        } +    }  }  void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures) @@ -415,27 +440,74 @@ void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_text  	}  } +void LLRenderPass::pushRiggedBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures) +{ +    LL_PROFILE_ZONE_SCOPED; +    LLVOAvatar* lastAvatar = nullptr; +    U64 lastMeshId = 0; +    mask |= LLVertexBuffer::MAP_WEIGHT4; +    for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) +    { +        LLDrawInfo* pparams = *i; +        if (pparams) +        { +            if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash) +            { +                uploadMatrixPalette(*pparams); +                lastAvatar = pparams->mAvatar; +                lastMeshId = pparams->mSkinInfo->mHash; +            } + +            pushBatch(*pparams, mask, texture, batch_textures); +        } +    } +} +  void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)  { +    LL_PROFILE_ZONE_SCOPED;  	for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)	  	{  		LLDrawInfo* pparams = *i;  		if (pparams)   		{ -			if (LLGLSLShader::sCurBoundShaderPtr) -			{ -				LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff); -			} -			else -			{ -				gGL.setAlphaRejectSettings(LLRender::CF_GREATER, pparams->mAlphaMaskCutoff); -			} -			 +			LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);  			pushBatch(*pparams, mask, texture, batch_textures);  		}  	}  } +void LLRenderPass::pushRiggedMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures) +{ +    LL_PROFILE_ZONE_SCOPED; +    LLVOAvatar* lastAvatar = nullptr; +    U64 lastMeshId = 0; +    for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) +    { +        LLDrawInfo* pparams = *i; +        if (pparams) +        { +            if (LLGLSLShader::sCurBoundShaderPtr) +            { +                LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff); +            } +            else +            { +                gGL.setAlphaRejectSettings(LLRender::CF_GREATER, pparams->mAlphaMaskCutoff); +            } + +            if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash) +            { +                uploadMatrixPalette(*pparams); +                lastAvatar = pparams->mAvatar; +                lastMeshId = pparams->mSkinInfo->mHash; +            } + +            pushBatch(*pparams, mask | LLVertexBuffer::MAP_WEIGHT4, texture, batch_textures); +        } +    } +} +  void LLRenderPass::applyModelMatrix(const LLDrawInfo& params)  {  	if (params.mModelMatrix != gGLLastMatrix) @@ -514,7 +586,24 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba  	}  } -void LLRenderPass::renderGroups(U32 type, U32 mask, BOOL texture) +// static +bool LLRenderPass::uploadMatrixPalette(LLDrawInfo& params)  { -	gPipeline.renderGroups(this, type, mask, texture); +    // upload matrix palette to shader +    const LLVOAvatar::MatrixPaletteCache& mpc = params.mAvatar->updateSkinInfoMatrixPalette(params.mSkinInfo); +    U32 count = mpc.mMatrixPalette.size(); + +    if (count == 0) +    { +        //skin info not loaded yet, don't render +        return false; +    } + +    LLGLSLShader::sCurBoundShaderPtr->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, +        count, +        FALSE, +        (GLfloat*)&(mpc.mGLMp[0])); + +    return true;  } + diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index ecd9bd034f..6d49b0254b 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -125,38 +125,68 @@ protected:  class LLRenderPass : public LLDrawPool  {  public: +    // list of possible LLRenderPass types to assign a render batch to +    // NOTE: "rigged" variant MUST be non-rigged variant + 1  	enum  	{  		PASS_SIMPLE = NUM_POOL_TYPES, +        PASS_SIMPLE_RIGGED,  		PASS_GRASS,  		PASS_FULLBRIGHT, +        PASS_FULLBRIGHT_RIGGED,  		PASS_INVISIBLE, -		PASS_INVISI_SHINY, +        PASS_INVISIBLE_RIGGED, +		PASS_INVISI_SHINY,  +        PASS_INVISI_SHINY_RIGGED,  		PASS_FULLBRIGHT_SHINY, +        PASS_FULLBRIGHT_SHINY_RIGGED,  		PASS_SHINY, +        PASS_SHINY_RIGGED,  		PASS_BUMP, +        PASS_BUMP_RIGGED,  		PASS_POST_BUMP, +        PASS_POST_BUMP_RIGGED,  		PASS_MATERIAL, +        PASS_MATERIAL_RIGGED,  		PASS_MATERIAL_ALPHA, +        PASS_MATERIAL_ALPHA_RIGGED,  		PASS_MATERIAL_ALPHA_MASK,              // Diffuse texture used as alpha mask +        PASS_MATERIAL_ALPHA_MASK_RIGGED,  		PASS_MATERIAL_ALPHA_EMISSIVE, +        PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED,  		PASS_SPECMAP, +        PASS_SPECMAP_RIGGED,  		PASS_SPECMAP_BLEND, +        PASS_SPECMAP_BLEND_RIGGED,  		PASS_SPECMAP_MASK,                     // Diffuse texture used as alpha mask and specular texture(map) +        PASS_SPECMAP_MASK_RIGGED,  		PASS_SPECMAP_EMISSIVE, +        PASS_SPECMAP_EMISSIVE_RIGGED,  		PASS_NORMMAP, +        PASS_NORMMAP_RIGGED,  		PASS_NORMMAP_BLEND, +        PASS_NORMMAP_BLEND_RIGGED,  		PASS_NORMMAP_MASK,                     // Diffuse texture used as alpha mask and normal map +        PASS_NORMMAP_MASK_RIGGED,  		PASS_NORMMAP_EMISSIVE, +        PASS_NORMMAP_EMISSIVE_RIGGED,  		PASS_NORMSPEC, -		PASS_NORMSPEC_BLEND, +        PASS_NORMSPEC_RIGGED, +		PASS_NORMSPEC_BLEND,  +        PASS_NORMSPEC_BLEND_RIGGED,  		PASS_NORMSPEC_MASK,                    // Diffuse texture used as alpha mask with normal and specular map +        PASS_NORMSPEC_MASK_RIGGED,  		PASS_NORMSPEC_EMISSIVE, +        PASS_NORMSPEC_EMISSIVE_RIGGED,  		PASS_GLOW, +        PASS_GLOW_RIGGED,  		PASS_ALPHA,  		PASS_ALPHA_MASK, +        PASS_ALPHA_MASK_RIGGED,  		PASS_FULLBRIGHT_ALPHA_MASK,            // Diffuse texture used as alpha mask and fullbright +        PASS_FULLBRIGHT_ALPHA_MASK_RIGGED,  		PASS_ALPHA_INVISIBLE, +        PASS_ALPHA_INVISIBLE_RIGGED,  		NUM_RENDER_TYPES,  	}; @@ -169,12 +199,13 @@ public:  	static void applyModelMatrix(const LLDrawInfo& params);  	virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE); +    virtual void pushRiggedBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);  	virtual void pushMaskBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE); +    virtual void pushRiggedMaskBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);  	virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE); +    static bool uploadMatrixPalette(LLDrawInfo& params);  	virtual void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE); -	virtual void renderGroups(U32 type, U32 mask, BOOL texture = TRUE); -	virtual void renderTexture(U32 type, U32 mask, BOOL batch_textures = TRUE); - +    virtual void renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);  };  class LLFacePool : public LLDrawPool diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 34f9bfe35d..9b298b120a 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -48,18 +48,20 @@  #include "lldrawpoolwater.h"  #include "llspatialpartition.h"  #include "llglcommonfunc.h" +#include "llvoavatar.h"  BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE; +#define current_shader (LLGLSLShader::sCurBoundShaderPtr) +  static BOOL deferred_render = FALSE;  LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) : -		LLRenderPass(type), current_shader(NULL), target_shader(NULL), -		simple_shader(NULL), fullbright_shader(NULL), emissive_shader(NULL), +		LLRenderPass(type), target_shader(NULL),  		mColorSFactor(LLRender::BF_UNDEF), mColorDFactor(LLRender::BF_UNDEF),  		mAlphaSFactor(LLRender::BF_UNDEF), mAlphaDFactor(LLRender::BF_UNDEF)  { - +   }  LLDrawPoolAlpha::~LLDrawPoolAlpha() @@ -98,33 +100,43 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)      F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); -    emissive_shader = (LLPipeline::sRenderDeferred)   ? &gDeferredEmissiveProgram    : -                      (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram; +    emissive_shader[0] = (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram; +    emissive_shader[1] = emissive_shader[0]->mRiggedVariant; -    emissive_shader->bind(); -    emissive_shader->uniform1i(LLShaderMgr::NO_ATMO, (LLPipeline::sRenderingHUDs) ? 1 : 0); -    emissive_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);  -	emissive_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); +    for (int i = 0; i < 2; ++i) +    { +        emissive_shader[i]->bind(); +        emissive_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, (LLPipeline::sRenderingHUDs) ? 1 : 0); +        emissive_shader[i]->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); +        emissive_shader[i]->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f)); +    }  	if (pass == 0)  	{ -        fullbright_shader = (LLPipeline::sImpostorRender)   ? &gDeferredFullbrightProgram      : -                            (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightProgram; - -		fullbright_shader->bind(); -		fullbright_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);  -		fullbright_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); -        fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); -		fullbright_shader->unbind(); +        fullbright_shader[0] = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightProgram : +                (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightProgram; +        fullbright_shader[1] = fullbright_shader[0]->mRiggedVariant; +  +        for (int i = 0; i < 2; ++i) +        { +            fullbright_shader[i]->bind(); +            fullbright_shader[i]->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); +            fullbright_shader[i]->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f)); +            fullbright_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); +            fullbright_shader[i]->unbind(); +        } -        simple_shader = (LLPipeline::sImpostorRender)   ? &gDeferredAlphaImpostorProgram : -                        (LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram    : &gDeferredAlphaProgram; +        simple_shader[0] = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram : +                (LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram; +        simple_shader[1] = simple_shader[0]->mRiggedVariant;  		//prime simple shader (loads shadow relevant uniforms) -		gPipeline.bindDeferredShader(*simple_shader); - -		simple_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); -        simple_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); +        for (int i = 0; i < 2; ++i) +        { +            gPipeline.bindDeferredShader(*simple_shader[i]); +            simple_shader[i]->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f)); +            simple_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); +        }  	}  	else if (!LLPipeline::sImpostorRender)  	{ @@ -133,16 +145,21 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)  		gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(),  							0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);	  		gPipeline.mDeferredDepth.bindTarget(); -		simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram; -		gObjectFullbrightAlphaMaskProgram.bind(); -		gObjectFullbrightAlphaMaskProgram.setMinimumAlpha(0.33f); +		simple_shader[0] = fullbright_shader[0] = &gObjectFullbrightAlphaMaskProgram; +        simple_shader[1] = fullbright_shader[1] = simple_shader[0]->mRiggedVariant; +         +        for (int i = 0; i < 2; ++i) +        { +            simple_shader[i]->bind(); +            simple_shader[i]->setMinimumAlpha(0.33f); +        }  	}  	deferred_render = TRUE;  	if (mShaderLevel > 0)  	{  		// Start out with no shaders. -		current_shader = target_shader = NULL; +		target_shader = NULL;  	}  	gPipeline.enableLightsDynamic();  } @@ -155,7 +172,7 @@ void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)  	{  		gPipeline.mDeferredDepth.flush();  		gPipeline.mScreen.bindTarget(); -		gObjectFullbrightAlphaMaskProgram.unbind(); +		LLGLSLShader::sCurBoundShaderPtr->unbind();  	}  	deferred_render = FALSE; @@ -172,51 +189,46 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass)  {      LL_PROFILE_ZONE_SCOPED; -    simple_shader     = (LLPipeline::sImpostorRender)   ? &gObjectSimpleImpostorProgram  : +    simple_shader[0]     = (LLPipeline::sImpostorRender)   ? &gObjectSimpleImpostorProgram  :                          (LLPipeline::sUnderWaterRender) ? &gObjectSimpleWaterProgram     : &gObjectSimpleProgram; -    fullbright_shader = (LLPipeline::sImpostorRender)   ? &gObjectFullbrightProgram      : +    fullbright_shader[0] = (LLPipeline::sImpostorRender)   ? &gObjectFullbrightProgram      :                          (LLPipeline::sUnderWaterRender) ? &gObjectFullbrightWaterProgram : &gObjectFullbrightProgram; -    emissive_shader   = (LLPipeline::sImpostorRender)   ? &gObjectEmissiveProgram        : +    emissive_shader[0]   = (LLPipeline::sImpostorRender)   ? &gObjectEmissiveProgram        :                          (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram   : &gObjectEmissiveProgram; +    simple_shader[1] = simple_shader[0]->mRiggedVariant; +    fullbright_shader[1] = fullbright_shader[0]->mRiggedVariant; +    emissive_shader[1] = emissive_shader[0]->mRiggedVariant; +      if (LLPipeline::sImpostorRender)  	{ -        if (mShaderLevel > 0) -		{ -            fullbright_shader->bind(); -			fullbright_shader->setMinimumAlpha(0.5f); -            fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); -			simple_shader->bind(); -			simple_shader->setMinimumAlpha(0.5f); -            simple_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); -        } -        else +        for (int i = 0; i < 2; ++i)          { -            gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); //OK +            fullbright_shader[i]->bind(); +            fullbright_shader[i]->setMinimumAlpha(0.5f); +            fullbright_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); +            simple_shader[i]->bind(); +            simple_shader[i]->setMinimumAlpha(0.5f); +            simple_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);          }  	}      else  	{ -        if (mShaderLevel > 0) -	    { -			fullbright_shader->bind(); -			fullbright_shader->setMinimumAlpha(0.f); -            fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); -			simple_shader->bind(); -			simple_shader->setMinimumAlpha(0.f); -            simple_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); -		} -        else +        for (int i = 0; i < 2; ++i)          { -            gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK +            fullbright_shader[i]->bind(); +            fullbright_shader[i]->setMinimumAlpha(0.f); +            fullbright_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); +            simple_shader[i]->bind(); +            simple_shader[i]->setMinimumAlpha(0.f); +            simple_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);          }      }  	gPipeline.enableLightsDynamic();      LLGLSLShader::bindNoShader(); -	current_shader = NULL;  }  void LLDrawPoolAlpha::endRenderPass( S32 pass ) @@ -266,14 +278,7 @@ void LLDrawPoolAlpha::render(S32 pass)  		gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);  	} -	if (mShaderLevel > 0) -	{ -		renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, pass); -	} -	else -	{ -		renderAlpha(getVertexDataMask(), pass); -	} +	renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, pass);  	gGL.setColorMask(true, false); @@ -284,16 +289,8 @@ void LLDrawPoolAlpha::render(S32 pass)  	if (sShowDebugAlpha)  	{ -		BOOL shaders = gPipeline.canUseVertexShaders(); -		if(shaders)  -		{ -			gHighlightProgram.bind(); -		} -		else -		{ -			gPipeline.enableLightsFullbright(); -		} - +		gHighlightProgram.bind(); +		  		gGL.diffuseColor4f(1,0,0,1);  		LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f*1024.f); @@ -315,10 +312,23 @@ void LLDrawPoolAlpha::render(S32 pass)  		gGL.diffuseColor4f(0, 1, 0, 1);  		pushBatches(LLRenderPass::PASS_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); -		if(shaders)  -		{ -			gHighlightProgram.unbind(); -		} +        gHighlightProgram.mRiggedVariant->bind(); +        gGL.diffuseColor4f(1, 0, 0, 1); + +        pushRiggedBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); +        pushRiggedBatches(LLRenderPass::PASS_ALPHA_INVISIBLE_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); + +        // Material alpha mask +        gGL.diffuseColor4f(0, 0, 1, 1); +        pushRiggedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); +        pushRiggedBatches(LLRenderPass::PASS_NORMMAP_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); +        pushRiggedBatches(LLRenderPass::PASS_SPECMAP_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); +        pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); +        pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); + +        gGL.diffuseColor4f(0, 1, 0, 1); +        pushRiggedBatches(LLRenderPass::PASS_INVISIBLE_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); +        LLGLSLShader::sCurBoundShaderPtr->unbind();  	}  } @@ -375,7 +385,7 @@ inline void Draw(LLDrawInfo* draw, U32 mask)  	draw->mVertexBuffer->drawRangeFast(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);                      } -bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material, LLGLSLShader* current_shader) +bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material)  {      bool tex_setup = false; @@ -393,7 +403,7 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material, LLGLSLShader  			current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap);  		}       } -    else if (current_shader == simple_shader) +    else if (current_shader == simple_shader[0] || current_shader == simple_shader[1])      {          current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);  	    current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); @@ -450,81 +460,86 @@ void LLDrawPoolAlpha::RestoreTexSetup(bool tex_setup)  	}  } -void LLDrawPoolAlpha::renderFullbrights(U32 mask, std::vector<LLDrawInfo*>& fullbrights) -{ -    gPipeline.enableLightsFullbright(); -    fullbright_shader->bind(); -    fullbright_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.0f); -     -    for (LLDrawInfo* draw : fullbrights) -    { -        bool tex_setup = TexSetup(draw, false, fullbright_shader); - -        LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test); -		gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); - -        Draw(draw, mask & ~(LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2)); -        RestoreTexSetup(tex_setup); -    } -    fullbright_shader->unbind(); -} -  void LLDrawPoolAlpha::drawEmissive(U32 mask, LLDrawInfo* draw)  { +    LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f);      draw->mVertexBuffer->setBufferFast((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);  	draw->mVertexBuffer->drawRangeFast(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);  } -void LLDrawPoolAlpha::drawEmissiveInline(U32 mask, LLDrawInfo* draw) + +void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives)  { +    emissive_shader[0]->bind(); +    emissive_shader[0]->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f); + +    gPipeline.enableLightsDynamic(); +      // install glow-accumulating blend mode -    gGL.blendFunc( -            LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color -			LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow) +    // don't touch color, add to alpha (glow) +    gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE); -	emissive_shader->bind(); -					 -	drawEmissive(mask, draw); +    for (LLDrawInfo* draw : emissives) +    { +        bool tex_setup = TexSetup(draw, false); +        drawEmissive(mask, draw); +        RestoreTexSetup(tex_setup); +    } -	// restore our alpha blend mode -	gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); +    // restore our alpha blend mode +    gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); -    current_shader->bind(); +    emissive_shader[0]->unbind();  } -void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives) +void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives)  { -    emissive_shader->bind(); -    emissive_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f); +    emissive_shader[1]->bind(); +    emissive_shader[1]->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f);      gPipeline.enableLightsDynamic(); +    mask |= LLVertexBuffer::MAP_WEIGHT4;      // install glow-accumulating blend mode      // don't touch color, add to alpha (glow) -	gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE);  -  +    gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE); + +    LLVOAvatar* lastAvatar = nullptr; +    U64 lastMeshId = 0; +      for (LLDrawInfo* draw : emissives)      { -        bool tex_setup = TexSetup(draw, false, emissive_shader); +        bool tex_setup = TexSetup(draw, false); +        if (lastAvatar != draw->mAvatar || lastMeshId != draw->mSkinInfo->mHash) +        { +            if (!uploadMatrixPalette(*draw)) +            { // failed to upload matrix palette, skip rendering +                continue; +            } +            lastAvatar = draw->mAvatar; +            lastMeshId = draw->mSkinInfo->mHash; +        }          drawEmissive(mask, draw);          RestoreTexSetup(tex_setup);      }      // restore our alpha blend mode -	gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); +    gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); -    emissive_shader->unbind(); +    emissive_shader[1]->unbind();  }  void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  {      LL_PROFILE_ZONE_SCOPED; -    BOOL batch_fullbrights = gSavedSettings.getBOOL("RenderAlphaBatchFullbrights"); -    BOOL batch_emissives   = gSavedSettings.getBOOL("RenderAlphaBatchEmissives"); -	BOOL initialized_lighting = FALSE; +    BOOL initialized_lighting = FALSE;  	BOOL light_enabled = TRUE; -	 -	for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) + +    LLVOAvatar* lastAvatar = nullptr; +    U64 lastMeshId = 0; +    LLGLSLShader* lastAvatarShader = nullptr; + +    for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)  	{          LL_PROFILE_ZONE_NAMED("renderAlpha - group");  		LLSpatialGroup* group = *i; @@ -535,9 +550,9 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  		    !group->isDead())  		{              static std::vector<LLDrawInfo*> emissives; -            static std::vector<LLDrawInfo*> fullbrights; +            static std::vector<LLDrawInfo*> rigged_emissives;              emissives.resize(0); -            fullbrights.resize(0); +            rigged_emissives.resize(0);  			bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE  													  || group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE; @@ -579,12 +594,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  					}  				} -                if (params.mFullbright && batch_fullbrights) -				{ -                    fullbrights.push_back(¶ms); -                    continue; -				} -  				LLRenderPass::applyModelMatrix(params);  				LLMaterial* mat = NULL; @@ -600,7 +609,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  					if (light_enabled || !initialized_lighting)  					{  						initialized_lighting = TRUE; -						target_shader = fullbright_shader; +						target_shader = fullbright_shader[0];  						light_enabled = FALSE;  					} @@ -609,7 +618,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  				else if (!light_enabled || !initialized_lighting)  				{  					initialized_lighting = TRUE; -					target_shader = simple_shader; +					target_shader = simple_shader[0];  					light_enabled = TRUE;  				} @@ -625,27 +634,36 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  						target_shader = &(gDeferredMaterialWaterProgram[mask]);  					} +                    if (params.mAvatar != nullptr) +                    { +                        llassert(target_shader->mRiggedVariant != nullptr); +                        target_shader = target_shader->mRiggedVariant; +                    } +  					if (current_shader != target_shader)  					{  						gPipeline.bindDeferredShader(*target_shader); -                        current_shader = target_shader;  					}  				}  				else if (!params.mFullbright)  				{ -					target_shader = simple_shader; +					target_shader = simple_shader[0];  				}  				else  				{ -					target_shader = fullbright_shader; +					target_shader = fullbright_shader[0];  				} -				if(current_shader != target_shader) -				{// If we need shaders, and we're not ALREADY using the proper shader, then bind it -				// (this way we won't rebind shaders unnecessarily). -					current_shader = target_shader; -					current_shader->bind(); -				} +                if (params.mAvatar != nullptr) +                { +                    target_shader = target_shader->mRiggedVariant; +                } + +                if (current_shader != target_shader) +                {// If we need shaders, and we're not ALREADY using the proper shader, then bind it +                // (this way we won't rebind shaders unnecessarily). +                    target_shader->bind(); +                }                  LLVector4 spec_color(1, 1, 1, 1);                  F32 env_intensity = 0.0f; @@ -661,7 +679,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)                  if (current_shader)                  { -                    current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, spec_color.mV[0], spec_color.mV[1], spec_color.mV[2], spec_color.mV[3]);						 +                    current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, spec_color.mV[0], spec_color.mV[1], spec_color.mV[2], spec_color.mV[3]);  				    current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env_intensity);  					current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, brightness);                  } @@ -671,32 +689,54 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  					params.mGroup->rebuildMesh();  				} -                bool tex_setup = TexSetup(¶ms, (mat != nullptr), current_shader); +                if (params.mAvatar != nullptr) +                { +                    if (lastAvatar != params.mAvatar || +                        lastMeshId != params.mSkinInfo->mHash || +                        lastAvatarShader != LLGLSLShader::sCurBoundShaderPtr) +                    { +                        if (!uploadMatrixPalette(params)) +                        { +                            continue; +                        } +                        lastAvatar = params.mAvatar; +                        lastMeshId = params.mSkinInfo->mHash; +                        lastAvatarShader = LLGLSLShader::sCurBoundShaderPtr; +                    } +                } + +                bool tex_setup = TexSetup(¶ms, (mat != nullptr));  				{  					LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);  					gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); -					params.mVertexBuffer->setBufferFast(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0)); - +                    U32 drawMask = mask; +                    if (params.mFullbright)                      { -					    params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); +                        drawMask &= ~(LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2);                      } +                    if (params.mAvatar != nullptr) +                    { +                        drawMask |= LLVertexBuffer::MAP_WEIGHT4; +                    } + +                    params.mVertexBuffer->setBufferFast(drawMask); +                    params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);  				}  				// If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow).  Interleaving these state-changing calls is expensive, but glow must be drawn Z-sorted with alpha. -				if (current_shader &&  -					draw_glow_for_this_partition && +				if (draw_glow_for_this_partition &&  					params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE))  				{ -                    if (batch_emissives) +                    if (params.mAvatar != nullptr)                      { -                        emissives.push_back(¶ms); +                        rigged_emissives.push_back(¶ms);                      }                      else                      { -                        drawEmissiveInline(mask, ¶ms); -                    }  +                        emissives.push_back(¶ms); +                    }  				}  				if (tex_setup) @@ -708,41 +748,56 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  				}  			} - -            bool rebind = false; -            if (batch_fullbrights)              { -                if (!fullbrights.empty()) +                bool rebind = false; +                LLGLSLShader* lastShader = current_shader; +                if (!emissives.empty())                  { -                    light_enabled = false; -                    renderFullbrights(mask, fullbrights); +                    light_enabled = true; +                    renderEmissives(mask, emissives);                      rebind = true;                  } -            } -            if (batch_emissives) -            { -                if (!emissives.empty()) +                if (!rigged_emissives.empty())                  {                      light_enabled = true; -                    renderEmissives(mask, emissives); +                    renderRiggedEmissives(mask, rigged_emissives);                      rebind = true;                  } -            } -            if (current_shader && rebind) -            { -                current_shader->bind(); +                if (lastShader && rebind) +                { +                    lastShader->bind(); +                }              } -		}         +		}  	}  	gGL.setSceneBlendType(LLRender::BT_ALPHA); -	LLVertexBuffer::unbind();	 -		 +	LLVertexBuffer::unbind(); +  	if (!light_enabled)  	{  		gPipeline.enableLightsDynamic();  	}  } + +bool LLDrawPoolAlpha::uploadMatrixPalette(const LLDrawInfo& params) +{ +    const LLVOAvatar::MatrixPaletteCache& mpc = params.mAvatar->updateSkinInfoMatrixPalette(params.mSkinInfo); +    U32 count = mpc.mMatrixPalette.size(); + +    if (count == 0) +    { +        //skin info not loaded yet, don't render +        return false; +    } + +    LLGLSLShader::sCurBoundShaderPtr->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, +        count, +        FALSE, +        (GLfloat*)&(mpc.mGLMp[0])); + +    return true; +} diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h index a50b1d929e..64c17c3fef 100644 --- a/indra/newview/lldrawpoolalpha.h +++ b/indra/newview/lldrawpoolalpha.h @@ -65,23 +65,22 @@ public:  	void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);  	void renderAlpha(U32 mask, S32 pass);  	void renderAlphaHighlight(U32 mask); -		 +    bool uploadMatrixPalette(const LLDrawInfo& params); +  	static BOOL sShowDebugAlpha;  private: -	LLGLSLShader* current_shader;  	LLGLSLShader* target_shader; -	LLGLSLShader* simple_shader; -	LLGLSLShader* fullbright_shader;	 -	LLGLSLShader* emissive_shader; -    void renderFullbrights(U32 mask, std::vector<LLDrawInfo*>& fullbrights); -    void renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives); +    // setup by beginFooPass, [0] is static variant, [1] is rigged variant +    LLGLSLShader* simple_shader[2] = { nullptr }; +	LLGLSLShader* fullbright_shader[2] = { nullptr }; +	LLGLSLShader* emissive_shader[2] = { nullptr };      void drawEmissive(U32 mask, LLDrawInfo* draw); -    void drawEmissiveInline(U32 mask, LLDrawInfo* draw); - -    bool TexSetup(LLDrawInfo* draw, bool use_material, LLGLSLShader* current_shader); +    void renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives); +    void renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives); +    bool TexSetup(LLDrawInfo* draw, bool use_material);      void RestoreTexSetup(bool tex_setup);  	// our 'normal' alpha blend function for this pass @@ -89,6 +88,9 @@ private:  	LLRender::eBlendFactor mColorDFactor;	  	LLRender::eBlendFactor mAlphaSFactor;  	LLRender::eBlendFactor mAlphaDFactor; + +    // if true, we're executing a rigged render pass +    bool mRigged = false;  };  class LLDrawPoolAlphaPostWater : public LLDrawPoolAlpha diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 5b51e9db24..125cd3fd5b 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -126,13 +126,6 @@ BOOL LLDrawPoolAvatar::isDead()          return FALSE;      } -	for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i) -    { -        if (mRiggedFace[i].size() > 0) -        { -            return FALSE; -        } -    }      return TRUE;  } @@ -159,17 +152,6 @@ void LLDrawPoolAvatar::prerender()  	{  		sBufferUsage = GL_STREAM_DRAW_ARB;  	} - -	if (!mDrawFace.empty()) -	{ -		const LLFace *facep = mDrawFace[0]; -		if (facep && facep->getDrawable()) -		{ -			LLVOAvatar* avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get(); -			updateRiggedVertexBuffers(avatarp); -            updateSkinInfoMatrixPalettes(avatarp); -		} -	}  }  LLMatrix4& LLDrawPoolAvatar::getModelView() @@ -215,15 +197,6 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass)  	case 2:  		beginDeferredSkinned();  		break; -	case 3: -		beginDeferredRiggedSimple(); -		break; -	case 4: -		beginDeferredRiggedBump(); -		break; -	default: -		beginDeferredRiggedMaterial(pass-5); -		break;  	}  } @@ -250,15 +223,6 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass)  	case 2:  		endDeferredSkinned();  		break; -	case 3: -		endDeferredRiggedSimple(); -		break; -	case 4: -		endDeferredRiggedBump(); -		break; -	default: -		endDeferredRiggedMaterial(pass-5); -		break;  	}  } @@ -271,176 +235,51 @@ void LLDrawPoolAvatar::renderDeferred(S32 pass)  S32 LLDrawPoolAvatar::getNumPostDeferredPasses()  { -	return 10; +	return 1;  }  void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass)  {      LL_PROFILE_ZONE_SCOPED -	switch (pass) -	{ -	case 0: -		beginPostDeferredAlpha(); -		break; -	case 1: -		beginRiggedFullbright(); -		break; -	case 2: -		beginRiggedFullbrightShiny(); -		break; -	case 3: -		beginDeferredRiggedAlpha(); -		break; -	case 4: -		beginRiggedFullbrightAlpha(); -		break; -	case 9: -		beginRiggedGlow(); -		break; -	default: -		beginDeferredRiggedMaterialAlpha(pass-5); -		break; -	} -} - -void LLDrawPoolAvatar::beginPostDeferredAlpha() -{ -    LL_PROFILE_ZONE_SCOPED - -	sSkipOpaque = TRUE; -	sShaderLevel = mShaderLevel; -	sVertexProgram = &gDeferredAvatarAlphaProgram; -	sRenderingSkinned = TRUE; +        sSkipOpaque = TRUE; +    sShaderLevel = mShaderLevel; +    sVertexProgram = &gDeferredAvatarAlphaProgram; +    sRenderingSkinned = TRUE; -	gPipeline.bindDeferredShader(*sVertexProgram); +    gPipeline.bindDeferredShader(*sVertexProgram); -	sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha); - -	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); -} - -void LLDrawPoolAvatar::beginDeferredRiggedAlpha() -{ -    LL_PROFILE_ZONE_SCOPED +    sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha); -	sVertexProgram = &gDeferredSkinnedAlphaProgram; -	gPipeline.bindDeferredShader(*sVertexProgram); -	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); -	gPipeline.enableLightsDynamic(); -} - -void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass) -{ -    LL_PROFILE_ZONE_SCOPED - -	switch (pass) -	{ -	case 0: pass = 1; break; -	case 1: pass = 5; break; -	case 2: pass = 9; break; -	default: pass = 13; break; -	} - -	pass += LLMaterial::SHADER_COUNT; - -	sVertexProgram = &gDeferredMaterialProgram[pass]; - -	if (LLPipeline::sUnderWaterRender) -	{ -		sVertexProgram = &(gDeferredMaterialWaterProgram[pass]); -	} - -	gPipeline.bindDeferredShader(*sVertexProgram); -	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); -	normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP); -	specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP); -	gPipeline.enableLightsDynamic(); -} - -void LLDrawPoolAvatar::endDeferredRiggedAlpha() -{ -    LL_PROFILE_ZONE_SCOPED - -	LLVertexBuffer::unbind(); -	gPipeline.unbindDeferredShader(*sVertexProgram); -	sDiffuseChannel = 0; -	normal_channel = -1; -	specular_channel = -1; -	sVertexProgram = NULL; +    sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);  }  void LLDrawPoolAvatar::endPostDeferredPass(S32 pass)  {      LL_PROFILE_ZONE_SCOPED +    // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done +    sRenderingSkinned = FALSE; +    sSkipOpaque = FALSE; -	switch (pass) -	{ -	case 0: -		endPostDeferredAlpha(); -		break; -	case 1: -		endRiggedFullbright(); -		break; -	case 2: -		endRiggedFullbrightShiny(); -		break; -	case 3: -		endDeferredRiggedAlpha(); -		break; -	case 4: -		endRiggedFullbrightAlpha(); -		break; -	case 5: -		endRiggedGlow(); -		break; -	default: -		endDeferredRiggedAlpha(); -		break; -	} -} - -void LLDrawPoolAvatar::endPostDeferredAlpha() -{ -    LL_PROFILE_ZONE_SCOPED - -	// if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done -	sRenderingSkinned = FALSE; -	sSkipOpaque = FALSE; -		 -	gPipeline.unbindDeferredShader(*sVertexProgram); -	sDiffuseChannel = 0; -	sShaderLevel = mShaderLevel; +    gPipeline.unbindDeferredShader(*sVertexProgram); +    sDiffuseChannel = 0; +    sShaderLevel = mShaderLevel;  }  void LLDrawPoolAvatar::renderPostDeferred(S32 pass)  {      LL_PROFILE_ZONE_SCOPED -	static const S32 actual_pass[] = -	{ //map post deferred pass numbers to what render() expects -		2, //skinned -		4, // rigged fullbright -		6, //rigged fullbright shiny -		7, //rigged alpha -		8, //rigged fullbright alpha -		9, //rigged material alpha 1 -		10,//rigged material alpha 2 -		11,//rigged material alpha 3 -		12,//rigged material alpha 4 -		13, //rigged glow -	}; - -	S32 p = actual_pass[pass]; - +    is_post_deferred_render = true;  	if (LLPipeline::sImpostorRender)  	{ //HACK for impostors so actual pass ends up being proper pass -		p -= 2; +        render(0);  	} - -	is_post_deferred_render = true; -	render(p); -	is_post_deferred_render = false; +    else +    { +        render(2); +    } +    is_post_deferred_render = false;  } @@ -506,68 +345,12 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)          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... -        S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP); -        sDiffuseChannel = 0; -        if (loc != -1) -        { -            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... -        S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP); -        sDiffuseChannel = 0; -        if (loc != -1) -        { -            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; -        S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP); -        sDiffuseChannel = 0; -        if (loc != -1) -        { -            sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); -        } -        sVertexProgram->bind(); -    }  }  void LLDrawPoolAvatar::endShadowPass(S32 pass)  {  	LL_PROFILE_ZONE_SCOPED; -    if (pass == SHADOW_PASS_ATTACHMENT_OPAQUE) -    { -        LLVertexBuffer::unbind(); -    } -      if (sShaderLevel > 0)      {          sVertexProgram->unbind(); @@ -625,77 +408,17 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)          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; -    }  }  S32 LLDrawPoolAvatar::getNumPasses()  { -    LL_PROFILE_ZONE_SCOPED - -	if (LLPipeline::sImpostorRender) -	{ -		return 8; -	} -	else  -	{ -		return 10; -	} +    return 3;  }  S32 LLDrawPoolAvatar::getNumDeferredPasses()  { -    LL_PROFILE_ZONE_SCOPED - -	if (LLPipeline::sImpostorRender) -	{ -		return 19; -	} -	else -	{ -		return 21; -	} +    return 3;  } @@ -733,27 +456,6 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass)  	case 2:  		beginSkinned();  		break; -	case 3: -		beginRiggedSimple(); -		break; -	case 4: -		beginRiggedFullbright(); -		break; -	case 5: -		beginRiggedShinySimple(); -		break; -	case 6: -		beginRiggedFullbrightShiny(); -		break; -	case 7: -		beginRiggedAlpha(); -		break; -	case 8: -		beginRiggedFullbrightAlpha(); -		break; -	case 9: -		beginRiggedGlow(); -		break;  	}  	if (pass == 0) @@ -782,27 +484,6 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass)  	case 2:  		endSkinned();  		break; -	case 3: -		endRiggedSimple(); -		break; -	case 4: -		endRiggedFullbright(); -		break; -	case 5: -		endRiggedShinySimple(); -		break; -	case 6: -		endRiggedFullbrightShiny(); -		break; -	case 7: -		endRiggedAlpha(); -		break; -	case 8: -		endRiggedFullbrightAlpha(); -		break; -	case 9: -		endRiggedGlow(); -		break;  	}  } @@ -1037,462 +718,6 @@ void LLDrawPoolAvatar::endSkinned()  	gGL.getTexUnit(0)->activate();  } -void LLDrawPoolAvatar::beginRiggedSimple() -{ -    LL_PROFILE_ZONE_SCOPED - -	if (sShaderLevel > 0) -	{ -		if (LLPipeline::sUnderWaterRender) -		{ -			sVertexProgram = &gSkinnedObjectSimpleWaterProgram; -		} -		else -		{ -			sVertexProgram = &gSkinnedObjectSimpleProgram; -		} -	} -	else -	{ -		if (LLPipeline::sUnderWaterRender) -		{ -			sVertexProgram = &gObjectSimpleNonIndexedWaterProgram; -		} -		else -		{ -			sVertexProgram = &gObjectSimpleNonIndexedProgram; -		} -	} - -	if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) -	{ -		sDiffuseChannel = 0; -		sVertexProgram->bind(); -        if (LLPipeline::sRenderingHUDs) -	    { -		    sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); -	    } -	    else -	    { -		    sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); -	    } -	} -} - -void LLDrawPoolAvatar::endRiggedSimple() -{ -    LL_PROFILE_ZONE_SCOPED - -	LLVertexBuffer::unbind(); -	if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) -	{ -		sVertexProgram->unbind(); -		sVertexProgram = NULL; -	} -} - -void LLDrawPoolAvatar::beginRiggedAlpha() -{ -    LL_PROFILE_ZONE_SCOPED - -	beginRiggedSimple(); -} - -void LLDrawPoolAvatar::endRiggedAlpha() -{ -    LL_PROFILE_ZONE_SCOPED - -	endRiggedSimple(); -} - - -void LLDrawPoolAvatar::beginRiggedFullbrightAlpha() -{ -    LL_PROFILE_ZONE_SCOPED - -	beginRiggedFullbright(); -} - -void LLDrawPoolAvatar::endRiggedFullbrightAlpha() -{ -    LL_PROFILE_ZONE_SCOPED - -	endRiggedFullbright(); -} - -void LLDrawPoolAvatar::beginRiggedGlow() -{ -    LL_PROFILE_ZONE_SCOPED - -	if (sShaderLevel > 0) -	{ -		if (LLPipeline::sUnderWaterRender) -		{ -			sVertexProgram = &gSkinnedObjectEmissiveWaterProgram; -		} -		else -		{ -			sVertexProgram = &gSkinnedObjectEmissiveProgram; -		} -	} -	else -	{ -		if (LLPipeline::sUnderWaterRender) -		{ -			sVertexProgram = &gObjectEmissiveNonIndexedWaterProgram; -		} -		else -		{ -			sVertexProgram = &gObjectEmissiveNonIndexedProgram; -		} -	} - -	if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) -	{ -		sDiffuseChannel = 0; -		sVertexProgram->bind(); - -		sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, LLPipeline::sRenderDeferred ? 2.2f : 1.1f); - -        if (LLPipeline::sRenderingHUDs) -	    { -		    sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); -	    } -	    else -	    { -		    sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); -	    } - -		F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); -		sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); -	} -} - -void LLDrawPoolAvatar::endRiggedGlow() -{ -    LL_PROFILE_ZONE_SCOPED - -	endRiggedFullbright(); -} - -void LLDrawPoolAvatar::beginRiggedFullbright() -{ -    LL_PROFILE_ZONE_SCOPED - -	if (sShaderLevel > 0) -	{ -		if (LLPipeline::sUnderWaterRender) -		{ -			sVertexProgram = &gSkinnedObjectFullbrightWaterProgram; -		} -		else -		{ -			if (LLPipeline::sRenderDeferred) -			{ -				sVertexProgram = &gDeferredSkinnedFullbrightProgram; -			} -			else -			{ -				sVertexProgram = &gSkinnedObjectFullbrightProgram; -			} -		} -	} -	else -	{ -		if (LLPipeline::sUnderWaterRender) -		{ -			sVertexProgram = &gObjectFullbrightNonIndexedWaterProgram; -		} -		else -		{ -			sVertexProgram = &gObjectFullbrightNonIndexedProgram; -		} -	} - -	if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) -	{ -		sDiffuseChannel = 0; -		sVertexProgram->bind(); - -        if (LLPipeline::sRenderingHUDs) -        {             -            sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); -            sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); -        } -		else if (LLPipeline::sRenderDeferred) -		{ -            sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); -            sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); -			F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); -			sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); -		}  -		else  -		{ -            sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); -            sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); -		} -	} -} - -void LLDrawPoolAvatar::endRiggedFullbright() -{ -    LL_PROFILE_ZONE_SCOPED - -	LLVertexBuffer::unbind(); -	if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) -	{ -		sVertexProgram->unbind(); -		sVertexProgram = NULL; -	} -} - -void LLDrawPoolAvatar::beginRiggedShinySimple() -{ -    LL_PROFILE_ZONE_SCOPED - -	if (sShaderLevel > 0) -	{ -		if (LLPipeline::sUnderWaterRender) -		{ -			sVertexProgram = &gSkinnedObjectShinySimpleWaterProgram; -		} -		else -		{ -			sVertexProgram = &gSkinnedObjectShinySimpleProgram; -		} -	} -	else -	{ -		if (LLPipeline::sUnderWaterRender) -		{ -			sVertexProgram = &gObjectShinyNonIndexedWaterProgram; -		} -		else -		{ -			sVertexProgram = &gObjectShinyNonIndexedProgram; -		} -	} - -	if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) -	{ -		sVertexProgram->bind(); -        if (LLPipeline::sRenderingHUDs) -	    { -		    sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); -	    } -	    else -	    { -		    sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); -	    } -		LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false); -	} -} - -void LLDrawPoolAvatar::endRiggedShinySimple() -{ -    LL_PROFILE_ZONE_SCOPED - -	LLVertexBuffer::unbind(); -	if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) -	{ -		LLDrawPoolBump::unbindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false); -		sVertexProgram->unbind(); -		sVertexProgram = NULL; -	} -} - -void LLDrawPoolAvatar::beginRiggedFullbrightShiny() -{ -    LL_PROFILE_ZONE_SCOPED - -	if (sShaderLevel > 0) -	{ -		if (LLPipeline::sUnderWaterRender) -		{ -			sVertexProgram = &gSkinnedObjectFullbrightShinyWaterProgram; -		} -		else -		{ -			if (LLPipeline::sRenderDeferred) -			{ -				sVertexProgram = &gDeferredSkinnedFullbrightShinyProgram; -			} -			else -			{ -				sVertexProgram = &gSkinnedObjectFullbrightShinyProgram; -			} -		} -	} -	else -	{ -		if (LLPipeline::sUnderWaterRender) -		{ -			sVertexProgram = &gObjectFullbrightShinyNonIndexedWaterProgram; -		} -		else -		{ -			sVertexProgram = &gObjectFullbrightShinyNonIndexedProgram; -		} -	} - -	if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) -	{ -		sVertexProgram->bind(); -        if (LLPipeline::sRenderingHUDs) -	    { -		    sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); -	    } -	    else -	    { -		    sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); -	    } -		LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false); - -        if (LLPipeline::sRenderingHUDs) -		{ -			sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); -            sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); -        } -		else if (LLPipeline::sRenderDeferred) -		{ -            sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); -			F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); -			sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); -            sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); -        } -        else -        { -			sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); -            sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); -		} -	} -} - -void LLDrawPoolAvatar::endRiggedFullbrightShiny() -{ -    LL_PROFILE_ZONE_SCOPED - -	LLVertexBuffer::unbind(); -	if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) -	{ -		LLDrawPoolBump::unbindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false); -		sVertexProgram->unbind(); -		sVertexProgram = NULL; -	} -} - - -void LLDrawPoolAvatar::beginDeferredRiggedSimple() -{ -    LL_PROFILE_ZONE_SCOPED - -	sVertexProgram = &gDeferredSkinnedDiffuseProgram; -	sDiffuseChannel = 0; -	sVertexProgram->bind(); -    if (LLPipeline::sRenderingHUDs) -	{ -		sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); -	} -	else -	{ -		sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); -	} -} - -void LLDrawPoolAvatar::endDeferredRiggedSimple() -{ -    LL_PROFILE_ZONE_SCOPED - -	LLVertexBuffer::unbind(); -	sVertexProgram->unbind(); -	sVertexProgram = NULL; -} - -void LLDrawPoolAvatar::beginDeferredRiggedBump() -{ -    LL_PROFILE_ZONE_SCOPED - -	sVertexProgram = &gDeferredSkinnedBumpProgram; -	sVertexProgram->bind(); -    if (LLPipeline::sRenderingHUDs) -	{ -		sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); -	} -	else -	{ -		sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); -	} -	normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP); -	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); -} - -void LLDrawPoolAvatar::endDeferredRiggedBump() -{ -    LL_PROFILE_ZONE_SCOPED - -	LLVertexBuffer::unbind(); -	sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP); -	sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); -	sVertexProgram->unbind(); -	normal_channel = -1; -	sDiffuseChannel = 0; -	sVertexProgram = NULL; -} - -void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass) -{ -    LL_PROFILE_ZONE_SCOPED - -	if (pass == 1 || -		pass == 5 || -		pass == 9 || -		pass == 13) -	{ //skip alpha passes -		return; -	} -	sVertexProgram = &gDeferredMaterialProgram[pass+LLMaterial::SHADER_COUNT]; - -	if (LLPipeline::sUnderWaterRender) -	{ -		sVertexProgram = &(gDeferredMaterialWaterProgram[pass+LLMaterial::SHADER_COUNT]); -	} - -	sVertexProgram->bind(); -    if (LLPipeline::sRenderingHUDs) -	{ -		sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1); -	} -	else -	{ -		sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0); -	} -	normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP); -	specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP); -	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); -} - -void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass) -{ -    LL_PROFILE_ZONE_SCOPED - -	if (pass == 1 || -		pass == 5 || -		pass == 9 || -		pass == 13) -	{ -		return; -	} - -	LLVertexBuffer::unbind(); -	sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP); -	sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP); -	sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); -	sVertexProgram->unbind(); -	normal_channel = -1; -	sDiffuseChannel = 0; -	sVertexProgram = NULL; -} -  void LLDrawPoolAvatar::beginDeferredSkinned()  {      LL_PROFILE_ZONE_SCOPED @@ -1654,142 +879,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  		return;  	} -	if (pass == 3) -	{ -		if (is_deferred_render) -		{ -			renderDeferredRiggedSimple(avatarp); -		} -		else -		{ -			renderRiggedSimple(avatarp); - -			if (LLPipeline::sRenderDeferred) -			{ //render "simple" materials -				renderRigged(avatarp, RIGGED_MATERIAL); -				renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_MASK); -				renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE); -				renderRigged(avatarp, RIGGED_NORMMAP); -				renderRigged(avatarp, RIGGED_NORMMAP_MASK); -				renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE); -				renderRigged(avatarp, RIGGED_SPECMAP); -				renderRigged(avatarp, RIGGED_SPECMAP_MASK); -				renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE); -				renderRigged(avatarp, RIGGED_NORMSPEC); -				renderRigged(avatarp, RIGGED_NORMSPEC_MASK); -				renderRigged(avatarp, RIGGED_NORMSPEC_EMISSIVE); -			} -		} -		return; -	} - -	if (pass == 4) -	{ -		if (is_deferred_render) -		{ -			renderDeferredRiggedBump(avatarp); -		} -		else -		{ -			renderRiggedFullbright(avatarp); -		} - -		return; -	} - -	if (is_deferred_render && pass >= 5 && pass <= 21) -	{ -		S32 p = pass-5; - -		if (p != 1 && -			p != 5 && -			p != 9 && -			p != 13) -		{ -			renderDeferredRiggedMaterial(avatarp, p); -		} -		return; -	} - - - - -	if (pass == 5) -	{ -		renderRiggedShinySimple(avatarp); -				 -		return; -	} - -	if (pass == 6) -	{ -		renderRiggedFullbrightShiny(avatarp); -		return; -	} - -	if (pass >= 7 && pass < 13) -	{ -		if (pass == 7) -		{ -			renderRiggedAlpha(avatarp); - -			if (LLPipeline::sRenderDeferred && !is_post_deferred_render) -			{ //render transparent materials under water -				LLGLEnable blend(GL_BLEND); - -				gGL.setColorMask(true, true); -				gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, -								LLRender::BF_ONE_MINUS_SOURCE_ALPHA, -								LLRender::BF_ZERO, -								LLRender::BF_ONE_MINUS_SOURCE_ALPHA); - -				renderRigged(avatarp, RIGGED_MATERIAL_ALPHA); -				renderRigged(avatarp, RIGGED_SPECMAP_BLEND); -				renderRigged(avatarp, RIGGED_NORMMAP_BLEND); -				renderRigged(avatarp, RIGGED_NORMSPEC_BLEND); - -				gGL.setColorMask(true, false); -			} -			return; -		} - -		if (pass == 8) -		{ -			renderRiggedFullbrightAlpha(avatarp); -			return; -		} - -		if (LLPipeline::sRenderDeferred && is_post_deferred_render) -		{ -			S32 p = 0; -			switch (pass) -			{ -			case 9: p = 1; break; -			case 10: p = 5; break; -			case 11: p = 9; break; -			case 12: p = 13; break; -			} - -			{ -				LLGLEnable blend(GL_BLEND); -				renderDeferredRiggedMaterial(avatarp, p); -			} -			return; -		} -		else if (pass == 9) -		{ -			renderRiggedGlow(avatarp); -			return; -		} -	} - -	if (pass == 13) -	{ -		renderRiggedGlow(avatarp); -		 -		return; -	} -	  	if ((sShaderLevel >= SHADER_LEVEL_CLOTH))  	{  		LLMatrix4 rot_mat; @@ -1821,776 +910,8 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  	}  } -void LLDrawPoolAvatar::getRiggedGeometry( -    LLFace* face, -    LLPointer<LLVertexBuffer>& buffer, -    U32 data_mask, -    const LLMeshSkinInfo* skin, -    LLVolume* volume, -    const LLVolumeFace& vol_face) -{ -    LL_PROFILE_ZONE_SCOPED - -    face->setGeomIndex(0); -    face->setIndicesIndex(0); - -    if (face->getTextureIndex() != FACE_DO_NOT_BATCH_TEXTURES) -    { -        face->setDrawInfo(NULL); -    } - -    //rigged faces do not batch textures -    face->setTextureIndex(FACE_DO_NOT_BATCH_TEXTURES); - -	if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable()) -	{ -        // make a new buffer -		if (sShaderLevel > 0) -		{ -			buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB); -		} -		else -		{ -			buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB); -		} - -		if (!buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true)) -		{ -			LL_WARNS("LLDrawPoolAvatar") << "Failed to allocate Vertex Buffer to " -				<< vol_face.mNumVertices << " vertices and " -				<< vol_face.mNumIndices << " indices" << LL_ENDL; -			// allocate dummy triangle -			buffer->allocateBuffer(1, 3, true); -			memset((U8*)buffer->getMappedData(), 0, buffer->getSize()); -			memset((U8*)buffer->getMappedIndices(), 0, buffer->getIndicesSize()); -		} -	} -	else -	{ -        //resize existing buffer -		if(!buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices)) -		{ -			LL_WARNS("LLDrawPoolAvatar") << "Failed to resize Vertex Buffer to " -				<< vol_face.mNumVertices << " vertices and " -				<< vol_face.mNumIndices << " indices" << LL_ENDL; -			// allocate dummy triangle -			buffer->resizeBuffer(1, 3); -			memset((U8*)buffer->getMappedData(), 0, buffer->getSize()); -			memset((U8*)buffer->getMappedIndices(), 0, buffer->getIndicesSize()); -		} -	} - -	face->setSize(buffer->getNumVerts(), buffer->getNumIndices()); -	face->setVertexBuffer(buffer); - -	U16 offset = 0; -		 -	LLMatrix4 mat_vert = LLMatrix4(skin->mBindShapeMatrix); -	glh::matrix4f m((F32*) mat_vert.mMatrix); -	m = m.inverse().transpose(); -		 -	F32 mat3[] =  -        { m.m[0], m.m[1], m.m[2], -          m.m[4], m.m[5], m.m[6], -          m.m[8], m.m[9], m.m[10] }; - -	LLMatrix3 mat_normal(mat3);				 - -	//let getGeometryVolume know if alpha should override shiny -	U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture()); - -	if (type == LLDrawPool::POOL_ALPHA) -	{ -		face->setPoolType(LLDrawPool::POOL_ALPHA); -	} -	else -	{ -		face->setPoolType(mType); // either POOL_AVATAR or POOL_CONTROL_AV -	} - -	//LL_INFOS() << "Rebuilt face " << face->getTEOffset() << " of " << face->getDrawable() << " at " << gFrameTimeSeconds << LL_ENDL; - -	// Let getGeometryVolume know if a texture matrix is in play -	if (face->mTextureMatrix) -	{ -		face->setState(LLFace::TEXTURE_ANIM); -	} -	else -	{ -		face->clearState(LLFace::TEXTURE_ANIM); -	} -	face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true); - -	buffer->flush(); -} - -void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( -    LLVOAvatar* avatar, -    LLFace* face, -    const LLVOVolume* vobj, -    LLVolume* volume, -    LLVolumeFace& vol_face) -{ -    LL_PROFILE_ZONE_SCOPED; - -	LLVector4a* weights = vol_face.mWeights; -	if (!weights) -	{ -		return; -	} - -    if (!vobj || vobj->isNoLOD()) -    { -        return; -    } - -	LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer(); -	LLDrawable* drawable = face->getDrawable(); - -    const U32 max_joints = LLSkinningUtil::getMaxJointCount(); - -#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS -    #define CONDITION_WEIGHT(f) ((U8)llclamp((S32)f, (S32)0, (S32)max_joints-1)) -    LLVector4a* just_weights = vol_face.mJustWeights; -    // we need to calculate the separated indices and store just the matrix weights for this vol... -    if (!vol_face.mJointIndices) -    { -        // not very consty after all... -        vol_face.allocateJointIndices(vol_face.mNumVertices); -        just_weights = vol_face.mJustWeights; - -        U8* joint_indices_cursor = vol_face.mJointIndices; -        for (int i = 0; i < vol_face.mNumVertices; i++) -        { -            F32* w = weights[i].getF32ptr(); -            F32* w_ = just_weights[i].getF32ptr(); - -            F32 w0 = floorf(w[0]); -            F32 w1 = floorf(w[1]); -            F32 w2 = floorf(w[2]); -            F32 w3 = floorf(w[3]); - -            joint_indices_cursor[0] = CONDITION_WEIGHT(w0); -            joint_indices_cursor[1] = CONDITION_WEIGHT(w1); -            joint_indices_cursor[2] = CONDITION_WEIGHT(w2); -            joint_indices_cursor[3] = CONDITION_WEIGHT(w3); - -            // remove joint portion of combined weight -            w_[0] = w[0] - w0; -            w_[1] = w[1] - w1; -            w_[2] = w[2] - w2; -            w_[3] = w[3] - w3; - -            joint_indices_cursor += 4; -        } -    } -#endif - -    U32 data_mask = face->getRiggedVertexBufferDataMask(); -    const LLMeshSkinInfo* skin = nullptr; - -	if (buffer.isNull() ||  -		buffer->getTypeMask() != data_mask || -		buffer->getNumVerts() != vol_face.mNumVertices || -		buffer->getNumIndices() != vol_face.mNumIndices || -		(drawable && drawable->isState(LLDrawable::REBUILD_ALL))) -	{ -        LL_PROFILE_ZONE_NAMED("Rigged VBO Rebuild"); -        skin = vobj->getSkinInfo(); -        // FIXME ugly const cast -        LLSkinningUtil::scrubInvalidJoints(avatar, const_cast<LLMeshSkinInfo*>(skin)); - -        if (!vol_face.mWeightsScrubbed) -        { -            LLSkinningUtil::scrubSkinWeights(weights, vol_face.mNumVertices, skin); -            vol_face.mWeightsScrubbed = TRUE; -        } - -		if (drawable && drawable->isState(LLDrawable::REBUILD_ALL)) -		{ -            //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues -			for (S32 i = 0; i < drawable->getNumFaces(); ++i) -			{ -				LLFace* facep = drawable->getFace(i); -				U32 face_data_mask = facep->getRiggedVertexBufferDataMask(); -				if (face_data_mask) -				{ -					LLPointer<LLVertexBuffer> cur_buffer = facep->getVertexBuffer(); -					const LLVolumeFace& cur_vol_face = volume->getVolumeFace(i); -					getRiggedGeometry(facep, cur_buffer, face_data_mask, skin, volume, cur_vol_face); -				} -			} -			drawable->clearState(LLDrawable::REBUILD_ALL); - -			buffer = face->getVertexBuffer(); -		} -		else -		{ -			//just rebuild this face -			getRiggedGeometry(face, buffer, data_mask, skin, volume, vol_face); -		} -	} - -	if (sShaderLevel <= 0 &&  -        face->mLastSkinTime < avatar->getLastSkinTime() && -        !buffer.isNull() && -        buffer->getNumVerts() == vol_face.mNumVertices && -        buffer->getNumIndices() == vol_face.mNumIndices) -	{ -        LL_PROFILE_ZONE_NAMED("Software Skinning"); -		//perform software vertex skinning for this face -		LLStrider<LLVector3> position; -		LLStrider<LLVector3> normal; - -		bool has_normal = buffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); -		buffer->getVertexStrider(position); - -		if (has_normal) -		{ -			buffer->getNormalStrider(normal); -		} - -		LLVector4a* pos = (LLVector4a*) position.get(); - -		LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL; - -        const MatrixPaletteCache& mpc = updateSkinInfoMatrixPalette(avatar, vobj->getMeshID()); -        const LLMatrix4a* mat = &(mpc.mMatrixPalette[0]); -        const LLMatrix4a& bind_shape_matrix = mpc.mBindShapeMatrix; - -        if (!mpc.mMatrixPalette.empty()) -        { -            for (U32 j = 0; j < buffer->getNumVerts(); ++j) -		    { -			    LLMatrix4a final_mat; -                LLSkinningUtil::getPerVertexSkinMatrix(weights[j].getF32ptr(), mat, false, final_mat, max_joints); - -			    LLVector4a& v = vol_face.mPositions[j]; -			    LLVector4a t; -			    LLVector4a dst; -			    bind_shape_matrix.affineTransform(v, t); -			    final_mat.affineTransform(t, dst); -			    pos[j] = dst; - -			    if (norm) -			    { -				    LLVector4a& n = vol_face.mNormals[j]; -				    bind_shape_matrix.rotate(n, t); -				    final_mat.rotate(t, dst); -				    //dst.normalize3fast(); -				    norm[j] = dst; -			    } -		    } -        } -	} -} - -void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) -{ -    LL_PROFILE_ZONE_SCOPED - -	if (!avatar->shouldRenderRigged()) -	{ -		return; -	} - -    LLUUID lastMeshId; - -	for (U32 i = 0; i < mRiggedFace[type].size(); ++i) -	{ -        LL_PROFILE_ZONE_NAMED("Render Rigged Face"); -		LLFace* face = mRiggedFace[type][i]; - -        S32 offset = face->getIndicesStart(); -		U32 count = face->getIndicesCount(); - -        U16 start = face->getGeomStart(); -		U16 end = start + face->getGeomCount()-1; - -		LLDrawable* drawable = face->getDrawable(); -		if (!drawable) -		{ -			continue; -		} - -		LLVOVolume* vobj = drawable->getVOVolume(); - -		if (!vobj) -		{ -			continue; -		} - -		LLVolume* volume = vobj->getVolume(); -		S32 te = face->getTEOffset(); - -		if (!volume || volume->getNumVolumeFaces() <= te || !volume->isMeshAssetLoaded()) -		{ -			continue; -		} - -		U32 data_mask = LLFace::getRiggedDataMask(type); - -		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; - -            LLViewerTexture* tex = face->getTexture(LLRender::DIFFUSE_MAP); -            if (tex) -            { -                if (tex->getIsAlphaMask()) -                { -                    is_alpha_mask = true; -                } -            } - -            if (tex) -            { -                LLGLenum image_format = tex->getPrimaryFormat(); -                if (!is_alpha_mask && (image_format == GL_RGBA || image_format == GL_ALPHA)) -                { -                    is_alpha_blend = true; -                } -            } - -            if (tex_entry) -            { -                if (tex_entry->getAlpha() <= 0.99f) -                { -                    is_alpha_blend = true; -                } -            } - -            if (mat) -            {                 -                switch (LLMaterial::eDiffuseAlphaMode(mat->getDiffuseAlphaMode())) -                { -                    case LLMaterial::DIFFUSE_ALPHA_MODE_MASK: -                    { -                        is_alpha_mask  = true; -                        is_alpha_blend = false; -                    } -                    break; - -                    case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND: -                    { -                        is_alpha_blend = true; -                        is_alpha_mask  = false; -                    } -                    break; - -                    case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE: -                    case LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT: -                    case LLMaterial::DIFFUSE_ALPHA_MODE_NONE: -                    default: -                        is_alpha_blend = false; -                        is_alpha_mask  = false; -                        break; -                } -            } - -            // 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) -			{ -                auto& meshId = vobj->getMeshID(); -                 -                if (lastMeshId != meshId) // <== only upload matrix palette to GL if the skininfo changed -                { -                    // upload matrix palette to shader -                    const MatrixPaletteCache& mpc = updateSkinInfoMatrixPalette(avatar, meshId); -                    U32 count = mpc.mMatrixPalette.size(); - -                    if (count == 0) -                    { -                        //skin info not loaded yet, don't render -                        continue; -                    } - -                    LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, -                        count, -                        FALSE, -                        (GLfloat*) &(mpc.mGLMp[0])); -                } - -                lastMeshId = meshId; -			} -			else -			{ -				data_mask &= ~LLVertexBuffer::MAP_WEIGHT4; -			} - -			if (mat) -			{ -				//order is important here LLRender::DIFFUSE_MAP should be last, becouse it change  -				//(gGL).mCurrTextureUnitIndex -                LLViewerTexture* specular = NULL; -                if (LLPipeline::sImpostorRender) -                { -                    specular = LLViewerTextureManager::findFetchedTexture(gBlackSquareID, TEX_LIST_STANDARD); -                    llassert(NULL != specular); -                } -                else -                { -                    specular = face->getTexture(LLRender::SPECULAR_MAP); -                } -                if (specular && specular_channel >= 0) -                { -                    gGL.getTexUnit(specular_channel)->bindFast(specular); -                } -                 -                if (normal_channel >= 0) -                { -                    auto* texture = face->getTexture(LLRender::NORMAL_MAP); -                    if (texture) -                    { -                        gGL.getTexUnit(normal_channel)->bindFast(texture); -                    } -                    //else -                    //{ -                        // TODO handle missing normal map -                    //} -                } - -				gGL.getTexUnit(sDiffuseChannel)->bindFast(face->getTexture(LLRender::DIFFUSE_MAP)); - - -				LLColor4 col = mat->getSpecularLightColor(); -				F32 spec = mat->getSpecularLightExponent()/255.f; - -				F32 env = mat->getEnvironmentIntensity()/255.f; - -				if (mat->getSpecularID().isNull()) -				{ -					env = tex_entry->getShiny()*0.25f; -					col.set(env,env,env,0); -					spec = env; -				} -		 -				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); -				sVertexProgram->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env); - -				if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) -				{ -                    F32 cutoff = mat->getAlphaMaskCutoff()/255.f; -					sVertexProgram->setMinimumAlpha(cutoff); -				} -				else -				{ -					sVertexProgram->setMinimumAlpha(0.f); -				} - -                if (!LLPipeline::sShadowRender && !LLPipeline::sReflectionRender) -                { -                    for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) -                    { -                        LLViewerTexture* tex = face->getTexture(i); -                        if (tex) -                        { -                            tex->addTextureStats(avatar->getPixelArea()); -                        } -                    } -                } -			} -			else -			{ -				sVertexProgram->setMinimumAlpha(0.f); -				if (normal_channel > -1) -				{ -					LLDrawPoolBump::bindBumpMap(face, normal_channel); -				} - -                gGL.getTexUnit(sDiffuseChannel)->bindFast(face->getTexture()); - -			} - -			if (face->mTextureMatrix && vobj->mTexAnimMode) -			{ -                U32 tex_index = gGL.getCurrentTexUnitIndex(); - -                if (tex_index <= 1) -                { -                    gGL.matrixMode(LLRender::eMatrixMode(LLRender::MM_TEXTURE0 + tex_index)); -                    gGL.pushMatrix(); -				    gGL.loadMatrix((F32*) face->mTextureMatrix->mMatrix); -                } - -				buff->setBufferFast(data_mask); -				buff->drawRangeFast(LLRender::TRIANGLES, start, end, count, offset); - -                if (tex_index <= 1) -                { -                    gGL.matrixMode(LLRender::eMatrixMode(LLRender::MM_TEXTURE0 + tex_index)); -				    gGL.popMatrix(); -                    gGL.matrixMode(LLRender::MM_MODELVIEW); -                } -			} -			else -			{ -				buff->setBufferFast(data_mask); -				buff->drawRangeFast(LLRender::TRIANGLES, start, end, count, offset); -			} -		} -	} -} - -void LLDrawPoolAvatar::renderDeferredRiggedSimple(LLVOAvatar* avatar) -{ -    LL_PROFILE_ZONE_SCOPED - -	renderRigged(avatar, RIGGED_DEFERRED_SIMPLE); -} - -void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar) -{ -    LL_PROFILE_ZONE_SCOPED - -	renderRigged(avatar, RIGGED_DEFERRED_BUMP); -} - -void LLDrawPoolAvatar::renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass) -{ -    LL_PROFILE_ZONE_SCOPED - -	renderRigged(avatar, pass); -} -  static LLTrace::BlockTimerStatHandle FTM_RIGGED_VBO("Rigged VBO"); -void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar) -{ -	LL_RECORD_BLOCK_TIME(FTM_RIGGED_VBO); - -	//update rigged vertex buffers -	for (U32 type = 0; type < NUM_RIGGED_PASSES; ++type) -	{ -        LL_PROFILE_ZONE_NAMED("Pass"); -		for (U32 i = 0; i < mRiggedFace[type].size(); ++i) -		{ -            LL_PROFILE_ZONE_NAMED("Face"); -			LLFace* face = mRiggedFace[type][i]; -			LLDrawable* drawable = face->getDrawable(); -			if (!drawable) -			{ -				continue; -			} - -			LLVOVolume* vobj = drawable->getVOVolume(); - -			if (!vobj || vobj->isNoLOD()) -			{ -				continue; -			} - -			LLVolume* volume = vobj->getVolume(); -			S32 te = face->getTEOffset(); - -			if (!volume || volume->getNumVolumeFaces() <= te) -			{ -				continue; -			} - -			LLVolumeFace& vol_face = volume->getVolumeFace(te); -			updateRiggedFaceVertexBuffer(avatar, face, vobj, volume, vol_face); -		} -	} -} - -void LLDrawPoolAvatar::updateSkinInfoMatrixPalettes(LLVOAvatar* avatarp) -{ -    LL_PROFILE_ZONE_SCOPED; -    //evict matrix palettes from the cache that haven't been updated in 10 frames -    for (matrix_palette_cache_t::iterator iter = mMatrixPaletteCache.begin(); iter != mMatrixPaletteCache.end(); ) -    { -        if (gFrameCount - iter->second.mFrame > 10) -        { -            iter = mMatrixPaletteCache.erase(iter); -        } -        else -        { -            ++iter; -        } -    } -} - -const LLDrawPoolAvatar::MatrixPaletteCache& LLDrawPoolAvatar::updateSkinInfoMatrixPalette(LLVOAvatar * avatarp, const LLUUID& meshId) -{ -    MatrixPaletteCache& entry = mMatrixPaletteCache[meshId]; - -    if (entry.mFrame != gFrameCount) -    { -        LL_PROFILE_ZONE_SCOPED; - -        const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(meshId); -        entry.mFrame = gFrameCount; - -        if (skin != nullptr) -        { -            entry.mBindShapeMatrix = skin->mBindShapeMatrix; - -            //build matrix palette -            U32 count = LLSkinningUtil::getMeshJointCount(skin); -            entry.mMatrixPalette.resize(count); -            LLSkinningUtil::initSkinningMatrixPalette(&(entry.mMatrixPalette[0]), count, skin, avatarp); - -            const LLMatrix4a* mat = &(entry.mMatrixPalette[0]); - -            entry.mGLMp.resize(count * 12); - -            F32* mp = &(entry.mGLMp[0]); - -            for (U32 i = 0; i < count; ++i) -            { -                F32* m = (F32*)mat[i].mMatrix[0].getF32ptr(); - -                U32 idx = i * 12; - -                mp[idx + 0] = m[0]; -                mp[idx + 1] = m[1]; -                mp[idx + 2] = m[2]; -                mp[idx + 3] = m[12]; - -                mp[idx + 4] = m[4]; -                mp[idx + 5] = m[5]; -                mp[idx + 6] = m[6]; -                mp[idx + 7] = m[13]; - -                mp[idx + 8] = m[8]; -                mp[idx + 9] = m[9]; -                mp[idx + 10] = m[10]; -                mp[idx + 11] = m[14]; -            } -        } -        else -        { -            entry.mMatrixPalette.resize(0); -            entry.mGLMp.resize(0); -        } -    } - -    return entry; -} - -void LLDrawPoolAvatar::renderRiggedSimple(LLVOAvatar* avatar) -{ -    LL_PROFILE_ZONE_SCOPED - -	renderRigged(avatar, RIGGED_SIMPLE); -} - -void LLDrawPoolAvatar::renderRiggedFullbright(LLVOAvatar* avatar) -{ -    LL_PROFILE_ZONE_SCOPED - -	renderRigged(avatar, RIGGED_FULLBRIGHT); -} - -	 -void LLDrawPoolAvatar::renderRiggedShinySimple(LLVOAvatar* avatar) -{ -    LL_PROFILE_ZONE_SCOPED - -	renderRigged(avatar, RIGGED_SHINY); -} - -void LLDrawPoolAvatar::renderRiggedFullbrightShiny(LLVOAvatar* avatar) -{ -    LL_PROFILE_ZONE_SCOPED - -	renderRigged(avatar, RIGGED_FULLBRIGHT_SHINY); -} - -void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar) -{ -    LL_PROFILE_ZONE_SCOPED - -	if (!mRiggedFace[RIGGED_ALPHA].empty()) -	{ -		LLGLEnable blend(GL_BLEND); - -		gGL.setColorMask(true, true); -		gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, -						LLRender::BF_ONE_MINUS_SOURCE_ALPHA, -						LLRender::BF_ZERO, -						LLRender::BF_ONE_MINUS_SOURCE_ALPHA); - -		renderRigged(avatar, RIGGED_ALPHA); -		gGL.setColorMask(true, false); -	} -} - -void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar) -{ -    LL_PROFILE_ZONE_SCOPED - -	if (!mRiggedFace[RIGGED_FULLBRIGHT_ALPHA].empty()) -	{ -		LLGLEnable blend(GL_BLEND); - -		gGL.setColorMask(true, true); -		gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, -						LLRender::BF_ONE_MINUS_SOURCE_ALPHA, -						LLRender::BF_ZERO, -						LLRender::BF_ONE_MINUS_SOURCE_ALPHA); - -		renderRigged(avatar, RIGGED_FULLBRIGHT_ALPHA); -		gGL.setColorMask(true, false); -	} -} - -void LLDrawPoolAvatar::renderRiggedGlow(LLVOAvatar* avatar) -{ -    LL_PROFILE_ZONE_SCOPED - -	if (!mRiggedFace[RIGGED_GLOW].empty()) -	{ -		LLGLEnable blend(GL_BLEND); -		LLGLDisable test(GL_ALPHA_TEST); -		gGL.flush(); - -		LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); -		glPolygonOffset(-1.0f, -1.0f); -		gGL.setSceneBlendType(LLRender::BT_ADD); - -		LLGLDepthTest depth(GL_TRUE, GL_FALSE); -		gGL.setColorMask(false, true); - -		renderRigged(avatar, RIGGED_GLOW, true); - -		gGL.setColorMask(true, false); -		gGL.setSceneBlendType(LLRender::BT_ALPHA); -	} -} - - -  //-----------------------------------------------------------------------------  // getDebugTexture()  //----------------------------------------------------------------------------- @@ -2619,66 +940,6 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const  	return LLColor3(0.f, 1.f, 0.f);  } -void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type) -{ -    LL_PROFILE_ZONE_SCOPED - -    llassert (facep->isState(LLFace::RIGGED)); -    llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV); -    if (facep->getPool() && facep->getPool() != this) -    { -        LL_ERRS() << "adding rigged face that's already in another pool" << LL_ENDL; -    } -	if (type >= NUM_RIGGED_PASSES) -	{ -		LL_ERRS() << "Invalid rigged face type." << LL_ENDL; -	} -	if (facep->getRiggedIndex(type) != -1) -	{ -		LL_ERRS() << "Tried to add a rigged face that's referenced elsewhere." << LL_ENDL; -	}	 -	 -	facep->setRiggedIndex(type, mRiggedFace[type].size()); -	facep->setPool(this); -	mRiggedFace[type].push_back(facep); -} - -void LLDrawPoolAvatar::removeRiggedFace(LLFace* facep) -{ -    LL_PROFILE_ZONE_SCOPED - -    llassert (facep->isState(LLFace::RIGGED)); -    llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV); -    if (facep->getPool() != this) -    { -        LL_ERRS() << "Tried to remove a rigged face from the wrong pool" << LL_ENDL; -    } -	facep->setPool(NULL); - -	for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i) -	{ -		S32 index = facep->getRiggedIndex(i); -		 -		if (index > -1) -		{ -			if (mRiggedFace[i].size() > index && mRiggedFace[i][index] == facep) -			{ -				facep->setRiggedIndex(i,-1); -				mRiggedFace[i].erase(mRiggedFace[i].begin()+index); -				for (U32 j = index; j < mRiggedFace[i].size(); ++j) -				{ //bump indexes down for faces referenced after erased face -					mRiggedFace[i][j]->setRiggedIndex(i, j); -				} -			} -			else -			{ -				LL_ERRS() << "Face reference data corrupt for rigged type " << i -					<< ((mRiggedFace[i].size() <= index) ? "; wrong index (out of bounds)" : (mRiggedFace[i][index] != facep) ? "; wrong face pointer" : "") -					<< LL_ENDL; -			} -		} -	} -}  LLVertexBufferAvatar::LLVertexBufferAvatar()  : LLVertexBuffer(sDataMask,  diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 800bbc5f62..21add39b21 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -62,119 +62,11 @@ public:      ~LLDrawPoolAvatar();      /*virtual*/ BOOL isDead(); -    typedef enum -	{ -		RIGGED_MATERIAL=0, -		RIGGED_MATERIAL_ALPHA, -		RIGGED_MATERIAL_ALPHA_MASK, -		RIGGED_MATERIAL_ALPHA_EMISSIVE, -		RIGGED_SPECMAP, -		RIGGED_SPECMAP_BLEND, -		RIGGED_SPECMAP_MASK, -		RIGGED_SPECMAP_EMISSIVE, -		RIGGED_NORMMAP, -		RIGGED_NORMMAP_BLEND, -		RIGGED_NORMMAP_MASK, -		RIGGED_NORMMAP_EMISSIVE, -		RIGGED_NORMSPEC, -		RIGGED_NORMSPEC_BLEND, -		RIGGED_NORMSPEC_MASK, -		RIGGED_NORMSPEC_EMISSIVE, -		RIGGED_SIMPLE, -		RIGGED_FULLBRIGHT, -		RIGGED_SHINY, -		RIGGED_FULLBRIGHT_SHINY, -		RIGGED_GLOW, -		RIGGED_ALPHA, -		RIGGED_FULLBRIGHT_ALPHA, -		RIGGED_DEFERRED_BUMP, -		RIGGED_DEFERRED_SIMPLE, -		NUM_RIGGED_PASSES, -		RIGGED_UNKNOWN, -	} eRiggedPass; - -	typedef enum -	{ -		RIGGED_MATERIAL_MASK = -						LLVertexBuffer::MAP_VERTEX |  -						LLVertexBuffer::MAP_NORMAL |  -						LLVertexBuffer::MAP_TEXCOORD0 | -						LLVertexBuffer::MAP_COLOR | -						LLVertexBuffer::MAP_WEIGHT4, -		RIGGED_MATERIAL_ALPHA_VMASK = RIGGED_MATERIAL_MASK, -		RIGGED_MATERIAL_ALPHA_MASK_MASK = RIGGED_MATERIAL_MASK, -		RIGGED_MATERIAL_ALPHA_EMISSIVE_MASK = RIGGED_MATERIAL_MASK, -		RIGGED_SPECMAP_VMASK = -						LLVertexBuffer::MAP_VERTEX |  -						LLVertexBuffer::MAP_NORMAL |  -						LLVertexBuffer::MAP_TEXCOORD0 | -						LLVertexBuffer::MAP_TEXCOORD2 | -						LLVertexBuffer::MAP_COLOR | -						LLVertexBuffer::MAP_WEIGHT4, -		RIGGED_SPECMAP_BLEND_MASK = RIGGED_SPECMAP_VMASK, -		RIGGED_SPECMAP_MASK_MASK = RIGGED_SPECMAP_VMASK, -		RIGGED_SPECMAP_EMISSIVE_MASK = RIGGED_SPECMAP_VMASK, -		RIGGED_NORMMAP_VMASK = -						LLVertexBuffer::MAP_VERTEX |  -						LLVertexBuffer::MAP_NORMAL |  -						LLVertexBuffer::MAP_TANGENT |  -						LLVertexBuffer::MAP_TEXCOORD0 | -						LLVertexBuffer::MAP_TEXCOORD1 | -						LLVertexBuffer::MAP_COLOR | -						LLVertexBuffer::MAP_WEIGHT4, -		RIGGED_NORMMAP_BLEND_MASK = RIGGED_NORMMAP_VMASK, -		RIGGED_NORMMAP_MASK_MASK = RIGGED_NORMMAP_VMASK, -		RIGGED_NORMMAP_EMISSIVE_MASK = RIGGED_NORMMAP_VMASK, -		RIGGED_NORMSPEC_VMASK = -						LLVertexBuffer::MAP_VERTEX |  -						LLVertexBuffer::MAP_NORMAL |  -						LLVertexBuffer::MAP_TANGENT |  -						LLVertexBuffer::MAP_TEXCOORD0 | -						LLVertexBuffer::MAP_TEXCOORD1 | -						LLVertexBuffer::MAP_TEXCOORD2 | -						LLVertexBuffer::MAP_COLOR | -						LLVertexBuffer::MAP_WEIGHT4, -		RIGGED_NORMSPEC_BLEND_MASK = RIGGED_NORMSPEC_VMASK, -		RIGGED_NORMSPEC_MASK_MASK = RIGGED_NORMSPEC_VMASK, -		RIGGED_NORMSPEC_EMISSIVE_MASK = RIGGED_NORMSPEC_VMASK, -		RIGGED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX |  -							 LLVertexBuffer::MAP_NORMAL |  -							 LLVertexBuffer::MAP_TEXCOORD0 | -							 LLVertexBuffer::MAP_COLOR | -							 LLVertexBuffer::MAP_WEIGHT4, -		RIGGED_FULLBRIGHT_MASK = LLVertexBuffer::MAP_VERTEX |  -							 LLVertexBuffer::MAP_TEXCOORD0 | -							 LLVertexBuffer::MAP_COLOR | -							 LLVertexBuffer::MAP_WEIGHT4, -		RIGGED_SHINY_MASK = RIGGED_SIMPLE_MASK, -		RIGGED_FULLBRIGHT_SHINY_MASK = RIGGED_SIMPLE_MASK,							  -		RIGGED_GLOW_MASK = LLVertexBuffer::MAP_VERTEX |  -							 LLVertexBuffer::MAP_TEXCOORD0 | -							 LLVertexBuffer::MAP_EMISSIVE | -							 LLVertexBuffer::MAP_WEIGHT4, -		RIGGED_ALPHA_MASK = RIGGED_SIMPLE_MASK, -		RIGGED_FULLBRIGHT_ALPHA_MASK = RIGGED_FULLBRIGHT_MASK, -		RIGGED_DEFERRED_BUMP_MASK = LLVertexBuffer::MAP_VERTEX |  -							 LLVertexBuffer::MAP_NORMAL |  -							 LLVertexBuffer::MAP_TEXCOORD0 | -							 LLVertexBuffer::MAP_TANGENT | -							 LLVertexBuffer::MAP_COLOR | -							 LLVertexBuffer::MAP_WEIGHT4, -		RIGGED_DEFERRED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX |  -							 LLVertexBuffer::MAP_NORMAL |  -							 LLVertexBuffer::MAP_TEXCOORD0 | -							 LLVertexBuffer::MAP_COLOR | -							 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; @@ -215,101 +107,19 @@ typedef enum  	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 LLVOVolume* vobj, -									  LLVolume* volume, -									  LLVolumeFace& vol_face); -	void updateRiggedVertexBuffers(LLVOAvatar* avatar); +    void beginDeferredRigid(); +    void beginDeferredImpostor(); +    void beginDeferredSkinned(); -    void updateSkinInfoMatrixPalettes(LLVOAvatar* avatarp); - -	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);  - -	std::vector<LLFace*> mRiggedFace[NUM_RIGGED_PASSES]; - -    LL_ALIGN_PREFIX(16) -    class MatrixPaletteCache -    { -    public: -        U32 mFrame; -        LLMeshSkinInfo::matrix_list_t mMatrixPalette; -        LL_ALIGN_16(LLMatrix4a mBindShapeMatrix); -        // Float array ready to be sent to GL -        std::vector<F32> mGLMp; - -        MatrixPaletteCache() : -            mFrame(gFrameCount-1) -        { -        } -    } LL_ALIGN_POSTFIX(16); -     -    const MatrixPaletteCache& updateSkinInfoMatrixPalette(LLVOAvatar* avatarp, const LLUUID& meshId); - -    typedef std::unordered_map<LLUUID, MatrixPaletteCache> matrix_palette_cache_t; -    matrix_palette_cache_t mMatrixPaletteCache; +    void endDeferredRigid(); +    void endDeferredImpostor(); +    void endDeferredSkinned();  	/*virtual*/ LLViewerTexture *getDebugTexture();  	/*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display  	void renderAvatars(LLVOAvatar *single_avatar, S32 pass = -1); // renders only one avatar if single_avatar is not null. -  	static BOOL sSkipOpaque;  	static BOOL sSkipTransparent;      static S32  sShadowPass; diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 8f3b0c99b4..af8b194f38 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -47,6 +47,7 @@  #include "pipeline.h"  #include "llspatialpartition.h"  #include "llviewershadermgr.h" +#include "llmodel.h"  //#include "llimagebmp.h"  //#include "../tools/imdebug/imdebug.h" @@ -203,22 +204,11 @@ S32 LLDrawPoolBump::numBumpPasses()  	{  		if (mShaderLevel > 1)  		{ -			if (LLPipeline::sImpostorRender) -			{ -				return 2; -			} -			else -			{ -				return 3; -			} -		} -		else if (LLPipeline::sImpostorRender) -		{ -			return 1; +			return 6;  		}  		else  		{ -			return 2; +			return 4;  		}  	}      else @@ -235,6 +225,8 @@ S32 LLDrawPoolBump::getNumPasses()  void LLDrawPoolBump::beginRenderPass(S32 pass)  {  	LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); +    mRigged = ((pass % 2) == 1); +    pass /= 2;  	switch( pass )  	{  		case 0: @@ -267,7 +259,7 @@ void LLDrawPoolBump::render(S32 pass)  	{  		return;  	} -	 +    pass /= 2;  	switch( pass )  	{  		case 0: @@ -295,6 +287,7 @@ void LLDrawPoolBump::render(S32 pass)  void LLDrawPoolBump::endRenderPass(S32 pass)  {  	LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); +    pass /= 2;  	switch( pass )  	{  		case 0: @@ -326,12 +319,7 @@ void LLDrawPoolBump::endRenderPass(S32 pass)  void LLDrawPoolBump::beginShiny(bool invisible)  {  	LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); -	if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))||  -		(invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))) -	{ -		return; -	} - +	  	mShiny = TRUE;  	sVertexMask = VERTEX_MASK_SHINY;  	// Second pass: environment map @@ -340,31 +328,31 @@ void LLDrawPoolBump::beginShiny(bool invisible)  		sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0;  	} -	if (getShaderLevel() > 0) +	if (LLPipeline::sUnderWaterRender)  	{ -		if (LLPipeline::sUnderWaterRender) -		{ -			shader = &gObjectShinyWaterProgram; -		} -		else -		{ -			shader = &gObjectShinyProgram; -		} -		shader->bind(); -        if (LLPipeline::sRenderingHUDs) -        { -            shader->uniform1i(LLShaderMgr::NO_ATMO, 1); -        } -        else -        { -            shader->uniform1i(LLShaderMgr::NO_ATMO, 0); -        } +		shader = &gObjectShinyWaterProgram;  	}  	else  	{ -		shader = NULL; +		shader = &gObjectShinyProgram;  	} +    if (mRigged) +    { +        llassert(shader->mRiggedVariant); +        shader = shader->mRiggedVariant; +    } + +	shader->bind(); +    if (LLPipeline::sRenderingHUDs) +    { +        shader->uniform1i(LLShaderMgr::NO_ATMO, 1); +    } +    else +    { +        shader->uniform1i(LLShaderMgr::NO_ATMO, 0); +    } +  	bindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel, invisible);  	if (mShaderLevel > 1) @@ -391,7 +379,6 @@ void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& di  			shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);			  			if (shader_level > 1)  			{ -				cube_map->setMatrix(1);  				// Make sure that texture coord generation happens for tex unit 1, as that's the one we use for   				// the cube map in the one pass shiny shaders  				cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); @@ -403,7 +390,6 @@ void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& di  			{  				cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);  				diffuse_channel = -1; -				cube_map->setMatrix(0);  				cube_map->enable(cube_channel);  			}			  			gGL.getTexUnit(cube_channel)->bind(cube_map); @@ -415,7 +401,6 @@ void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& di  			diffuse_channel = -1;  			gGL.getTexUnit(0)->disable();  			cube_map->enable(0); -			cube_map->setMatrix(0);  			gGL.getTexUnit(0)->bind(cube_map);  			gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR); @@ -427,27 +412,32 @@ void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& di  void LLDrawPoolBump::renderShiny(bool invisible)  {  	LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); -	if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))||  -		(invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))) -	{ -		return; -	} - +	  	if( gSky.mVOSkyp->getCubeMap() )  	{  		LLGLEnable blend_enable(GL_BLEND);  		if (!invisible && mShaderLevel > 1)  		{ -			LLRenderPass::pushBatches(LLRenderPass::PASS_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +            if (mRigged) +            { +                LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_SHINY_RIGGED, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +            } +            else +            { +                LLRenderPass::pushBatches(LLRenderPass::PASS_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +            }  		}  		else if (!invisible)  		{ -			renderGroups(LLRenderPass::PASS_SHINY, sVertexMask); +            if (mRigged) +            { +                gPipeline.renderRiggedGroups(this, LLRenderPass::PASS_SHINY_RIGGED, sVertexMask, TRUE); +            } +            else +            { +                gPipeline.renderGroups(this, LLRenderPass::PASS_SHINY, sVertexMask, TRUE); +            }  		} -		//else // invisible (deprecated) -		//{ -			//renderGroups(LLRenderPass::PASS_INVISI_SHINY, sVertexMask); -		//}  	}  } @@ -472,27 +462,12 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&          // Moved below shader->disableTexture call to avoid false alarms from auto-re-enable of textures on stage 0          // MAINT-755  		cube_map->disable(); -		cube_map->restoreMatrix(); -	} - -	if (!LLGLSLShader::sNoFixedFunction) -	{ -		gGL.getTexUnit(diffuse_channel)->disable(); -		gGL.getTexUnit(cube_channel)->disable(); - -		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);  	}  }  void LLDrawPoolBump::endShiny(bool invisible)  {  	LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); -	if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))||  -		(invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))) -	{ -		return; -	}  	unbindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel, invisible);  	if (shader) @@ -508,11 +483,7 @@ void LLDrawPoolBump::endShiny(bool invisible)  void LLDrawPoolBump::beginFullbrightShiny()  {  	LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); -	if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY)) -	{ -		return; -	} - +	  	sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0;  	// Second pass: environment map @@ -533,6 +504,12 @@ void LLDrawPoolBump::beginFullbrightShiny()  		}  	} +    if (mRigged) +    { +        llassert(shader->mRiggedVariant); +        shader = shader->mRiggedVariant; +    } +  	LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;  	if( cube_map )  	{ @@ -553,9 +530,8 @@ void LLDrawPoolBump::beginFullbrightShiny()  		LLVector3 vec = LLVector3(gShinyOrigin) * mat;  		LLVector4 vec4(vec, gShinyOrigin.mV[3]); -		shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);			 +		shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV); -		cube_map->setMatrix(1);  		// Make sure that texture coord generation happens for tex unit 1, as that's the one we use for   		// the cube map in the one pass shiny shaders  		gGL.getTexUnit(1)->disable(); @@ -579,10 +555,6 @@ void LLDrawPoolBump::beginFullbrightShiny()  void LLDrawPoolBump::renderFullbrightShiny()  {  	LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); -	if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY)) -	{ -		return; -	}  	if( gSky.mVOSkyp->getCubeMap() )  	{ @@ -590,11 +562,25 @@ void LLDrawPoolBump::renderFullbrightShiny()  		if (mShaderLevel > 1)  		{ -			LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +            if (mRigged) +            { +                LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +            } +            else +            { +                LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +            }  		}  		else  		{ -			LLRenderPass::renderTexture(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask); +            if (mRigged) +            { +                LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED, sVertexMask); +            } +            else +            { +                LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask); +            }  		}  	}  } @@ -602,18 +588,13 @@ void LLDrawPoolBump::renderFullbrightShiny()  void LLDrawPoolBump::endFullbrightShiny()  {  	LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); -	if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY)) -	{ -		return; -	}  	LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;  	if( cube_map )  	{  		cube_map->disable(); -		cube_map->restoreMatrix(); -		/*if (diffuse_channel != 0) +        /*if (diffuse_channel != 0)  		{  			shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);  		} @@ -726,53 +707,22 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsi  }  //static -void LLDrawPoolBump::beginBump(U32 pass) +void LLDrawPoolBump::beginBump()  {	 -	if (!gPipeline.hasRenderBatches(pass)) -	{ -		return; -	} -  	sVertexMask = VERTEX_MASK_BUMP;  	LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);  	// Optional second pass: emboss bump map  	stop_glerror(); -	if (LLGLSLShader::sNoFixedFunction) -	{ -		gObjectBumpProgram.bind(); -	} -	else -	{ -		// TEXTURE UNIT 0 -		// Output.rgb = texture at texture coord 0 -		gGL.getTexUnit(0)->activate(); - -		gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA); -		gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA); +    shader = &gObjectBumpProgram; -		// TEXTURE UNIT 1 -		gGL.getTexUnit(1)->activate(); -  -		gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); - -		gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD_SIGNED, LLTexUnit::TBS_PREV_COLOR, LLTexUnit::TBS_ONE_MINUS_TEX_ALPHA); -		gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA); - -		// src	= tex0 + (1 - tex1) - 0.5 -		//		= (bump0/2 + 0.5) + (1 - (bump1/2 + 0.5)) - 0.5 -		//		= (1 + bump0 - bump1) / 2 +    if (mRigged) +    { +        llassert(shader->mRiggedVariant); +        shader = shader->mRiggedVariant; +    } - -		// Blend: src * dst + dst * src -		//		= 2 * src * dst -		//		= 2 * ((1 + bump0 - bump1) / 2) * dst   [0 - 2 * dst] -		//		= (1 + bump0 - bump1) * dst.rgb -		//		= dst.rgb + dst.rgb * (bump0 - bump1) - -		gGL.getTexUnit(0)->activate(); -		gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); -	} +    shader->bind();  	gGL.setSceneBlendType(LLRender::BT_MULT_X2);  	stop_glerror(); @@ -781,11 +731,6 @@ void LLDrawPoolBump::beginBump(U32 pass)  //static  void LLDrawPoolBump::renderBump(U32 pass)  { -	if (!gPipeline.hasRenderBatches(pass)) -	{ -		return; -	} -  	LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);  	LLGLDisable fog(GL_FOG);  	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_LEQUAL); @@ -800,11 +745,6 @@ void LLDrawPoolBump::renderBump(U32 pass)  //static  void LLDrawPoolBump::endBump(U32 pass)  { -	if (!gPipeline.hasRenderBatches(pass)) -	{ -		return; -	} -  	if (LLGLSLShader::sNoFixedFunction)  	{  		gObjectBumpProgram.unbind(); @@ -828,7 +768,7 @@ S32 LLDrawPoolBump::getNumDeferredPasses()  {   	if (gSavedSettings.getBOOL("RenderObjectBump"))  	{ -		return 1; +		return 2;  	}  	else  	{ @@ -838,66 +778,86 @@ S32 LLDrawPoolBump::getNumDeferredPasses()  void LLDrawPoolBump::beginDeferredPass(S32 pass)  { -	if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP)) +	if (!gPipeline.hasRenderBatches( pass == 0 ? LLRenderPass::PASS_BUMP : LLRenderPass::PASS_BUMP_RIGGED))  	{  		return;  	}  	LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);  	mShiny = TRUE; -	gDeferredBumpProgram.bind(); -	diffuse_channel = gDeferredBumpProgram.enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); -	bump_channel = gDeferredBumpProgram.enableTexture(LLViewerShaderMgr::BUMP_MAP); +	gDeferredBumpProgram.bind(pass == 1); +	diffuse_channel = LLGLSLShader::sCurBoundShaderPtr->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); +	bump_channel = LLGLSLShader::sCurBoundShaderPtr->enableTexture(LLViewerShaderMgr::BUMP_MAP);  	gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);  	gGL.getTexUnit(bump_channel)->unbind(LLTexUnit::TT_TEXTURE);  }  void LLDrawPoolBump::endDeferredPass(S32 pass)  { -	if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP)) +	if (!gPipeline.hasRenderBatches(pass == 0 ? LLRenderPass::PASS_BUMP : LLRenderPass::PASS_BUMP_RIGGED))  	{  		return;  	}  	LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);  	mShiny = FALSE; -	gDeferredBumpProgram.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); -	gDeferredBumpProgram.disableTexture(LLViewerShaderMgr::BUMP_MAP); -	gDeferredBumpProgram.unbind(); +    LLGLSLShader::sCurBoundShaderPtr->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); +    LLGLSLShader::sCurBoundShaderPtr->disableTexture(LLViewerShaderMgr::BUMP_MAP); +    LLGLSLShader::sCurBoundShaderPtr->unbind();  	gGL.getTexUnit(0)->activate();  }  void LLDrawPoolBump::renderDeferred(S32 pass)  { -	if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP)) +    if (!gPipeline.hasRenderBatches(pass == 0 ? LLRenderPass::PASS_BUMP : LLRenderPass::PASS_BUMP_RIGGED))  	{  		return;  	}  	LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); -	U32 type = LLRenderPass::PASS_BUMP; -	LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); -	LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); +    bool rigged = pass == 1; +    U32 type = rigged ? LLRenderPass::PASS_BUMP_RIGGED : LLRenderPass::PASS_BUMP; +    LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); +    LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); -	U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR; -	 -	for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)	 -	{ -		LLDrawInfo& params = **i; +    U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR; -		gDeferredBumpProgram.setMinimumAlpha(params.mAlphaMaskCutoff); -		LLDrawPoolBump::bindBumpMap(params, bump_channel); -		pushBatch(params, mask, TRUE); -	} +    LLVOAvatar* avatar = nullptr; +    U64 skin = 0; + +    for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) +    { +        LLDrawInfo& params = **i; + +        LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(params.mAlphaMaskCutoff); +        LLDrawPoolBump::bindBumpMap(params, bump_channel); + +        if (rigged) +        { +            if (avatar != params.mAvatar || skin != params.mSkinInfo->mHash) +            { +                uploadMatrixPalette(params); +                avatar = params.mAvatar; +                skin = params.mSkinInfo->mHash; +            } +            pushBatch(params, mask | LLVertexBuffer::MAP_WEIGHT4, TRUE, FALSE); +        } +        else +        { +            pushBatch(params, mask, TRUE, FALSE); +        } +    }  }  void LLDrawPoolBump::beginPostDeferredPass(S32 pass)  { +    mRigged = ((pass % 2) == 1); +    pass /= 2;  	switch (pass)  	{  	case 0:  		beginFullbrightShiny();  		break;  	case 1: -		beginBump(LLRenderPass::PASS_POST_BUMP); +		beginBump();  		break;  	}  } @@ -920,6 +880,7 @@ void LLDrawPoolBump::endPostDeferredPass(S32 pass)  void LLDrawPoolBump::renderPostDeferred(S32 pass)  { +    pass /= 2;  	switch (pass)  	{  	case 0: @@ -1462,8 +1423,17 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI  void LLDrawPoolBump::renderBump(U32 type, U32 mask)  {	 -	LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); -	LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); +    LLVOAvatar* avatar = nullptr; +    U64 skin = 0; + +    if (mRigged) +    { // nudge type enum and include skinweights for rigged pass +        type += 1; +        mask |= LLVertexBuffer::MAP_WEIGHT4; +    } + +    LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); +    LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);  	for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)	  	{ @@ -1471,6 +1441,21 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)  		if (LLDrawPoolBump::bindBumpMap(params))  		{ +            if (mRigged) +            { +                if (avatar != params.mAvatar || skin != params.mSkinInfo->mHash) +                { +                    if (uploadMatrixPalette(params)) +                    { +                        avatar = params.mAvatar; +                        skin = params.mSkinInfo->mHash; +                    } +                    else +                    { +                        continue; +                    } +                } +            }  			pushBatch(params, mask, FALSE);  		}  	} diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index bab160c34d..d76e925eb0 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -57,7 +57,7 @@ public:  	virtual void endRenderPass( S32 pass );  	virtual S32	 getNumPasses();  	/*virtual*/ void prerender(); -	/*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE); +	void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE) override;  	void renderBump(U32 type, U32 mask);  	void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture); @@ -72,7 +72,7 @@ public:  	void renderFullbrightShiny();  	void endFullbrightShiny(); -	void beginBump(U32 pass = LLRenderPass::PASS_BUMP); +	void beginBump();  	void renderBump(U32 pass = LLRenderPass::PASS_BUMP);  	void endBump(U32 pass = LLRenderPass::PASS_BUMP); @@ -84,7 +84,7 @@ public:  	/*virtual*/ void endDeferredPass(S32 pass);  	/*virtual*/ void renderDeferred(S32 pass); -	virtual S32 getNumPostDeferredPasses() { return 2; } +	virtual S32 getNumPostDeferredPasses() { return 4; }  	/*virtual*/ void beginPostDeferredPass(S32 pass);  	/*virtual*/ void endPostDeferredPass(S32 pass);  	/*virtual*/ void renderPostDeferred(S32 pass); @@ -94,6 +94,7 @@ public:  private:  	static BOOL bindBumpMap(U8 bump_code, LLViewerTexture* tex, F32 vsize, S32 channel); +    bool mRigged = false; // if true, doing a rigged pass  }; diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index d2a8757379..fd5850084b 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -31,6 +31,7 @@  #include "llviewershadermgr.h"  #include "pipeline.h"  #include "llglcommonfunc.h" +#include "llvoavatar.h"  S32 diffuse_channel = -1; @@ -47,11 +48,18 @@ void LLDrawPoolMaterials::prerender()  S32 LLDrawPoolMaterials::getNumDeferredPasses()  { -	return 12; +    // 12 render passes times 2 (one for each rigged and non rigged) +	return 12*2;  }  void LLDrawPoolMaterials::beginDeferredPass(S32 pass)  { +    bool rigged = false; +    if (pass >= 12) +    {  +        rigged = true; +        pass -= 12; +    }  	U32 shader_idx[] =   	{  		0, //LLRenderPass::PASS_MATERIAL, @@ -72,13 +80,22 @@ void LLDrawPoolMaterials::beginDeferredPass(S32 pass)  		15, //LLRenderPass::PASS_NORMSPEC_GLOW,  	}; -	mShader = &(gDeferredMaterialProgram[shader_idx[pass]]); - -	if (LLPipeline::sUnderWaterRender) -	{ -		mShader = &(gDeferredMaterialWaterProgram[shader_idx[pass]]); -	} - +    U32 idx = shader_idx[pass]; +     +    if (LLPipeline::sUnderWaterRender) +    { +        mShader = &(gDeferredMaterialWaterProgram[idx]); +    } +    else +    { +        mShader = &(gDeferredMaterialProgram[idx]); +    } +     +    if (rigged) +    { +        llassert(mShader->mRiggedVariant != nullptr); +        mShader = mShader->mRiggedVariant; +    }  	mShader->bind();      if (LLPipeline::sRenderingHUDs) @@ -127,9 +144,20 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)  		LLRenderPass::PASS_NORMSPEC_EMISSIVE,  	}; +    bool rigged = false; +    if (pass >= 12) +    { +        rigged = true; +        pass -= 12; +    } +  	llassert(pass < sizeof(type_list)/sizeof(U32));  	U32 type = type_list[pass]; +    if (rigged) +    { +        type += 1; +    }  	U32 mask = mShader->mAttributeMask; @@ -160,7 +188,7 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)          {              LL_PROFILE_ZONE_SCOPED; -            pushMaterialsBatch(params, mask); +            pushMaterialsBatch(params, mask, rigged);          }  	}  } @@ -175,7 +203,7 @@ void LLDrawPoolMaterials::bindNormalMap(LLViewerTexture* tex)  	mShader->bindTexture(LLShaderMgr::BUMP_MAP, tex);  } -void LLDrawPoolMaterials::pushMaterialsBatch(LLDrawInfo& params, U32 mask) +void LLDrawPoolMaterials::pushMaterialsBatch(LLDrawInfo& params, U32 mask, bool rigged)  {      LL_PROFILE_ZONE_SCOPED;  	applyModelMatrix(params); @@ -214,6 +242,24 @@ void LLDrawPoolMaterials::pushMaterialsBatch(LLDrawInfo& params, U32 mask)  		params.mGroup->rebuildMesh();  	} +    // upload matrix palette to shader +    if (rigged) +    { +        const LLVOAvatar::MatrixPaletteCache& mpc = params.mAvatar->updateSkinInfoMatrixPalette(params.mSkinInfo); +        U32 count = mpc.mMatrixPalette.size(); + +        if (count == 0) +        { +            //skin info not loaded yet, don't render +            return; +        } + +        mShader->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, +            count, +            FALSE, +            (GLfloat*)&(mpc.mGLMp[0])); +    } +  	LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);  	params.mVertexBuffer->setBufferFast(mask); diff --git a/indra/newview/lldrawpoolmaterials.h b/indra/newview/lldrawpoolmaterials.h index 6e39821b07..8a3ad923df 100644 --- a/indra/newview/lldrawpoolmaterials.h +++ b/indra/newview/lldrawpoolmaterials.h @@ -55,21 +55,21 @@ public:  		LLVertexBuffer::MAP_TANGENT  	}; -	/*virtual*/ U32 getVertexDataMask() { return VERTEX_DATA_MASK; } +	U32 getVertexDataMask() override { return VERTEX_DATA_MASK; } -	/*virtual*/ void render(S32 pass = 0) { } -	/*virtual*/ S32	 getNumPasses() {return 0;} -	/*virtual*/ void prerender(); +	void render(S32 pass = 0) override { } +	S32	 getNumPasses() override {return 0;} +	void prerender() override; -	/*virtual*/ S32 getNumDeferredPasses(); -	/*virtual*/ void beginDeferredPass(S32 pass); -	/*virtual*/ void endDeferredPass(S32 pass); -	/*virtual*/ void renderDeferred(S32 pass); +	S32 getNumDeferredPasses() override; +	void beginDeferredPass(S32 pass) override; +	void endDeferredPass(S32 pass) override; +	void renderDeferred(S32 pass) override;  	void bindSpecularMap(LLViewerTexture* tex);  	void bindNormalMap(LLViewerTexture* tex); -	/*virtual*/ void pushMaterialsBatch(LLDrawInfo& params, U32 mask); +	void pushMaterialsBatch(LLDrawInfo& params, U32 mask, bool rigged);  };  #endif //LL_LLDRAWPOOLMATERIALS_H diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 320160d10d..ca4e20ae9b 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -45,15 +45,24 @@ static LLTrace::BlockTimerStatHandle FTM_RENDER_GRASS_DEFERRED("Deferred Grass")  void LLDrawPoolGlow::beginPostDeferredPass(S32 pass)  { -	gDeferredEmissiveProgram.bind(); -	gDeferredEmissiveProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); +    if (pass == 0) +    { +        gDeferredEmissiveProgram.bind(); +    } +    else +    { +        llassert(gDeferredEmissiveProgram.mRiggedVariant); +        gDeferredEmissiveProgram.mRiggedVariant->bind(); +    } + +	LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);      if (LLPipeline::sRenderingHUDs)  	{ -		gDeferredEmissiveProgram.uniform1i(LLShaderMgr::NO_ATMO, 1); +        LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 1);  	}  	else  	{ -		gDeferredEmissiveProgram.uniform1i(LLShaderMgr::NO_ATMO, 0); +        LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 0);  	}  } @@ -71,7 +80,14 @@ void LLDrawPoolGlow::renderPostDeferred(S32 pass)  	LLGLDepthTest depth(GL_TRUE, GL_FALSE);  	gGL.setColorMask(false, true); -	pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +    if (pass == 0) +    { +        pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +    } +    else +    { +        pushRiggedBatches(LLRenderPass::PASS_GLOW_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +    }  	gGL.setColorMask(true, false);  	gGL.setSceneBlendType(LLRender::BT_ALPHA);	 @@ -79,7 +95,8 @@ void LLDrawPoolGlow::renderPostDeferred(S32 pass)  void LLDrawPoolGlow::endPostDeferredPass(S32 pass)  { -	gDeferredEmissiveProgram.unbind(); +    LLGLSLShader::sCurBoundShaderPtr->unbind(); +  	LLRenderPass::endRenderPass(pass);  } @@ -87,7 +104,7 @@ S32 LLDrawPoolGlow::getNumPasses()  {  	if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0)  	{ -		return 1; +		return 2;  	}  	else  	{ @@ -112,6 +129,11 @@ void LLDrawPoolGlow::render(S32 pass)  	llassert(shader_level > 0);  	LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram; +    if (pass == 1) +    { +        llassert(shader->mRiggedVariant); +        shader = shader->mRiggedVariant; +    }  	shader->bind();  	if (LLPipeline::sRenderDeferred)  	{ @@ -120,7 +142,7 @@ void LLDrawPoolGlow::render(S32 pass)  	else  	{  		shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f); -	}	 +	}      if (LLPipeline::sRenderingHUDs)  	{ @@ -134,7 +156,14 @@ void LLDrawPoolGlow::render(S32 pass)  	LLGLDepthTest depth(GL_TRUE, GL_FALSE);  	gGL.setColorMask(false, true); -	pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +    if (pass == 0) +    { +        pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +    } +    else +    { +        pushRiggedBatches(LLRenderPass::PASS_GLOW_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +    }  	gGL.setColorMask(true, false);  	gGL.setSceneBlendType(LLRender::BT_ALPHA); @@ -155,39 +184,43 @@ void LLDrawPoolSimple::prerender()  	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);  } +S32 LLDrawPoolSimple::getNumPasses() +{ +    return 2; +} +  void LLDrawPoolSimple::beginRenderPass(S32 pass)  {  	LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE); -	if (LLPipeline::sImpostorRender) -	{ -		simple_shader = &gObjectSimpleImpostorProgram; -	} -	else if (LLPipeline::sUnderWaterRender) -	{ -		simple_shader = &gObjectSimpleWaterProgram; -	} -	else -	{ -		simple_shader = &gObjectSimpleProgram; -	} +    if (LLPipeline::sImpostorRender) +    { +        simple_shader = &gObjectSimpleImpostorProgram; +    } +    else if (LLPipeline::sUnderWaterRender) +    { +        simple_shader = &gObjectSimpleWaterProgram; +    } +    else +    { +        simple_shader = &gObjectSimpleProgram; +    } +  +    if (pass == 1) +    { +        llassert(simple_shader->mRiggedVariant); +        simple_shader = simple_shader->mRiggedVariant; +    } -	if (mShaderLevel > 0) -	{ -		simple_shader->bind(); +	simple_shader->bind(); -        if (LLPipeline::sRenderingHUDs) -	    { -		    simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1); -	    } -	    else -	    { -		    simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0); -	    } +    if (LLPipeline::sRenderingHUDs) +	{ +		simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);  	} -	else  +	else  	{ -		LLGLSLShader::bindNoShader(); +		simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);  	}  } @@ -197,10 +230,7 @@ void LLDrawPoolSimple::endRenderPass(S32 pass)  	stop_glerror();  	LLRenderPass::endRenderPass(pass);  	stop_glerror(); -	if (mShaderLevel > 0) -	{ -		simple_shader->unbind(); -	} +	simple_shader->unbind();  }  void LLDrawPoolSimple::render(S32 pass) @@ -211,35 +241,38 @@ void LLDrawPoolSimple::render(S32 pass)  		LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE);  		gPipeline.enableLightsDynamic(); -		if (mShaderLevel > 0) -		{ -			U32 mask = getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX; - -			pushBatches(LLRenderPass::PASS_SIMPLE, mask, TRUE, TRUE); - -			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_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 -		{ -			LLGLDisable alpha_test(GL_ALPHA_TEST); -			renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask()); -		} -		 -	} -} - - +		U32 mask = getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX; +        if (pass == 0) +        { +            pushBatches(LLRenderPass::PASS_SIMPLE, mask, TRUE, TRUE); +            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_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 +        { +            pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, mask, TRUE, TRUE); +            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 +                pushRiggedBatches(LLRenderPass::PASS_BUMP_RIGGED, mask, TRUE, TRUE); +                pushRiggedBatches(LLRenderPass::PASS_MATERIAL_RIGGED, mask, TRUE, TRUE); +                pushRiggedBatches(LLRenderPass::PASS_SPECMAP_RIGGED, mask, TRUE, TRUE); +                pushRiggedBatches(LLRenderPass::PASS_NORMMAP_RIGGED, mask, TRUE, TRUE); +                pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_RIGGED, mask, TRUE, TRUE); +            } +        } +	} +} @@ -261,32 +294,31 @@ void LLDrawPoolAlphaMask::beginRenderPass(S32 pass)  {  	LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK); -	if (LLPipeline::sUnderWaterRender) -	{ -		simple_shader = &gObjectSimpleWaterAlphaMaskProgram; -	} -	else -	{ -		simple_shader = &gObjectSimpleAlphaMaskProgram; -	} +    if (LLPipeline::sUnderWaterRender) +    { +        simple_shader = &gObjectSimpleWaterAlphaMaskProgram; +    } +    else +    { +        simple_shader = &gObjectSimpleAlphaMaskProgram; +    } -	if (mShaderLevel > 0) -	{ -		simple_shader->bind(); +    if (pass == 1) +    { +        llassert(simple_shader->mRiggedVariant); +        simple_shader = simple_shader->mRiggedVariant; +    } -        if (LLPipeline::sRenderingHUDs) -	    { -		    simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1); -	    } -	    else -	    { -		    simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0); -	    } -	} -	else  -	{ -		LLGLSLShader::bindNoShader(); -	} +    simple_shader->bind(); + +    if (LLPipeline::sRenderingHUDs) +    { +	    simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1); +    } +    else +    { +	    simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0); +    }  }  void LLDrawPoolAlphaMask::endRenderPass(S32 pass) @@ -306,20 +338,22 @@ void LLDrawPoolAlphaMask::render(S32 pass)  	LLGLDisable blend(GL_BLEND);      LL_PROFILE_ZONE_SCOPED; -	if (mShaderLevel > 0) -	{ -		simple_shader->bind(); -		simple_shader->setMinimumAlpha(0.33f); +	 -        if (LLPipeline::sRenderingHUDs) -	    { -		    simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1); -	    } -	    else -	    { -		    simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0); -	    } +	simple_shader->bind(); +	simple_shader->setMinimumAlpha(0.33f); + +    if (LLPipeline::sRenderingHUDs) +	{ +		simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1); +	} +	else +	{ +		simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0); +	} +    if (pass == 0) +    {  		pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);  		pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);  		pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); @@ -328,9 +362,11 @@ void LLDrawPoolAlphaMask::render(S32 pass)  	}  	else  	{ -		LLGLEnable test(GL_ALPHA_TEST); -		pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE); -		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK +        pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +        pushRiggedMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +        pushRiggedMaskBatches(LLRenderPass::PASS_SPECMAP_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +        pushRiggedMaskBatches(LLRenderPass::PASS_NORMMAP_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +        pushRiggedMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);  	}  } @@ -348,31 +384,32 @@ void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass)  {  	LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK); +    bool rigged = (pass == 1);  	if (LLPipeline::sUnderWaterRender)  	{ -		simple_shader = &gObjectFullbrightWaterAlphaMaskProgram; +        gObjectFullbrightWaterAlphaMaskProgram.bind(rigged);  	}  	else  	{ -		simple_shader = &gObjectFullbrightAlphaMaskProgram; +		gObjectFullbrightAlphaMaskProgram.bind(rigged);  	} -	if (mShaderLevel > 0) +    if (LLPipeline::sRenderingHUDs)  	{ -		simple_shader->bind(); - -        if (LLPipeline::sRenderingHUDs) -	    { -		    simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1); -	    } -	    else -	    { -		    simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0); -	    } +		LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 1); +        LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f);  	} -	else  +	else  	{ -		LLGLSLShader::bindNoShader(); +        LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 0); +        if (LLPipeline::sRenderDeferred) +        { +            LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); +        } +        else +        { +            LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); +        }  	}  } @@ -382,70 +419,61 @@ void LLDrawPoolFullbrightAlphaMask::endRenderPass(S32 pass)  	stop_glerror();  	LLRenderPass::endRenderPass(pass);  	stop_glerror(); -	if (mShaderLevel > 0) -	{ -		simple_shader->unbind(); -	} +    LLGLSLShader::sCurBoundShaderPtr->unbind();  }  void LLDrawPoolFullbrightAlphaMask::render(S32 pass)  {  	LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK); -	if (mShaderLevel > 0) -	{ -		if (simple_shader) -		{ -			simple_shader->bind(); -			simple_shader->setMinimumAlpha(0.33f); - -            if (LLPipeline::sRenderingHUDs) -	        { -		        simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1); -                simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); -	        } -	        else -	        { -		        simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0); -                if (LLPipeline::sRenderDeferred) -			    { -                    simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);				     -			    } -                else -                { -				    simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); -			    } -	        } -		} -		pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); -		//LLGLSLShader::bindNoShader(); -	} -	else -	{ -		LLGLEnable test(GL_ALPHA_TEST); -		gPipeline.enableLightsFullbright(); -		pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE); -		gPipeline.enableLightsDynamic(); -		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK -	} +    if (pass == 0) +    { +        pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +    } +    else +    { +        pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +    } +	  }  //===============================  //DEFERRED IMPLEMENTATION  //=============================== +S32 LLDrawPoolSimple::getNumDeferredPasses() +{ +    if (LLPipeline::sRenderingHUDs) +    { +        return 1; +    } +    else +    { +        return 2; +    } +}  void LLDrawPoolSimple::beginDeferredPass(S32 pass)  {  	LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED); -	gDeferredDiffuseProgram.bind(); + +    mShader = &gDeferredDiffuseProgram; +     +    if (pass == 1) +    { +        llassert(mShader->mRiggedVariant != nullptr); +        mShader = mShader->mRiggedVariant; +    } +     + +    mShader->bind();      if (LLPipeline::sRenderingHUDs)  	{ -		gDeferredDiffuseProgram.uniform1i(LLShaderMgr::NO_ATMO, 1); +		mShader->uniform1i(LLShaderMgr::NO_ATMO, 1);  	}  	else  	{ -		gDeferredDiffuseProgram.uniform1i(LLShaderMgr::NO_ATMO, 0); +		mShader->uniform1i(LLShaderMgr::NO_ATMO, 0);  	}  } @@ -454,7 +482,7 @@ void LLDrawPoolSimple::endDeferredPass(S32 pass)  	LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED);  	LLRenderPass::endRenderPass(pass); -	gDeferredDiffuseProgram.unbind(); +	mShader->unbind();  }  void LLDrawPoolSimple::renderDeferred(S32 pass) @@ -463,41 +491,61 @@ void LLDrawPoolSimple::renderDeferred(S32 pass)  	LLGLDisable blend(GL_BLEND);  	LLGLDisable alpha_test(GL_ALPHA_TEST); +    if (pass == 0)  	{ //render simple  		LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED);  		pushBatches(LLRenderPass::PASS_SIMPLE, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);  	} +    else +    { +        //render simple rigged +        pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +    }  }  static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK_DEFERRED("Deferred Alpha Mask");  void LLDrawPoolAlphaMask::beginDeferredPass(S32 pass)  { -	 +    if (pass == 0) +    { +        gDeferredDiffuseAlphaMaskProgram.bind(); +    } +    else +    { +        llassert(gDeferredDiffuseAlphaMaskProgram.mRiggedVariant); +        gDeferredDiffuseAlphaMaskProgram.mRiggedVariant->bind(); +    } +  }  void LLDrawPoolAlphaMask::endDeferredPass(S32 pass)  { -	 +    LLGLSLShader::sCurBoundShaderPtr->unbind();  }  void LLDrawPoolAlphaMask::renderDeferred(S32 pass)  {  	LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK_DEFERRED); -	gDeferredDiffuseAlphaMaskProgram.bind(); -	gDeferredDiffuseAlphaMaskProgram.setMinimumAlpha(0.33f); +	LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(0.33f);      if (LLPipeline::sRenderingHUDs)  	{ -		gDeferredDiffuseAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 1); +        LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 1);  	}  	else  	{ -		gDeferredDiffuseAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 0); +        LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 0);  	} -	pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); -	gDeferredDiffuseAlphaMaskProgram.unbind();			 +    if (pass == 0) +    { +        pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +    } +    else +    { +        pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +    }  } @@ -572,7 +620,7 @@ void LLDrawPoolGrass::render(S32 pass)  		LLGLEnable test(GL_ALPHA_TEST);  		gGL.setSceneBlendType(LLRender::BT_ALPHA);  		//render grass -		LLRenderPass::renderTexture(LLRenderPass::PASS_GRASS, getVertexDataMask()); +		LLRenderPass::pushBatches(LLRenderPass::PASS_GRASS, getVertexDataMask());  	}  } @@ -603,7 +651,7 @@ void LLDrawPoolGrass::renderDeferred(S32 pass)  	    }  		//render grass -		LLRenderPass::renderTexture(LLRenderPass::PASS_GRASS, getVertexDataMask()); +		LLRenderPass::pushBatches(LLRenderPass::PASS_GRASS, getVertexDataMask());  	}			  } @@ -621,24 +669,24 @@ void LLDrawPoolFullbright::prerender()  void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass)  { +    bool rigged = (pass == 1);  	if (LLPipeline::sUnderWaterRender)  	{ -		gDeferredFullbrightWaterProgram.bind(); +		gDeferredFullbrightWaterProgram.bind(rigged);  	}  	else  	{ -		gDeferredFullbrightProgram.bind(); +		gDeferredFullbrightProgram.bind(rigged);          if (LLPipeline::sRenderingHUDs)  	    { -		    gDeferredFullbrightProgram.uniform1i(LLShaderMgr::NO_ATMO, 1); +            LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 1);  	    }  	    else  	    { -		    gDeferredFullbrightProgram.uniform1i(LLShaderMgr::NO_ATMO, 0); +            LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 0);  	    }  	} -	  }  void LLDrawPoolFullbright::renderPostDeferred(S32 pass) @@ -647,19 +695,19 @@ void LLDrawPoolFullbright::renderPostDeferred(S32 pass)  	gGL.setSceneBlendType(LLRender::BT_ALPHA);  	U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; -	pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE); +    if (pass == 0) +    { +        pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE); +    } +    else +    { +        pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, fullbright_mask, TRUE, TRUE); +    }  }  void LLDrawPoolFullbright::endPostDeferredPass(S32 pass)  { -	if (LLPipeline::sUnderWaterRender) -	{ -		gDeferredFullbrightWaterProgram.unbind(); -	} -	else -	{ -		gDeferredFullbrightProgram.unbind(); -	} +    LLGLSLShader::sCurBoundShaderPtr->unbind();  	LLRenderPass::endRenderPass(pass);  } @@ -675,6 +723,12 @@ void LLDrawPoolFullbright::beginRenderPass(S32 pass)  	{  		fullbright_shader = &gObjectFullbrightProgram;  	} + +    if (pass == 1) +    { +        llassert(fullbright_shader->mRiggedVariant); +        fullbright_shader = fullbright_shader->mRiggedVariant; +    }  }  void LLDrawPoolFullbright::endRenderPass(S32 pass) @@ -715,21 +769,23 @@ void LLDrawPoolFullbright::render(S32 pass)  	    }  		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(); -		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); + +        if (pass == 0) +        { +            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 +        { +            pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, fullbright_mask, TRUE, TRUE); +            pushRiggedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED, fullbright_mask, TRUE, TRUE); +            pushRiggedBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE_RIGGED, fullbright_mask, TRUE, TRUE); +            pushRiggedBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE_RIGGED, fullbright_mask, TRUE, TRUE); +            pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED, fullbright_mask, TRUE, TRUE); +        }  	}  	stop_glerror(); @@ -737,39 +793,39 @@ void LLDrawPoolFullbright::render(S32 pass)  S32 LLDrawPoolFullbright::getNumPasses()  {  -	return 1; +	return 2;  }  void LLDrawPoolFullbrightAlphaMask::beginPostDeferredPass(S32 pass)  { -	 +    bool rigged = (pass == 1);      if (LLPipeline::sRenderingHUDs)      { -        gObjectFullbrightAlphaMaskProgram.bind(); -		gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); -        gObjectFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 1); +        gObjectFullbrightAlphaMaskProgram.bind(rigged); +		LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); +        LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 1);      }  	else if (LLPipeline::sRenderDeferred)  	{          if (LLPipeline::sUnderWaterRender)  		{ -			gDeferredFullbrightAlphaMaskWaterProgram.bind(); -			gDeferredFullbrightAlphaMaskWaterProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); -            gDeferredFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 1); +            gDeferredFullbrightAlphaMaskWaterProgram.bind(rigged); +            LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); +            LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 1);  		}  		else  		{ -			gDeferredFullbrightAlphaMaskProgram.bind(); -			gDeferredFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); -            gDeferredFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 0); +			gDeferredFullbrightAlphaMaskProgram.bind(rigged); +            LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); +            LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 0);  		}      }      else      { -		gObjectFullbrightAlphaMaskProgram.bind(); -		gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); -        gObjectFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 0); +		gObjectFullbrightAlphaMaskProgram.bind(rigged); +        LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); +        LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 0);  	}  } @@ -778,26 +834,19 @@ void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass)  	LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT);  	LLGLDisable blend(GL_BLEND);  	U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; -	pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, fullbright_mask, TRUE, TRUE); +    if (pass == 0) +    { +        pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, fullbright_mask, TRUE, TRUE); +    } +    else +    { +        pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, fullbright_mask, TRUE, TRUE); +    }  }  void LLDrawPoolFullbrightAlphaMask::endPostDeferredPass(S32 pass)  { -	if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred) -	{ -		gObjectFullbrightAlphaMaskProgram.unbind(); -	} -	else -	{ -		if (LLPipeline::sUnderWaterRender) -		{ -			gDeferredFullbrightAlphaMaskWaterProgram.unbind(); -		} -		else -		{ -			gDeferredFullbrightAlphaMaskProgram.unbind(); -		} -	} +    LLGLSLShader::sCurBoundShaderPtr->unbind();  	LLRenderPass::endRenderPass(pass);  } diff --git a/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h index b27cc4babc..9ef9ea910d 100644 --- a/indra/newview/lldrawpoolsimple.h +++ b/indra/newview/lldrawpoolsimple.h @@ -29,6 +29,8 @@  #include "lldrawpool.h" +class LLGLSLShader; +  class LLDrawPoolSimple : public LLRenderPass  {  public: @@ -43,18 +45,19 @@ public:  	LLDrawPoolSimple(); -	/*virtual*/ S32 getNumDeferredPasses() { return 1; } -	/*virtual*/ void beginDeferredPass(S32 pass); -	/*virtual*/ void endDeferredPass(S32 pass); -	/*virtual*/ void renderDeferred(S32 pass); +    S32 getNumDeferredPasses() override; +	void beginDeferredPass(S32 pass) override; +	void endDeferredPass(S32 pass) override; +	void renderDeferred(S32 pass) override; -	/*virtual*/ void beginRenderPass(S32 pass); -	/*virtual*/ void endRenderPass(S32 pass); +	void beginRenderPass(S32 pass) override; +	void endRenderPass(S32 pass) override;  	/// We need two passes so we can handle emissive materials separately. -	/*virtual*/ S32	 getNumPasses() { return 1; } -	/*virtual*/ void render(S32 pass = 0); -	/*virtual*/ void prerender(); +    S32	 getNumPasses() override; +	void render(S32 pass = 0) override; +	void prerender() override; +    LLGLSLShader* mShader = nullptr;  };  class LLDrawPoolGrass : public LLRenderPass @@ -98,12 +101,12 @@ public:  	LLDrawPoolAlphaMask(); -	/*virtual*/ S32 getNumDeferredPasses() { return 1; } +	/*virtual*/ S32 getNumDeferredPasses() { return 2; }  	/*virtual*/ void beginDeferredPass(S32 pass);  	/*virtual*/ void endDeferredPass(S32 pass);  	/*virtual*/ void renderDeferred(S32 pass); -	/*virtual*/ S32	 getNumPasses() { return 1; } +	/*virtual*/ S32	 getNumPasses() { return 2; }  	/*virtual*/ void beginRenderPass(S32 pass);  	/*virtual*/ void endRenderPass(S32 pass);  	/*virtual*/ void render(S32 pass = 0); @@ -124,12 +127,12 @@ public:  	LLDrawPoolFullbrightAlphaMask(); -	/*virtual*/ S32 getNumPostDeferredPasses() { return 1; } +	/*virtual*/ S32 getNumPostDeferredPasses() { return 2; }  	/*virtual*/ void beginPostDeferredPass(S32 pass);  	/*virtual*/ void endPostDeferredPass(S32 pass);  	/*virtual*/ void renderPostDeferred(S32 pass); -	/*virtual*/ S32	 getNumPasses() { return 1; } +	/*virtual*/ S32	 getNumPasses() { return 2; }  	/*virtual*/ void beginRenderPass(S32 pass);  	/*virtual*/ void endRenderPass(S32 pass);  	/*virtual*/ void render(S32 pass = 0); @@ -150,7 +153,7 @@ public:  	LLDrawPoolFullbright(); -	/*virtual*/ S32 getNumPostDeferredPasses() { return 1; } +	/*virtual*/ S32 getNumPostDeferredPasses() { return 2; }  	/*virtual*/ void beginPostDeferredPass(S32 pass);  	/*virtual*/ void endPostDeferredPass(S32 pass);  	/*virtual*/ void renderPostDeferred(S32 pass); @@ -179,7 +182,7 @@ public:  	virtual void prerender() { } -	/*virtual*/ S32 getNumPostDeferredPasses() { return 1; } +	/*virtual*/ S32 getNumPostDeferredPasses() { return 2; }  	/*virtual*/ void beginPostDeferredPass(S32 pass);   	/*virtual*/ void endPostDeferredPass(S32 pass);  	/*virtual*/ void renderPostDeferred(S32 pass); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 88b958d24a..39ca7961d8 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -56,6 +56,7 @@  #include "llviewertexture.h"  #include "llvoavatar.h"  #include "llsculptidsize.h" +#include "llmeshrepository.h"  #if LL_LINUX  // Work-around spurious used before init warning on Vector4a @@ -71,6 +72,7 @@ static LLStaticHashedString sColorIn("color_in");  BOOL LLFace::sSafeRenderSelect = TRUE; // FALSE +  #define DOTVEC(a,b) (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2])  /* @@ -197,14 +199,7 @@ void LLFace::destroy()  	if (mDrawPoolp)  	{ -		if (this->isState(LLFace::RIGGED) && (mDrawPoolp->getType() == LLDrawPool::POOL_CONTROL_AV || mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR)) -		{ -			((LLDrawPoolAvatar*) mDrawPoolp)->removeRiggedFace(this); -		} -		else -		{ -			mDrawPoolp->removeFace(this); -		} +		mDrawPoolp->removeFace(this);  		mDrawPoolp = NULL;  	} @@ -1286,7 +1281,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		return FALSE;  	} -	const LLVolumeFace &vf = volume.getVolumeFace(f); +    bool rigged = isState(RIGGED); + +    const LLVolumeFace &vf = volume.getVolumeFace(f);  	S32 num_vertices = (S32)vf.mNumVertices;  	S32 num_indices = (S32) vf.mNumIndices; @@ -1450,9 +1447,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		}  	} -	LLMatrix4a mat_normal; -	mat_normal.loadu(mat_norm_in); -	  	F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0;  	bool do_xform = false;  	if (rebuild_tcoord) @@ -1487,6 +1481,45 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		}  	} +    const LLMeshSkinInfo* skin = nullptr; +    LLMatrix4a mat_vert; +    LLMatrix4a mat_normal; + +    // prepare mat_vert +    if (rebuild_pos) +    { +        if (rigged) +        { //override with bind shape matrix if rigged +            skin = mSkinInfo; +            mat_vert = skin->mBindShapeMatrix; +        } +        else +        { +            mat_vert.loadu(mat_vert_in); +        } +    } + +    if (rebuild_normal || rebuild_tangent) +    { //override mat_normal with inverse of skin->mBindShapeMatrix +        LL_PROFILE_ZONE_NAMED("getGeometryVolume - norm mat override"); +        if (rigged) +        { +            if (skin == nullptr) +            { +                skin = mSkinInfo; +            } + +            //TODO -- cache this (check profile marker above)? +            glh::matrix4f m((F32*) skin->mBindShapeMatrix.getF32ptr()); +            m = m.inverse().transpose(); +            mat_normal.loadu(m.m); +        } +        else +        { +            mat_normal.loadu(mat_norm_in); +        } +    } +  	static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);  #ifdef GL_TRANSFORM_FEEDBACK_BUFFER @@ -1740,7 +1773,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  					do_xform = false;  				} -				if (getVirtualSize() >= MIN_TEX_ANIM_SIZE || isState(LLFace::RIGGED)) +				if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) // || isState(LLFace::RIGGED))  				{ //don't override texture transform during tc bake  					tex_mode = 0;  				} @@ -2036,9 +2069,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range); -			LLMatrix4a mat_vert; -			mat_vert.loadu(mat_vert_in); - +			  			F32* dst = (F32*) vert.get();  			F32* end_f32 = dst+mGeomCount*4; @@ -2089,10 +2120,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			}  		} -		  		if (rebuild_normal)  		{ -			//LL_RECORD_TIME_BLOCK(FTM_FACE_GEOM_NORMAL); +            LL_PROFILE_ZONE_NAMED("getGeometryVolume - normal"); +  			mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);  			F32* normals = (F32*) norm.get();  			LLVector4a* src = vf.mNormals; @@ -2714,56 +2745,6 @@ void LLFace::clearVertexBuffer()  	mVertexBuffer = NULL;  } -//static -U32 LLFace::getRiggedDataMask(U32 type) -{ -	static const U32 rigged_data_mask[] = { -		LLDrawPoolAvatar::RIGGED_MATERIAL_MASK, -		LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_VMASK, -		LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_MASK_MASK, -		LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_EMISSIVE_MASK, -		LLDrawPoolAvatar::RIGGED_SPECMAP_VMASK, -		LLDrawPoolAvatar::RIGGED_SPECMAP_BLEND_MASK, -		LLDrawPoolAvatar::RIGGED_SPECMAP_MASK_MASK, -		LLDrawPoolAvatar::RIGGED_SPECMAP_EMISSIVE_MASK, -		LLDrawPoolAvatar::RIGGED_NORMMAP_VMASK, -		LLDrawPoolAvatar::RIGGED_NORMMAP_BLEND_MASK, -		LLDrawPoolAvatar::RIGGED_NORMMAP_MASK_MASK, -		LLDrawPoolAvatar::RIGGED_NORMMAP_EMISSIVE_MASK, -		LLDrawPoolAvatar::RIGGED_NORMSPEC_VMASK, -		LLDrawPoolAvatar::RIGGED_NORMSPEC_BLEND_MASK, -		LLDrawPoolAvatar::RIGGED_NORMSPEC_MASK_MASK, -		LLDrawPoolAvatar::RIGGED_NORMSPEC_EMISSIVE_MASK, -		LLDrawPoolAvatar::RIGGED_SIMPLE_MASK, -		LLDrawPoolAvatar::RIGGED_FULLBRIGHT_MASK, -		LLDrawPoolAvatar::RIGGED_SHINY_MASK, -		LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY_MASK, -		LLDrawPoolAvatar::RIGGED_GLOW_MASK, -		LLDrawPoolAvatar::RIGGED_ALPHA_MASK, -		LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA_MASK, -		LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP_MASK,						  -		LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE_MASK, -	}; - -	llassert(type < sizeof(rigged_data_mask)/sizeof(U32)); - -	return rigged_data_mask[type]; -} - -U32 LLFace::getRiggedVertexBufferDataMask() const -{ -	U32 data_mask = 0; -	for (U32 i = 0; i < mRiggedIndex.size(); ++i) -	{ -		if (mRiggedIndex[i] > -1) -		{ -			data_mask |= LLFace::getRiggedDataMask(i); -		} -	} - -	return data_mask; -} -  S32 LLFace::getRiggedIndex(U32 type) const  {  	if (mRiggedIndex.empty()) @@ -2776,19 +2757,7 @@ S32 LLFace::getRiggedIndex(U32 type) const  	return mRiggedIndex[type];  } -void LLFace::setRiggedIndex(U32 type, S32 index) +U64 LLFace::getSkinHash()  { -	if (mRiggedIndex.empty()) -	{ -		mRiggedIndex.resize(LLDrawPoolAvatar::NUM_RIGGED_PASSES); -		for (U32 i = 0; i < mRiggedIndex.size(); ++i) -		{ -			mRiggedIndex[i] = -1; -		} -	} - -	llassert(type < mRiggedIndex.size()); - -	mRiggedIndex[type] = index; +    return mSkinInfo ? mSkinInfo->mHash : 0;  } - diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 2e76c974fa..c533edede4 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -49,6 +49,7 @@ class LLViewerTexture;  class LLGeometryManager;  class LLTextureAtlasSlot;  class LLDrawInfo; +class LLMeshSkinInfo;  const F32 MIN_ALPHA_SIZE = 1024.f;  const F32 MIN_TEX_ANIM_SIZE = 512.f; @@ -228,11 +229,7 @@ public:  	void setVertexBuffer(LLVertexBuffer* buffer);  	void clearVertexBuffer(); //sets mVertexBuffer to NULL  	LLVertexBuffer* getVertexBuffer()	const	{ return mVertexBuffer; } -	U32 getRiggedVertexBufferDataMask() const;  	S32 getRiggedIndex(U32 type) const; -	void setRiggedIndex(U32 type, S32 index); - -	static U32 getRiggedDataMask(U32 type);  	void	notifyAboutCreatingTexture(LLViewerTexture *texture);  	void	notifyAboutMissingAsset(LLViewerTexture *texture); @@ -261,6 +258,11 @@ public:  	LLMatrix4*	mSpecMapMatrix;  	LLMatrix4*	mNormalMapMatrix;  	LLDrawInfo* mDrawInfo; +    LLVOAvatar* mAvatar = nullptr; +    LLMeshSkinInfo* mSkinInfo = nullptr; +     +    // return mSkinInfo->mHash or 0 if mSkinInfo is null +    U64 getSkinHash();  private:  	LLPointer<LLVertexBuffer> mVertexBuffer; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index a19d6d0b19..c5a3ff44b3 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1956,7 +1956,7 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat  		LLMeshSkinInfo info(skin);  		info.mMeshID = mesh_id; -		// LL_DEBUGS(LOG_MESH) << "info pelvis offset" << info.mPelvisOffset << LL_ENDL; +        // LL_DEBUGS(LOG_MESH) << "info pelvis offset" << info.mPelvisOffset << LL_ENDL;  		{  			LLMutexLock lock(mMutex);  			mSkinInfoQ.push_back(info); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 30b7124550..332fa73944 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -2901,8 +2901,24 @@ void renderBatchSize(LLDrawInfo* params)  {  	LLGLEnable offset(GL_POLYGON_OFFSET_FILL);  	glPolygonOffset(-1.f, 1.f); -	gGL.diffuseColor4ubv((GLubyte*) &(params->mDebugColor)); -	pushVerts(params, LLVertexBuffer::MAP_VERTEX); +    LLGLSLShader* old_shader = LLGLSLShader::sCurBoundShaderPtr; +    U32 mask = LLVertexBuffer::MAP_VERTEX; +    bool bind = false; +    if (params->mAvatar) +    {  +        bind = true; +        old_shader->mRiggedVariant->bind(); +        LLRenderPass::uploadMatrixPalette(*params); +        mask |= LLVertexBuffer::MAP_WEIGHT4; +    } +	 +    gGL.diffuseColor4ubv((GLubyte*)&(params->mDebugColor)); +	pushVerts(params, mask); + +    if (bind) +    { +        old_shader->bind(); +    }  }  void renderShadowFrusta(LLDrawInfo* params) @@ -4085,6 +4101,11 @@ void LLDrawInfo::validate()  	mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);  } +U64 LLDrawInfo::getSkinHash() +{ +    return mSkinInfo ? mSkinInfo->mHash : 0; +} +  LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage)  {  	return new LLVertexBuffer(type_mask, usage); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 8cc50e71b1..5fca516f19 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -82,6 +82,9 @@ public:  	void validate(); +    // return mSkinHash->mHash, or 0 if mSkinHash is null +    U64 getSkinHash(); +  	LLVector4a mExtents[2];  	LLPointer<LLVertexBuffer> mVertexBuffer; @@ -120,6 +123,8 @@ public:  	F32  mAlphaMaskCutoff;  	U8   mDiffuseAlphaMode;  	bool mSelected; +    LLVOAvatar* mAvatar = nullptr; +    LLMeshSkinInfo* mSkinInfo = nullptr;  	struct CompareTexture @@ -647,7 +652,7 @@ class LLVolumeGeometryManager: public LLGeometryManager  	virtual void rebuildGeom(LLSpatialGroup* group);  	virtual void rebuildMesh(LLSpatialGroup* group);  	virtual void getGeometry(LLSpatialGroup* group); -	U32 genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL no_materials = FALSE); +	U32 genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL rigged = FALSE);  	void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);  private: @@ -655,13 +660,13 @@ private:  	void freeFaces();  	static int32_t sInstanceCount; -	static LLFace** sFullbrightFaces; -	static LLFace** sBumpFaces; -	static LLFace** sSimpleFaces; -	static LLFace** sNormFaces; -	static LLFace** sSpecFaces; -	static LLFace** sNormSpecFaces; -	static LLFace** sAlphaFaces; +	static LLFace** sFullbrightFaces[2]; +	static LLFace** sBumpFaces[2]; +	static LLFace** sSimpleFaces[2]; +	static LLFace** sNormFaces[2]; +	static LLFace** sSpecFaces[2]; +	static LLFace** sNormSpecFaces[2]; +	static LLFace** sAlphaFaces[2];  };  //spatial partition that uses volume geometry manager (implemented in LLVOVolume.cpp) diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 6368286f6e..38ac4275cf 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -578,8 +578,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  	//  	LLAppViewer::instance()->pingMainloopTimeout("Display:Camera"); -	LLViewerCamera::getInstance()->setZoomParameters(zoom_factor, subfield); -	LLViewerCamera::getInstance()->setNear(MIN_NEAR_PLANE); +    if (LLViewerCamera::instanceExists()) +    { +        LLViewerCamera::getInstance()->setZoomParameters(zoom_factor, subfield); +        LLViewerCamera::getInstance()->setNear(MIN_NEAR_PLANE); +    }  	//////////////////////////  	// diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index b34c5b1188..a1f532dd35 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -77,6 +77,7 @@ LLGLSLShader			gTransformTangentProgram;  //utility shaders  LLGLSLShader	gOcclusionProgram; +LLGLSLShader    gSkinnedOcclusionProgram;  LLGLSLShader	gOcclusionCubeProgram;  LLGLSLShader	gCustomAlphaProgram;  LLGLSLShader	gGlowCombineProgram; @@ -87,6 +88,7 @@ LLGLSLShader	gTwoTextureCompareProgram;  LLGLSLShader	gOneTextureFilterProgram;  LLGLSLShader	gOneTextureNoColorProgram;  LLGLSLShader	gDebugProgram; +LLGLSLShader    gSkinnedDebugProgram;  LLGLSLShader	gClipProgram;  LLGLSLShader	gDownsampleDepthProgram;  LLGLSLShader	gDownsampleDepthRectProgram; @@ -96,56 +98,49 @@ LLGLSLShader	gBenchmarkProgram;  //object shaders  LLGLSLShader		gObjectSimpleProgram; +LLGLSLShader        gSkinnedObjectSimpleProgram;  LLGLSLShader		gObjectSimpleImpostorProgram; +LLGLSLShader        gSkinnedObjectSimpleImpostorProgram;  LLGLSLShader		gObjectPreviewProgram;  LLGLSLShader		gObjectSimpleWaterProgram; +LLGLSLShader        gSkinnedObjectSimpleWaterProgram;  LLGLSLShader		gObjectSimpleAlphaMaskProgram; +LLGLSLShader        gSkinnedObjectSimpleAlphaMaskProgram;  LLGLSLShader		gObjectSimpleWaterAlphaMaskProgram; +LLGLSLShader        gSkinnedObjectSimpleWaterAlphaMaskProgram;  LLGLSLShader		gObjectFullbrightProgram; +LLGLSLShader        gSkinnedObjectFullbrightProgram;  LLGLSLShader		gObjectFullbrightWaterProgram; +LLGLSLShader        gSkinnedObjectFullbrightWaterProgram;  LLGLSLShader		gObjectEmissiveProgram; +LLGLSLShader        gSkinnedObjectEmissiveProgram;  LLGLSLShader		gObjectEmissiveWaterProgram; +LLGLSLShader        gSkinnedObjectEmissiveWaterProgram;  LLGLSLShader		gObjectFullbrightAlphaMaskProgram; +LLGLSLShader        gSkinnedObjectFullbrightAlphaMaskProgram;  LLGLSLShader		gObjectFullbrightWaterAlphaMaskProgram; +LLGLSLShader        gSkinnedObjectFullbrightWaterAlphaMaskProgram;  LLGLSLShader		gObjectFullbrightShinyProgram; +LLGLSLShader        gSkinnedObjectFullbrightShinyProgram;  LLGLSLShader		gObjectFullbrightShinyWaterProgram; +LLGLSLShader        gSkinnedObjectFullbrightShinyWaterProgram;  LLGLSLShader		gObjectShinyProgram; +LLGLSLShader        gSkinnedObjectShinyProgram;  LLGLSLShader		gObjectShinyWaterProgram; +LLGLSLShader        gSkinnedObjectShinyWaterProgram;  LLGLSLShader		gObjectBumpProgram; +LLGLSLShader        gSkinnedObjectBumpProgram;  LLGLSLShader		gTreeProgram;  LLGLSLShader		gTreeWaterProgram;  LLGLSLShader		gObjectFullbrightNoColorProgram;  LLGLSLShader		gObjectFullbrightNoColorWaterProgram; -LLGLSLShader		gObjectSimpleNonIndexedProgram;  LLGLSLShader		gObjectSimpleNonIndexedTexGenProgram;  LLGLSLShader		gObjectSimpleNonIndexedTexGenWaterProgram; -LLGLSLShader		gObjectSimpleNonIndexedWaterProgram;  LLGLSLShader		gObjectAlphaMaskNonIndexedProgram;  LLGLSLShader		gObjectAlphaMaskNonIndexedWaterProgram;  LLGLSLShader		gObjectAlphaMaskNoColorProgram;  LLGLSLShader		gObjectAlphaMaskNoColorWaterProgram; -LLGLSLShader		gObjectFullbrightNonIndexedProgram; -LLGLSLShader		gObjectFullbrightNonIndexedWaterProgram; -LLGLSLShader		gObjectEmissiveNonIndexedProgram; -LLGLSLShader		gObjectEmissiveNonIndexedWaterProgram; -LLGLSLShader		gObjectFullbrightShinyNonIndexedProgram; -LLGLSLShader		gObjectFullbrightShinyNonIndexedWaterProgram; -LLGLSLShader		gObjectShinyNonIndexedProgram; -LLGLSLShader		gObjectShinyNonIndexedWaterProgram; - -//object hardware skinning shaders -LLGLSLShader		gSkinnedObjectSimpleProgram; -LLGLSLShader		gSkinnedObjectFullbrightProgram; -LLGLSLShader		gSkinnedObjectEmissiveProgram; -LLGLSLShader		gSkinnedObjectFullbrightShinyProgram; -LLGLSLShader		gSkinnedObjectShinySimpleProgram; - -LLGLSLShader		gSkinnedObjectSimpleWaterProgram; -LLGLSLShader		gSkinnedObjectFullbrightWaterProgram; -LLGLSLShader		gSkinnedObjectEmissiveWaterProgram; -LLGLSLShader		gSkinnedObjectFullbrightShinyWaterProgram; -LLGLSLShader		gSkinnedObjectShinySimpleWaterProgram;  //environment shaders  LLGLSLShader		gTerrainProgram; @@ -191,17 +186,18 @@ LLGLSLShader			gDeferredWaterProgram;  LLGLSLShader			gDeferredUnderWaterProgram;  LLGLSLShader			gDeferredDiffuseProgram;  LLGLSLShader			gDeferredDiffuseAlphaMaskProgram; +LLGLSLShader            gDeferredSkinnedDiffuseAlphaMaskProgram;  LLGLSLShader			gDeferredNonIndexedDiffuseProgram;  LLGLSLShader			gDeferredNonIndexedDiffuseAlphaMaskProgram;  LLGLSLShader			gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;  LLGLSLShader			gDeferredSkinnedDiffuseProgram;  LLGLSLShader			gDeferredSkinnedBumpProgram; -LLGLSLShader			gDeferredSkinnedAlphaProgram;  LLGLSLShader			gDeferredBumpProgram;  LLGLSLShader			gDeferredTerrainProgram;  LLGLSLShader            gDeferredTerrainWaterProgram;  LLGLSLShader			gDeferredTreeProgram;  LLGLSLShader			gDeferredTreeShadowProgram; +LLGLSLShader            gDeferredSkinnedTreeShadowProgram;  LLGLSLShader			gDeferredAvatarProgram;  LLGLSLShader			gDeferredAvatarAlphaProgram;  LLGLSLShader			gDeferredLightProgram; @@ -213,9 +209,12 @@ LLGLSLShader			gDeferredBlurLightProgram;  LLGLSLShader			gDeferredSoftenProgram;  LLGLSLShader			gDeferredSoftenWaterProgram;  LLGLSLShader			gDeferredShadowProgram; +LLGLSLShader            gDeferredSkinnedShadowProgram;  LLGLSLShader			gDeferredShadowCubeProgram;  LLGLSLShader			gDeferredShadowAlphaMaskProgram; +LLGLSLShader            gDeferredSkinnedShadowAlphaMaskProgram;  LLGLSLShader			gDeferredShadowFullbrightAlphaMaskProgram; +LLGLSLShader            gDeferredSkinnedShadowFullbrightAlphaMaskProgram;  LLGLSLShader			gDeferredAvatarShadowProgram;  LLGLSLShader			gDeferredAvatarAlphaShadowProgram;  LLGLSLShader			gDeferredAvatarAlphaMaskShadowProgram; @@ -223,14 +222,20 @@ LLGLSLShader			gDeferredAttachmentShadowProgram;  LLGLSLShader			gDeferredAttachmentAlphaShadowProgram;  LLGLSLShader			gDeferredAttachmentAlphaMaskShadowProgram;  LLGLSLShader			gDeferredAlphaProgram; +LLGLSLShader            gDeferredSkinnedAlphaProgram;  LLGLSLShader			gDeferredAlphaImpostorProgram; +LLGLSLShader            gDeferredSkinnedAlphaImpostorProgram;  LLGLSLShader			gDeferredAlphaWaterProgram; +LLGLSLShader            gDeferredSkinnedAlphaWaterProgram;  LLGLSLShader			gDeferredAvatarEyesProgram;  LLGLSLShader			gDeferredFullbrightProgram;  LLGLSLShader			gDeferredFullbrightAlphaMaskProgram;  LLGLSLShader			gDeferredFullbrightWaterProgram; +LLGLSLShader            gDeferredSkinnedFullbrightWaterProgram;  LLGLSLShader			gDeferredFullbrightAlphaMaskWaterProgram; +LLGLSLShader            gDeferredSkinnedFullbrightAlphaMaskWaterProgram;  LLGLSLShader			gDeferredEmissiveProgram; +LLGLSLShader            gDeferredSkinnedEmissiveProgram;  LLGLSLShader			gDeferredPostProgram;  LLGLSLShader			gDeferredCoFProgram;  LLGLSLShader			gDeferredDoFCombineProgram; @@ -243,14 +248,29 @@ LLGLSLShader			gDeferredWLSunProgram;  LLGLSLShader			gDeferredWLMoonProgram;  LLGLSLShader			gDeferredStarProgram;  LLGLSLShader			gDeferredFullbrightShinyProgram; -LLGLSLShader			gDeferredSkinnedFullbrightShinyProgram; +LLGLSLShader            gDeferredSkinnedFullbrightShinyProgram;  LLGLSLShader			gDeferredSkinnedFullbrightProgram; +LLGLSLShader            gDeferredSkinnedFullbrightAlphaMaskProgram;  LLGLSLShader			gNormalMapGenProgram;  // Deferred materials shaders  LLGLSLShader			gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];  LLGLSLShader			gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2]; +//helper for making a rigged variant of a given shader +bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader) +{ +    riggedShader.mName = llformat("Skinned %s", shader.mName.c_str()); +    riggedShader.mFeatures = shader.mFeatures; +    riggedShader.mFeatures.hasObjectSkinning = true; +    riggedShader.addPermutation("HAS_SKIN", "1"); +    riggedShader.mShaderFiles = shader.mShaderFiles; +    riggedShader.mShaderLevel = shader.mShaderLevel; +    riggedShader.mShaderGroup = shader.mShaderGroup; +    shader.mRiggedVariant = &riggedShader; +    return riggedShader.createShader(NULL, NULL); +} +  LLViewerShaderMgr::LLViewerShaderMgr() :  	mShaderLevel(SHADER_COUNT, 0),  	mMaxAvatarShaderLevel(0) @@ -263,75 +283,77 @@ LLViewerShaderMgr::LLViewerShaderMgr() :  	mShaderList.push_back(&gWLMoonProgram);  	mShaderList.push_back(&gAvatarProgram);  	mShaderList.push_back(&gObjectShinyProgram); -	mShaderList.push_back(&gObjectShinyNonIndexedProgram); +    mShaderList.push_back(&gSkinnedObjectShinyProgram);  	mShaderList.push_back(&gWaterProgram);  	mShaderList.push_back(&gWaterEdgeProgram);  	mShaderList.push_back(&gAvatarEyeballProgram);   	mShaderList.push_back(&gObjectSimpleProgram); +    mShaderList.push_back(&gSkinnedObjectSimpleProgram);  	mShaderList.push_back(&gObjectSimpleImpostorProgram); +    mShaderList.push_back(&gSkinnedObjectSimpleImpostorProgram);  	mShaderList.push_back(&gObjectPreviewProgram);  	mShaderList.push_back(&gImpostorProgram);  	mShaderList.push_back(&gObjectFullbrightNoColorProgram);  	mShaderList.push_back(&gObjectFullbrightNoColorWaterProgram);  	mShaderList.push_back(&gObjectSimpleAlphaMaskProgram); +    mShaderList.push_back(&gSkinnedObjectSimpleAlphaMaskProgram);  	mShaderList.push_back(&gObjectBumpProgram); +    mShaderList.push_back(&gSkinnedObjectBumpProgram);  	mShaderList.push_back(&gObjectEmissiveProgram); +    mShaderList.push_back(&gSkinnedObjectEmissiveProgram);  	mShaderList.push_back(&gObjectEmissiveWaterProgram); +    mShaderList.push_back(&gSkinnedObjectEmissiveWaterProgram);  	mShaderList.push_back(&gObjectFullbrightProgram); +    mShaderList.push_back(&gSkinnedObjectFullbrightProgram);  	mShaderList.push_back(&gObjectFullbrightAlphaMaskProgram); +    mShaderList.push_back(&gSkinnedObjectFullbrightAlphaMaskProgram);  	mShaderList.push_back(&gObjectFullbrightShinyProgram); +    mShaderList.push_back(&gSkinnedObjectFullbrightShinyProgram);  	mShaderList.push_back(&gObjectFullbrightShinyWaterProgram); -	mShaderList.push_back(&gObjectSimpleNonIndexedProgram); +    mShaderList.push_back(&gSkinnedObjectFullbrightShinyWaterProgram);  	mShaderList.push_back(&gObjectSimpleNonIndexedTexGenProgram);  	mShaderList.push_back(&gObjectSimpleNonIndexedTexGenWaterProgram); -	mShaderList.push_back(&gObjectSimpleNonIndexedWaterProgram);  	mShaderList.push_back(&gObjectAlphaMaskNonIndexedProgram);  	mShaderList.push_back(&gObjectAlphaMaskNonIndexedWaterProgram);  	mShaderList.push_back(&gObjectAlphaMaskNoColorProgram);  	mShaderList.push_back(&gObjectAlphaMaskNoColorWaterProgram);  	mShaderList.push_back(&gTreeProgram);  	mShaderList.push_back(&gTreeWaterProgram); -	mShaderList.push_back(&gObjectFullbrightNonIndexedProgram); -	mShaderList.push_back(&gObjectFullbrightNonIndexedWaterProgram); -	mShaderList.push_back(&gObjectEmissiveNonIndexedProgram); -	mShaderList.push_back(&gObjectEmissiveNonIndexedWaterProgram); -	mShaderList.push_back(&gObjectFullbrightShinyNonIndexedProgram); -	mShaderList.push_back(&gObjectFullbrightShinyNonIndexedWaterProgram); -	mShaderList.push_back(&gSkinnedObjectSimpleProgram); -	mShaderList.push_back(&gSkinnedObjectFullbrightProgram); -	mShaderList.push_back(&gSkinnedObjectEmissiveProgram); -	mShaderList.push_back(&gSkinnedObjectFullbrightShinyProgram); -	mShaderList.push_back(&gSkinnedObjectShinySimpleProgram); -	mShaderList.push_back(&gSkinnedObjectSimpleWaterProgram); -	mShaderList.push_back(&gSkinnedObjectFullbrightWaterProgram); -	mShaderList.push_back(&gSkinnedObjectEmissiveWaterProgram); -	mShaderList.push_back(&gSkinnedObjectFullbrightShinyWaterProgram); -	mShaderList.push_back(&gSkinnedObjectShinySimpleWaterProgram);  	mShaderList.push_back(&gTerrainProgram);  	mShaderList.push_back(&gTerrainWaterProgram);  	mShaderList.push_back(&gObjectSimpleWaterProgram); +    mShaderList.push_back(&gSkinnedObjectSimpleWaterProgram);  	mShaderList.push_back(&gObjectFullbrightWaterProgram); +    mShaderList.push_back(&gSkinnedObjectFullbrightWaterProgram);  	mShaderList.push_back(&gObjectSimpleWaterAlphaMaskProgram); +    mShaderList.push_back(&gSkinnedObjectSimpleWaterAlphaMaskProgram);  	mShaderList.push_back(&gObjectFullbrightWaterAlphaMaskProgram); +    mShaderList.push_back(&gSkinnedObjectFullbrightWaterAlphaMaskProgram);  	mShaderList.push_back(&gAvatarWaterProgram);  	mShaderList.push_back(&gObjectShinyWaterProgram); -	mShaderList.push_back(&gObjectShinyNonIndexedWaterProgram); +    mShaderList.push_back(&gSkinnedObjectShinyWaterProgram);  	mShaderList.push_back(&gUnderWaterProgram);  	mShaderList.push_back(&gDeferredSunProgram);  	mShaderList.push_back(&gDeferredSoftenProgram);  	mShaderList.push_back(&gDeferredSoftenWaterProgram);  	mShaderList.push_back(&gDeferredAlphaProgram); +    mShaderList.push_back(&gDeferredSkinnedAlphaProgram);  	mShaderList.push_back(&gDeferredAlphaImpostorProgram); +    mShaderList.push_back(&gDeferredSkinnedAlphaImpostorProgram);  	mShaderList.push_back(&gDeferredAlphaWaterProgram); -	mShaderList.push_back(&gDeferredSkinnedAlphaProgram); +    mShaderList.push_back(&gDeferredSkinnedAlphaWaterProgram);  	mShaderList.push_back(&gDeferredFullbrightProgram);  	mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram);  	mShaderList.push_back(&gDeferredFullbrightWaterProgram); -	mShaderList.push_back(&gDeferredFullbrightAlphaMaskWaterProgram);	 +    mShaderList.push_back(&gDeferredSkinnedFullbrightWaterProgram); +	mShaderList.push_back(&gDeferredFullbrightAlphaMaskWaterProgram); +    mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskWaterProgram);  	mShaderList.push_back(&gDeferredFullbrightShinyProgram); -	mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram); +    mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram);  	mShaderList.push_back(&gDeferredSkinnedFullbrightProgram); +    mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskProgram);  	mShaderList.push_back(&gDeferredEmissiveProgram); +    mShaderList.push_back(&gDeferredSkinnedEmissiveProgram);  	mShaderList.push_back(&gDeferredAvatarEyesProgram);  	mShaderList.push_back(&gDeferredWaterProgram);  	mShaderList.push_back(&gDeferredUnderWaterProgram);	 @@ -732,8 +754,10 @@ void LLViewerShaderMgr::setShaders()  void LLViewerShaderMgr::unloadShaders()  {  	gOcclusionProgram.unload(); +    gSkinnedOcclusionProgram.unload();  	gOcclusionCubeProgram.unload();  	gDebugProgram.unload(); +    gSkinnedDebugProgram.unload();  	gClipProgram.unload();  	gDownsampleDepthProgram.unload();  	gDownsampleDepthRectProgram.unload(); @@ -755,58 +779,50 @@ void LLViewerShaderMgr::unloadShaders()  	gObjectFullbrightNoColorProgram.unload();  	gObjectFullbrightNoColorWaterProgram.unload();  	gObjectSimpleProgram.unload(); +    gSkinnedObjectSimpleProgram.unload();  	gObjectSimpleImpostorProgram.unload(); +    gSkinnedObjectSimpleImpostorProgram.unload();  	gObjectPreviewProgram.unload();  	gImpostorProgram.unload();  	gObjectSimpleAlphaMaskProgram.unload(); +    gSkinnedObjectSimpleAlphaMaskProgram.unload();  	gObjectBumpProgram.unload(); +    gSkinnedObjectBumpProgram.unload();  	gObjectSimpleWaterProgram.unload(); +    gSkinnedObjectSimpleWaterProgram.unload();  	gObjectSimpleWaterAlphaMaskProgram.unload(); +    gSkinnedObjectSimpleWaterAlphaMaskProgram.unload();  	gObjectFullbrightProgram.unload(); +    gSkinnedObjectFullbrightProgram.unload();  	gObjectFullbrightWaterProgram.unload(); +    gSkinnedObjectFullbrightWaterProgram.unload();  	gObjectEmissiveProgram.unload(); +    gSkinnedObjectEmissiveProgram.unload();  	gObjectEmissiveWaterProgram.unload(); +    gSkinnedObjectEmissiveWaterProgram.unload();  	gObjectFullbrightAlphaMaskProgram.unload(); +    gSkinnedObjectFullbrightAlphaMaskProgram.unload();  	gObjectFullbrightWaterAlphaMaskProgram.unload(); +    gSkinnedObjectFullbrightWaterAlphaMaskProgram.unload();  	gObjectShinyProgram.unload(); +    gSkinnedObjectShinyProgram.unload();  	gObjectFullbrightShinyProgram.unload(); +    gSkinnedObjectFullbrightShinyProgram.unload();  	gObjectFullbrightShinyWaterProgram.unload(); +    gSkinnedObjectFullbrightShinyWaterProgram.unload();  	gObjectShinyWaterProgram.unload(); +    gSkinnedObjectShinyWaterProgram.unload(); -	gObjectSimpleNonIndexedProgram.unload();  	gObjectSimpleNonIndexedTexGenProgram.unload();  	gObjectSimpleNonIndexedTexGenWaterProgram.unload(); -	gObjectSimpleNonIndexedWaterProgram.unload();  	gObjectAlphaMaskNonIndexedProgram.unload();  	gObjectAlphaMaskNonIndexedWaterProgram.unload();  	gObjectAlphaMaskNoColorProgram.unload();  	gObjectAlphaMaskNoColorWaterProgram.unload(); -	gObjectFullbrightNonIndexedProgram.unload(); -	gObjectFullbrightNonIndexedWaterProgram.unload(); -	gObjectEmissiveNonIndexedProgram.unload(); -	gObjectEmissiveNonIndexedWaterProgram.unload();  	gTreeProgram.unload();  	gTreeWaterProgram.unload(); -	gObjectShinyNonIndexedProgram.unload(); -	gObjectFullbrightShinyNonIndexedProgram.unload(); -	gObjectFullbrightShinyNonIndexedWaterProgram.unload(); -	gObjectShinyNonIndexedWaterProgram.unload(); - -	gSkinnedObjectSimpleProgram.unload(); -	gSkinnedObjectFullbrightProgram.unload(); -	gSkinnedObjectEmissiveProgram.unload(); -	gSkinnedObjectFullbrightShinyProgram.unload(); -	gSkinnedObjectShinySimpleProgram.unload(); -	 -	gSkinnedObjectSimpleWaterProgram.unload(); -	gSkinnedObjectFullbrightWaterProgram.unload(); -	gSkinnedObjectEmissiveWaterProgram.unload(); -	gSkinnedObjectFullbrightShinyWaterProgram.unload(); -	gSkinnedObjectShinySimpleWaterProgram.unload(); -	 -  	gWaterProgram.unload();      gWaterEdgeProgram.unload();  	gUnderWaterProgram.unload(); @@ -832,13 +848,13 @@ void LLViewerShaderMgr::unloadShaders()  	gDeferredDiffuseProgram.unload();  	gDeferredDiffuseAlphaMaskProgram.unload(); +    gDeferredSkinnedDiffuseAlphaMaskProgram.unload();  	gDeferredNonIndexedDiffuseAlphaMaskProgram.unload();  	gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload();  	gDeferredNonIndexedDiffuseProgram.unload();  	gDeferredSkinnedDiffuseProgram.unload();  	gDeferredSkinnedBumpProgram.unload(); -	gDeferredSkinnedAlphaProgram.unload(); - +	  	gTransformPositionProgram.unload();  	gTransformTexCoordProgram.unload();  	gTransformNormalProgram.unload(); @@ -915,7 +931,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders()  	}  	shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl",        1 ) ); -	boost::unordered_map<std::string, std::string> attribs; +	std::unordered_map<std::string, std::string> attribs;  	attribs["MAX_JOINTS_PER_MESH_OBJECT"] =   		boost::lexical_cast<std::string>(LLSkinningUtil::getMaxJointCount()); @@ -1227,14 +1243,15 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	{  		gDeferredTreeProgram.unload();  		gDeferredTreeShadowProgram.unload(); +        gDeferredSkinnedTreeShadowProgram.unload();  		gDeferredDiffuseProgram.unload();  		gDeferredDiffuseAlphaMaskProgram.unload(); +        gDeferredSkinnedDiffuseAlphaMaskProgram.unload();  		gDeferredNonIndexedDiffuseAlphaMaskProgram.unload();  		gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload();  		gDeferredNonIndexedDiffuseProgram.unload();  		gDeferredSkinnedDiffuseProgram.unload();  		gDeferredSkinnedBumpProgram.unload(); -		gDeferredSkinnedAlphaProgram.unload();  		gDeferredBumpProgram.unload();  		gDeferredImpostorProgram.unload();  		gDeferredTerrainProgram.unload(); @@ -1251,9 +1268,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSoftenProgram.unload();  		gDeferredSoftenWaterProgram.unload();  		gDeferredShadowProgram.unload(); +        gDeferredSkinnedShadowProgram.unload();  		gDeferredShadowCubeProgram.unload();          gDeferredShadowAlphaMaskProgram.unload(); +        gDeferredSkinnedShadowAlphaMaskProgram.unload();          gDeferredShadowFullbrightAlphaMaskProgram.unload(); +        gDeferredSkinnedShadowFullbrightAlphaMaskProgram.unload();  		gDeferredAvatarShadowProgram.unload();          gDeferredAvatarAlphaShadowProgram.unload();          gDeferredAvatarAlphaMaskShadowProgram.unload(); @@ -1263,12 +1283,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAvatarProgram.unload();  		gDeferredAvatarAlphaProgram.unload();  		gDeferredAlphaProgram.unload(); +        gDeferredSkinnedAlphaProgram.unload();  		gDeferredAlphaWaterProgram.unload(); +        gDeferredSkinnedAlphaWaterProgram.unload();  		gDeferredFullbrightProgram.unload();  		gDeferredFullbrightAlphaMaskProgram.unload();  		gDeferredFullbrightWaterProgram.unload(); +        gDeferredSkinnedFullbrightWaterProgram.unload();  		gDeferredFullbrightAlphaMaskWaterProgram.unload(); +        gDeferredSkinnedFullbrightAlphaMaskWaterProgram.unload();  		gDeferredEmissiveProgram.unload(); +        gDeferredSkinnedEmissiveProgram.unload();  		gDeferredAvatarEyesProgram.unload();  		gDeferredPostProgram.unload();		  		gDeferredCoFProgram.unload();		 @@ -1283,8 +1308,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()          gDeferredWLMoonProgram.unload();  		gDeferredStarProgram.unload();  		gDeferredFullbrightShinyProgram.unload(); -		gDeferredSkinnedFullbrightShinyProgram.unload(); +        gDeferredSkinnedFullbrightShinyProgram.unload();  		gDeferredSkinnedFullbrightProgram.unload(); +        gDeferredSkinnedFullbrightAlphaMaskProgram.unload();          gDeferredHighlightProgram.unload();          gDeferredHighlightNormalProgram.unload(); @@ -1341,7 +1367,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredDiffuseProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;  		gDeferredDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; -		success = gDeferredDiffuseProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gDeferredDiffuseProgram, gDeferredSkinnedDiffuseProgram); +		success = success && gDeferredDiffuseProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1353,7 +1380,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredDiffuseAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;  		gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; -		success = gDeferredDiffuseAlphaMaskProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gDeferredDiffuseAlphaMaskProgram, gDeferredSkinnedDiffuseAlphaMaskProgram); +		success = success && gDeferredDiffuseAlphaMaskProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1395,94 +1423,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ -		gDeferredSkinnedDiffuseProgram.mName = "Deferred Skinned Diffuse Shader"; -		gDeferredSkinnedDiffuseProgram.mFeatures.hasObjectSkinning = true; -		gDeferredSkinnedDiffuseProgram.mFeatures.encodesNormal = true; -        gDeferredSkinnedDiffuseProgram.mFeatures.hasSrgb = true; -		gDeferredSkinnedDiffuseProgram.mShaderFiles.clear(); -		gDeferredSkinnedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredSkinnedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredSkinnedDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; -		success = gDeferredSkinnedDiffuseProgram.createShader(NULL, NULL); -		llassert(success); -	} - -	if (success) -	{ -		gDeferredSkinnedBumpProgram.mName = "Deferred Skinned Bump Shader"; -		gDeferredSkinnedBumpProgram.mFeatures.hasObjectSkinning = true; -        gDeferredSkinnedBumpProgram.mFeatures.encodesNormal = true; -		gDeferredSkinnedBumpProgram.mShaderFiles.clear(); -		gDeferredSkinnedBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredSkinnedBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredSkinnedBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; -		success = gDeferredSkinnedBumpProgram.createShader(NULL, NULL); -        llassert(success); -	} - -	if (success) -	{ -		gDeferredSkinnedAlphaProgram.mName = "Deferred Skinned Alpha Shader"; -		gDeferredSkinnedAlphaProgram.mFeatures.hasObjectSkinning = true; -		gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = false; -		gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = false; -		gDeferredSkinnedAlphaProgram.mFeatures.isAlphaLighting = true; -		gDeferredSkinnedAlphaProgram.mFeatures.disableTextureIndex = true; -		gDeferredSkinnedAlphaProgram.mFeatures.hasSrgb = true; -		gDeferredSkinnedAlphaProgram.mFeatures.encodesNormal = true; -		gDeferredSkinnedAlphaProgram.mFeatures.calculatesAtmospherics = true; -		gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true; -		gDeferredSkinnedAlphaProgram.mFeatures.hasTransport = true; -		gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = true; -		gDeferredSkinnedAlphaProgram.mFeatures.hasShadows = true; -         -		gDeferredSkinnedAlphaProgram.mShaderFiles.clear(); -		gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredSkinnedAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - -		gDeferredSkinnedAlphaProgram.clearPermutations(); -		gDeferredSkinnedAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1"); -		gDeferredSkinnedAlphaProgram.addPermutation("HAS_SKIN", "1"); -        gDeferredSkinnedAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1"); - -		if (use_sun_shadow) -		{ -			gDeferredSkinnedAlphaProgram.addPermutation("HAS_SHADOW", "1"); -		} - -        if (ambient_kill) -        { -            gDeferredSkinnedAlphaProgram.addPermutation("AMBIENT_KILL", "1"); -        } - -        if (sunlight_kill) -        { -            gDeferredSkinnedAlphaProgram.addPermutation("SUNLIGHT_KILL", "1"); -        } - -        if (local_light_kill) -        { -            gDeferredSkinnedAlphaProgram.addPermutation("LOCAL_LIGHT_KILL", "1"); -        } - -		success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL); -		llassert(success); - -		// Hack to include uniforms for lighting without linking in lighting file -		gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = true; -		gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = true; -	} - -	if (success) -	{  		gDeferredBumpProgram.mName = "Deferred Bump Shader";  		gDeferredBumpProgram.mFeatures.encodesNormal = true;  		gDeferredBumpProgram.mShaderFiles.clear();  		gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; -		success = gDeferredBumpProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gDeferredBumpProgram, gDeferredSkinnedBumpProgram); +		success = success && gDeferredBumpProgram.createShader(NULL, NULL);  		llassert(success);  	} @@ -1570,6 +1518,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()                  gDeferredMaterialProgram[i].addPermutation("HAS_SKIN", "1");                  gDeferredMaterialProgram[i].mFeatures.hasObjectSkinning = true;              } +            else +            { +                gDeferredMaterialProgram[i].mRiggedVariant = &gDeferredMaterialProgram[i + 0x10]; +            }              success = gDeferredMaterialProgram[i].createShader(NULL, NULL);              llassert(success); @@ -1615,6 +1567,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()              {                  gDeferredMaterialWaterProgram[i].addPermutation("HAS_SKIN", "1");              } +            else +            { +                gDeferredMaterialWaterProgram[i].mRiggedVariant = &(gDeferredMaterialWaterProgram[i + 0x10]); +            }              gDeferredMaterialWaterProgram[i].addPermutation("WATER_FOG","1");              if (ambient_kill) @@ -1691,10 +1647,25 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; +        gDeferredTreeShadowProgram.mRiggedVariant = &gDeferredSkinnedTreeShadowProgram;  		success = gDeferredTreeShadowProgram.createShader(NULL, NULL);          llassert(success);  	} +    if (success) +    { +        gDeferredSkinnedTreeShadowProgram.mName = "Deferred Skinned Tree Shadow Shader"; +        gDeferredSkinnedTreeShadowProgram.mShaderFiles.clear(); +        gDeferredSkinnedTreeShadowProgram.mFeatures.isDeferred = true; +        gDeferredSkinnedTreeShadowProgram.mFeatures.hasShadows = true; +        gDeferredSkinnedTreeShadowProgram.mFeatures.hasObjectSkinning = true; +        gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); +        gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); +        gDeferredSkinnedTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; +        success = gDeferredSkinnedTreeShadowProgram.createShader(NULL, NULL); +        llassert(success); +    } +  	if (success)  	{  		gDeferredImpostorProgram.mName = "Deferred Impostor Shader"; @@ -1883,172 +1854,235 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ -		gDeferredAlphaProgram.mName = "Deferred Alpha Shader"; - -		gDeferredAlphaProgram.mFeatures.calculatesLighting = false; -		gDeferredAlphaProgram.mFeatures.hasLighting = false; -		gDeferredAlphaProgram.mFeatures.isAlphaLighting = true; -		gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels -		gDeferredAlphaProgram.mFeatures.hasSrgb = true; -		gDeferredAlphaProgram.mFeatures.encodesNormal = true; -		gDeferredAlphaProgram.mFeatures.calculatesAtmospherics = true; -        gDeferredAlphaProgram.mFeatures.hasAtmospherics = true; -        gDeferredAlphaProgram.mFeatures.hasGamma = true; -        gDeferredAlphaProgram.mFeatures.hasTransport = true; -        gDeferredAlphaProgram.mFeatures.hasShadows = use_sun_shadow; - -        if (mShaderLevel[SHADER_DEFERRED] < 1) +        for (int i = 0; i < 2 && success; ++i)          { -            gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; -        } -        else -        { //shave off some texture units for shadow maps -            gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1); -        } -             -        gDeferredAlphaProgram.mShaderFiles.clear(); -        gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); -        gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); - -        gDeferredAlphaProgram.clearPermutations(); -        gDeferredAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1"); -        gDeferredAlphaProgram.addPermutation("USE_INDEXED_TEX", "1"); -        if (use_sun_shadow) -        { -            gDeferredAlphaProgram.addPermutation("HAS_SHADOW", "1"); -        } +            LLGLSLShader* shader = nullptr; +            bool rigged = i == 1; +            if (!rigged) +            { +                shader = &gDeferredAlphaProgram; +                shader->mName = "Deferred Alpha Shader"; +                shader->mRiggedVariant = &gDeferredSkinnedAlphaProgram; +            } +            else +            { +                shader = &gDeferredSkinnedAlphaProgram; +                shader->mName = "Skinned Deferred Alpha Shader"; +                shader->mFeatures.hasObjectSkinning = true; +            } -        if (ambient_kill) -        { -            gDeferredAlphaProgram.addPermutation("AMBIENT_KILL", "1"); -        } +            shader->mFeatures.calculatesLighting = false; +            shader->mFeatures.hasLighting = false; +            shader->mFeatures.isAlphaLighting = true; +            shader->mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels +            shader->mFeatures.hasSrgb = true; +            shader->mFeatures.encodesNormal = true; +            shader->mFeatures.calculatesAtmospherics = true; +            shader->mFeatures.hasAtmospherics = true; +            shader->mFeatures.hasGamma = true; +            shader->mFeatures.hasTransport = true; +            shader->mFeatures.hasShadows = use_sun_shadow; + +            if (mShaderLevel[SHADER_DEFERRED] < 1) +            { +                shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; +            } +            else +            { //shave off some texture units for shadow maps +                shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1); +            } -        if (sunlight_kill) -        { -            gDeferredAlphaProgram.addPermutation("SUNLIGHT_KILL", "1"); -        } +            shader->mShaderFiles.clear(); +            shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); +            shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); -        if (local_light_kill) -        { -            gDeferredAlphaProgram.addPermutation("LOCAL_LIGHT_KILL", "1"); -        } +            shader->clearPermutations(); +            shader->addPermutation("USE_VERTEX_COLOR", "1"); +            shader->addPermutation("USE_INDEXED_TEX", "1"); +            if (use_sun_shadow) +            { +                shader->addPermutation("HAS_SHADOW", "1"); +            } -        gDeferredAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; +            if (ambient_kill) +            { +                shader->addPermutation("AMBIENT_KILL", "1"); +            } -        success = gDeferredAlphaProgram.createShader(NULL, NULL); -        llassert(success); +            if (sunlight_kill) +            { +                shader->addPermutation("SUNLIGHT_KILL", "1"); +            } -        // Hack -        gDeferredAlphaProgram.mFeatures.calculatesLighting = true; -        gDeferredAlphaProgram.mFeatures.hasLighting = true; +            if (local_light_kill) +            { +                shader->addPermutation("LOCAL_LIGHT_KILL", "1"); +            } + +            if (rigged) +            { +                shader->addPermutation("HAS_SKIN", "1"); +            } + +            shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + +            success = shader->createShader(NULL, NULL); +            llassert(success); + +            // Hack +            shader->mFeatures.calculatesLighting = true; +            shader->mFeatures.hasLighting = true; +        }      }      if (success)      { -        gDeferredAlphaImpostorProgram.mName = "Deferred Alpha Impostor Shader"; +        LLGLSLShader* shaders[] = {  +            &gDeferredAlphaImpostorProgram,  +            &gDeferredSkinnedAlphaImpostorProgram  +        }; -// Begin Hack -		gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = false; -		gDeferredAlphaImpostorProgram.mFeatures.hasLighting = false; +        for (int i = 0; i < 2 && success; ++i) +        { +            bool rigged = i == 1; +            LLGLSLShader* shader = shaders[i]; -        gDeferredAlphaImpostorProgram.mFeatures.hasSrgb = true; -		gDeferredAlphaImpostorProgram.mFeatures.isAlphaLighting = true; -        gDeferredAlphaImpostorProgram.mFeatures.encodesNormal = true; -        gDeferredAlphaImpostorProgram.mFeatures.hasShadows = use_sun_shadow; +            shader->mName = rigged ? "Skinned Deferred Alpha Impostor Shader" : "Deferred Alpha Impostor Shader"; -        if (mShaderLevel[SHADER_DEFERRED] < 1) -        { -            gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; -        } -        else -        { //shave off some texture units for shadow maps -            gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1); -        } +            // Begin Hack +            shader->mFeatures.calculatesLighting = false; +            shader->mFeatures.hasLighting = false; -        gDeferredAlphaImpostorProgram.mShaderFiles.clear(); -        gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); -        gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); +            shader->mFeatures.hasSrgb = true; +            shader->mFeatures.isAlphaLighting = true; +            shader->mFeatures.encodesNormal = true; +            shader->mFeatures.hasShadows = use_sun_shadow; -        gDeferredAlphaImpostorProgram.clearPermutations(); -        gDeferredAlphaImpostorProgram.addPermutation("USE_INDEXED_TEX", "1"); -        gDeferredAlphaImpostorProgram.addPermutation("FOR_IMPOSTOR", "1"); -        gDeferredAlphaImpostorProgram.addPermutation("USE_VERTEX_COLOR", "1"); +            if (mShaderLevel[SHADER_DEFERRED] < 1) +            { +                shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; +            } +            else +            { //shave off some texture units for shadow maps +                shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1); +            } -        if (use_sun_shadow) -        { -            gDeferredAlphaImpostorProgram.addPermutation("HAS_SHADOW", "1"); -        } +            shader->mShaderFiles.clear(); +            shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); +            shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); + +            shader->clearPermutations(); +            shader->addPermutation("USE_INDEXED_TEX", "1"); +            shader->addPermutation("FOR_IMPOSTOR", "1"); +            shader->addPermutation("USE_VERTEX_COLOR", "1"); +            if (rigged) +            { +                shader->mFeatures.hasObjectSkinning = true; +                shader->addPermutation("HAS_SKIN", "1"); +            } -        gDeferredAlphaImpostorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; +            if (use_sun_shadow) +            { +                shader->addPermutation("HAS_SHADOW", "1"); +            } -        success = gDeferredAlphaImpostorProgram.createShader(NULL, NULL); -        llassert(success); +            shader->mRiggedVariant = &gDeferredSkinnedAlphaImpostorProgram; +            shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED]; +            if (!rigged) +            { +                shader->mRiggedVariant = shaders[1]; +            } +            success = shader->createShader(NULL, NULL); +            llassert(success); -// End Hack -        gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = true; -        gDeferredAlphaImpostorProgram.mFeatures.hasLighting = true; +            // End Hack +            shader->mFeatures.calculatesLighting = true; +            shader->mFeatures.hasLighting = true; +        }      } -	if (success) -	{ -		gDeferredAlphaWaterProgram.mName = "Deferred Alpha Underwater Shader"; -		gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = false; -		gDeferredAlphaWaterProgram.mFeatures.hasLighting = false; -		gDeferredAlphaWaterProgram.mFeatures.isAlphaLighting = true; -		gDeferredAlphaWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels -		gDeferredAlphaWaterProgram.mFeatures.hasWaterFog = true; -		gDeferredAlphaWaterProgram.mFeatures.hasSrgb = true; -		gDeferredAlphaWaterProgram.mFeatures.encodesNormal = true; -		gDeferredAlphaWaterProgram.mFeatures.calculatesAtmospherics = true; -		gDeferredAlphaWaterProgram.mFeatures.hasAtmospherics = true; -		gDeferredAlphaWaterProgram.mFeatures.hasGamma = true; -		gDeferredAlphaWaterProgram.mFeatures.hasTransport = true; -		gDeferredAlphaWaterProgram.mFeatures.hasShadows = use_sun_shadow; - -		if (mShaderLevel[SHADER_DEFERRED] < 1) -		{ -			gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; -		} -		else -		{ //shave off some texture units for shadow maps -			gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1); -		} -		gDeferredAlphaWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		gDeferredAlphaWaterProgram.mShaderFiles.clear(); -		gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); - -		gDeferredAlphaWaterProgram.clearPermutations(); -		gDeferredAlphaWaterProgram.addPermutation("USE_INDEXED_TEX", "1"); -		gDeferredAlphaWaterProgram.addPermutation("WATER_FOG", "1"); -        gDeferredAlphaWaterProgram.addPermutation("USE_VERTEX_COLOR", "1"); -		if (use_sun_shadow) -		{ -			gDeferredAlphaWaterProgram.addPermutation("HAS_SHADOW", "1"); -		} +    if (success) +    { +        LLGLSLShader* shader[] = { +            &gDeferredAlphaWaterProgram, +            &gDeferredSkinnedAlphaWaterProgram +        }; +         +        gDeferredAlphaWaterProgram.mRiggedVariant = &gDeferredSkinnedAlphaWaterProgram; +		 +        gDeferredAlphaWaterProgram.mName = "Deferred Alpha Underwater Shader"; +        gDeferredSkinnedAlphaWaterProgram.mName = "Deferred Skinned Alpha Underwater Shader"; -        if (ambient_kill) +        for (int i = 0; i < 2 && success; ++i)          { -            gDeferredAlphaWaterProgram.addPermutation("AMBIENT_KILL", "1"); -        } +            shader[i]->mFeatures.calculatesLighting = false; +            shader[i]->mFeatures.hasLighting = false; +            shader[i]->mFeatures.isAlphaLighting = true; +            shader[i]->mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels +            shader[i]->mFeatures.hasWaterFog = true; +            shader[i]->mFeatures.hasSrgb = true; +            shader[i]->mFeatures.encodesNormal = true; +            shader[i]->mFeatures.calculatesAtmospherics = true; +            shader[i]->mFeatures.hasAtmospherics = true; +            shader[i]->mFeatures.hasGamma = true; +            shader[i]->mFeatures.hasTransport = true; +            shader[i]->mFeatures.hasShadows = use_sun_shadow; + +            if (mShaderLevel[SHADER_DEFERRED] < 1) +            { +                shader[i]->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; +            } +            else +            { //shave off some texture units for shadow maps +                shader[i]->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1); +            } +            shader[i]->mShaderGroup = LLGLSLShader::SG_WATER; +            shader[i]->mShaderFiles.clear(); +            shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); +            shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); + +            shader[i]->clearPermutations(); +            shader[i]->addPermutation("USE_INDEXED_TEX", "1"); +            shader[i]->addPermutation("WATER_FOG", "1"); +            shader[i]->addPermutation("USE_VERTEX_COLOR", "1"); +            if (use_sun_shadow) +            { +                shader[i]->addPermutation("HAS_SHADOW", "1"); +            } -        if (sunlight_kill) -        { -            gDeferredAlphaWaterProgram.addPermutation("SUNLIGHT_KILL", "1"); -        } +            if (ambient_kill) +            { +                shader[i]->addPermutation("AMBIENT_KILL", "1"); +            } -        if (local_light_kill) -        { -            gDeferredAlphaWaterProgram.addPermutation("LOCAL_LIGHT_KILL", "1"); -        } -        gDeferredAlphaWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; +            if (sunlight_kill) +            { +                shader[i]->addPermutation("SUNLIGHT_KILL", "1"); +            } -		success = gDeferredAlphaWaterProgram.createShader(NULL, NULL); -		llassert(success); +            if (local_light_kill) +            { +                shader[i]->addPermutation("LOCAL_LIGHT_KILL", "1"); +            } -		// Hack -		gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = true; -		gDeferredAlphaWaterProgram.mFeatures.hasLighting = true; +            if (i == 1) +            { // rigged variant +                shader[i]->mFeatures.hasObjectSkinning = true; +                shader[i]->addPermutation("HAS_SKIN", "1"); +            } +            else +            { +                shader[i]->mRiggedVariant = shader[1]; +            } +            shader[i]->mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + +            success = shader[i]->createShader(NULL, NULL); +            llassert(success); + +            // Hack +            shader[i]->mFeatures.calculatesLighting = true; +            shader[i]->mFeatures.hasLighting = true; +        }  	}  	if (success) @@ -2082,6 +2116,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; +        success = make_rigged_variant(gDeferredFullbrightProgram, gDeferredSkinnedFullbrightProgram);  		success = gDeferredFullbrightProgram.createShader(NULL, NULL);  		llassert(success);  	} @@ -2099,7 +2134,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK","1");  		gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; -		success = gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gDeferredFullbrightAlphaMaskProgram, gDeferredSkinnedFullbrightAlphaMaskProgram); +		success = success && gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL);  		llassert(success);  	} @@ -2118,10 +2154,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];  		gDeferredFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		gDeferredFullbrightWaterProgram.addPermutation("WATER_FOG","1"); -		success = gDeferredFullbrightWaterProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gDeferredFullbrightWaterProgram, gDeferredSkinnedFullbrightWaterProgram); +		success = success && gDeferredFullbrightWaterProgram.createShader(NULL, NULL);  		llassert(success);  	} - +      	if (success)  	{  		gDeferredFullbrightAlphaMaskWaterProgram.mName = "Deferred Fullbright Underwater Alpha Masking Shader"; @@ -2138,7 +2175,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredFullbrightAlphaMaskWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;  		gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("HAS_ALPHA_MASK","1");  		gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("WATER_FOG","1"); -		success = gDeferredFullbrightAlphaMaskWaterProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gDeferredFullbrightAlphaMaskWaterProgram, gDeferredSkinnedFullbrightAlphaMaskWaterProgram); +		success = success && gDeferredFullbrightAlphaMaskWaterProgram.createShader(NULL, NULL);  		llassert(success);  	} @@ -2155,43 +2193,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; -		success = gDeferredFullbrightShinyProgram.createShader(NULL, NULL); -		llassert(success); -	} - -	if (success) -	{ -		gDeferredSkinnedFullbrightProgram.mName = "Skinned Fullbright Shader"; -		gDeferredSkinnedFullbrightProgram.mFeatures.calculatesAtmospherics = true; -		gDeferredSkinnedFullbrightProgram.mFeatures.hasAtmospherics = true; -		gDeferredSkinnedFullbrightProgram.mFeatures.hasGamma = true; -		gDeferredSkinnedFullbrightProgram.mFeatures.hasTransport = true; -		gDeferredSkinnedFullbrightProgram.mFeatures.hasObjectSkinning = true; -		gDeferredSkinnedFullbrightProgram.mFeatures.disableTextureIndex = true; -		gDeferredSkinnedFullbrightProgram.mFeatures.hasSrgb = true; -		gDeferredSkinnedFullbrightProgram.mShaderFiles.clear(); -		gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredSkinnedFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		success = gDeferredSkinnedFullbrightProgram.createShader(NULL, NULL); -		llassert(success); -	} - -	if (success) -	{ -		gDeferredSkinnedFullbrightShinyProgram.mName = "Skinned Fullbright Shiny Shader"; -		gDeferredSkinnedFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; -        gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasAtmospherics = true; -		gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasGamma = true; -		gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasTransport = true; -		gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasObjectSkinning = true; -		gDeferredSkinnedFullbrightShinyProgram.mFeatures.disableTextureIndex = true; -        gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasSrgb = true; -		gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.clear(); -		gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredSkinnedFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		success = gDeferredSkinnedFullbrightShinyProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gDeferredFullbrightShinyProgram, gDeferredSkinnedFullbrightShinyProgram); +		success = success && gDeferredFullbrightShinyProgram.createShader(NULL, NULL);  		llassert(success);  	} @@ -2206,7 +2209,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; -		success = gDeferredEmissiveProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gDeferredEmissiveProgram, gDeferredSkinnedEmissiveProgram); +		success = success && gDeferredEmissiveProgram.createShader(NULL, NULL);  		llassert(success);  	} @@ -2349,10 +2353,29 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		{  			gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", "1");  		} +        gDeferredShadowProgram.mRiggedVariant = &gDeferredSkinnedShadowProgram;  		success = gDeferredShadowProgram.createShader(NULL, NULL);  		llassert(success);  	} +    if (success) +    { +        gDeferredSkinnedShadowProgram.mName = "Deferred Skinned Shadow Shader"; +        gDeferredSkinnedShadowProgram.mFeatures.isDeferred = true; +        gDeferredSkinnedShadowProgram.mFeatures.hasShadows = true; +        gDeferredSkinnedShadowProgram.mFeatures.hasObjectSkinning = true; +        gDeferredSkinnedShadowProgram.mShaderFiles.clear(); +        gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); +        gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB)); +        gDeferredSkinnedShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; +        if (gGLManager.mHasDepthClamp) +        { +            gDeferredSkinnedShadowProgram.addPermutation("DEPTH_CLAMP", "1"); +        } +        success = gDeferredSkinnedShadowProgram.createShader(NULL, NULL); +        llassert(success); +    } +  	if (success)  	{  		gDeferredShadowCubeProgram.mName = "Deferred Shadow Cube Shader"; @@ -2386,11 +2409,32 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		}          gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1");  		gDeferredShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; +        gDeferredShadowFullbrightAlphaMaskProgram.mRiggedVariant = &gDeferredSkinnedShadowFullbrightAlphaMaskProgram;  		success = gDeferredShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL);  		llassert(success);  	}      if (success) +    { +        gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mName = "Deferred Skinned Shadow Fullbright Alpha Mask Shader"; +        gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; +        gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mFeatures.hasObjectSkinning = true; +        gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.clear(); +        gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); +        gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB)); + +        gDeferredSkinnedShadowFullbrightAlphaMaskProgram.clearPermutations(); +        if (gGLManager.mHasDepthClamp) +        { +            gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); +        } +        gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1"); +        gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; +        success = gDeferredSkinnedShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL); +        llassert(success); +    } + +    if (success)  	{  		gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader";  		gDeferredShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; @@ -2403,10 +2447,28 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  			gDeferredShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");  		}  		gDeferredShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; +        gDeferredShadowAlphaMaskProgram.mRiggedVariant = &gDeferredSkinnedShadowAlphaMaskProgram;  		success = gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL);  		llassert(success);  	} +    if (success) +    { +        gDeferredSkinnedShadowAlphaMaskProgram.mName = "Deferred Skinned Shadow Alpha Mask Shader"; +        gDeferredSkinnedShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; +        gDeferredSkinnedShadowAlphaMaskProgram.mFeatures.hasObjectSkinning = true; +        gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.clear(); +        gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); +        gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB)); +        if (gGLManager.mHasDepthClamp) +        { +            gDeferredSkinnedShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); +        } +        gDeferredSkinnedShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; +        success = gDeferredSkinnedShadowAlphaMaskProgram.createShader(NULL, NULL); +        llassert(success); +    } +  	if (success)  	{  		gDeferredAvatarShadowProgram.mName = "Deferred Avatar Shadow Shader"; @@ -2782,79 +2844,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  BOOL LLViewerShaderMgr::loadShadersObject()  {  	BOOL success = TRUE; -	 -	if (mShaderLevel[SHADER_OBJECT] == 0) -	{ -		gObjectShinyProgram.unload(); -		gObjectFullbrightShinyProgram.unload(); -		gObjectFullbrightShinyWaterProgram.unload(); -		gObjectShinyWaterProgram.unload(); -		gObjectFullbrightNoColorProgram.unload(); -		gObjectFullbrightNoColorWaterProgram.unload(); -		gObjectSimpleProgram.unload(); -		gObjectSimpleImpostorProgram.unload(); -		gObjectPreviewProgram.unload(); -		gImpostorProgram.unload(); -		gObjectSimpleAlphaMaskProgram.unload(); -		gObjectBumpProgram.unload(); -		gObjectSimpleWaterProgram.unload(); -		gObjectSimpleWaterAlphaMaskProgram.unload(); -		gObjectEmissiveProgram.unload(); -		gObjectEmissiveWaterProgram.unload(); -		gObjectFullbrightProgram.unload(); -		gObjectFullbrightAlphaMaskProgram.unload(); -		gObjectFullbrightWaterProgram.unload(); -		gObjectFullbrightWaterAlphaMaskProgram.unload(); -		gObjectShinyNonIndexedProgram.unload(); -		gObjectFullbrightShinyNonIndexedProgram.unload(); -		gObjectFullbrightShinyNonIndexedWaterProgram.unload(); -		gObjectShinyNonIndexedWaterProgram.unload(); -		gObjectSimpleNonIndexedTexGenProgram.unload(); -		gObjectSimpleNonIndexedTexGenWaterProgram.unload(); -		gObjectSimpleNonIndexedWaterProgram.unload(); -		gObjectAlphaMaskNonIndexedProgram.unload(); -		gObjectAlphaMaskNonIndexedWaterProgram.unload(); -		gObjectAlphaMaskNoColorProgram.unload(); -		gObjectAlphaMaskNoColorWaterProgram.unload(); -		gObjectFullbrightNonIndexedProgram.unload(); -		gObjectFullbrightNonIndexedWaterProgram.unload(); -		gObjectEmissiveNonIndexedProgram.unload(); -		gObjectEmissiveNonIndexedWaterProgram.unload(); -		gSkinnedObjectSimpleProgram.unload(); -		gSkinnedObjectFullbrightProgram.unload(); -		gSkinnedObjectEmissiveProgram.unload(); -		gSkinnedObjectFullbrightShinyProgram.unload(); -		gSkinnedObjectShinySimpleProgram.unload(); -		gSkinnedObjectSimpleWaterProgram.unload(); -		gSkinnedObjectFullbrightWaterProgram.unload(); -		gSkinnedObjectEmissiveWaterProgram.unload(); -		gSkinnedObjectFullbrightShinyWaterProgram.unload(); -		gSkinnedObjectShinySimpleWaterProgram.unload(); -		gTreeProgram.unload(); -		gTreeWaterProgram.unload(); -	 -		return TRUE; -	}  	if (success)  	{ -		gObjectSimpleNonIndexedProgram.mName = "Non indexed Shader"; -		gObjectSimpleNonIndexedProgram.mFeatures.calculatesLighting = true; -		gObjectSimpleNonIndexedProgram.mFeatures.calculatesAtmospherics = true; -		gObjectSimpleNonIndexedProgram.mFeatures.hasGamma = true; -		gObjectSimpleNonIndexedProgram.mFeatures.hasAtmospherics = true; -		gObjectSimpleNonIndexedProgram.mFeatures.hasLighting = true; -        gObjectSimpleNonIndexedProgram.mFeatures.hasAlphaMask = true; // Fix for MAINT-8836 -		gObjectSimpleNonIndexedProgram.mFeatures.disableTextureIndex = 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)); -		gObjectSimpleNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		success = gObjectSimpleNonIndexedProgram.createShader(NULL, NULL); -	} -	 -	if (success) -	{  		gObjectSimpleNonIndexedTexGenProgram.mName = "Non indexed tex-gen Shader";  		gObjectSimpleNonIndexedTexGenProgram.mFeatures.calculatesLighting = true;  		gObjectSimpleNonIndexedTexGenProgram.mFeatures.calculatesAtmospherics = true; @@ -2869,24 +2861,6 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		success = gObjectSimpleNonIndexedTexGenProgram.createShader(NULL, NULL);  	} - -	if (success) -	{ -		gObjectSimpleNonIndexedWaterProgram.mName = "Non indexed Water Shader"; -		gObjectSimpleNonIndexedWaterProgram.mFeatures.calculatesLighting = true; -		gObjectSimpleNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; -		gObjectSimpleNonIndexedWaterProgram.mFeatures.hasWaterFog = true; -		gObjectSimpleNonIndexedWaterProgram.mFeatures.hasAtmospherics = true; -		gObjectSimpleNonIndexedWaterProgram.mFeatures.hasLighting = true; -		gObjectSimpleNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; -		gObjectSimpleNonIndexedWaterProgram.mShaderFiles.clear(); -		gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); -		gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectSimpleNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		gObjectSimpleNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gObjectSimpleNonIndexedWaterProgram.createShader(NULL, NULL); -	} -  	if (success)  	{  		gObjectSimpleNonIndexedTexGenWaterProgram.mName = "Non indexed tex-gen Water Shader"; @@ -3011,70 +2985,6 @@ BOOL LLViewerShaderMgr::loadShadersObject()  	if (success)  	{ -		gObjectFullbrightNonIndexedProgram.mName = "Non Indexed Fullbright Shader"; -		gObjectFullbrightNonIndexedProgram.mFeatures.calculatesAtmospherics = true; -		gObjectFullbrightNonIndexedProgram.mFeatures.hasGamma = true; -		gObjectFullbrightNonIndexedProgram.mFeatures.hasTransport = true; -		gObjectFullbrightNonIndexedProgram.mFeatures.isFullbright = true; -		gObjectFullbrightNonIndexedProgram.mFeatures.disableTextureIndex = true; -		gObjectFullbrightNonIndexedProgram.mShaderFiles.clear(); -		gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); -		gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectFullbrightNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		success = gObjectFullbrightNonIndexedProgram.createShader(NULL, NULL); -	} - -	if (success) -	{ -		gObjectFullbrightNonIndexedWaterProgram.mName = "Non Indexed Fullbright Water Shader"; -		gObjectFullbrightNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; -		gObjectFullbrightNonIndexedWaterProgram.mFeatures.isFullbright = true; -		gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasWaterFog = true;		 -		gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasTransport = true; -		gObjectFullbrightNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; -		gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasSrgb = true; -		gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.clear(); -		gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); -		gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectFullbrightNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		gObjectFullbrightNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gObjectFullbrightNonIndexedWaterProgram.createShader(NULL, NULL); -	} - -	if (success) -	{ -		gObjectEmissiveNonIndexedProgram.mName = "Non Indexed Emissive Shader"; -		gObjectEmissiveNonIndexedProgram.mFeatures.calculatesAtmospherics = true; -		gObjectEmissiveNonIndexedProgram.mFeatures.hasGamma = true; -		gObjectEmissiveNonIndexedProgram.mFeatures.hasTransport = true; -		gObjectEmissiveNonIndexedProgram.mFeatures.isFullbright = true; -		gObjectEmissiveNonIndexedProgram.mFeatures.disableTextureIndex = true; -		gObjectEmissiveNonIndexedProgram.mFeatures.hasSrgb = true; -		gObjectEmissiveNonIndexedProgram.mShaderFiles.clear(); -		gObjectEmissiveNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB)); -		gObjectEmissiveNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectEmissiveNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		success = gObjectEmissiveNonIndexedProgram.createShader(NULL, NULL); -	} - -	if (success) -	{ -		gObjectEmissiveNonIndexedWaterProgram.mName = "Non Indexed Emissive Water Shader"; -		gObjectEmissiveNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; -		gObjectEmissiveNonIndexedWaterProgram.mFeatures.isFullbright = true; -		gObjectEmissiveNonIndexedWaterProgram.mFeatures.hasWaterFog = true;		 -		gObjectEmissiveNonIndexedWaterProgram.mFeatures.hasTransport = true; -		gObjectEmissiveNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; -		gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.clear(); -		gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB)); -		gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectEmissiveNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		gObjectEmissiveNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gObjectEmissiveNonIndexedWaterProgram.createShader(NULL, NULL); -	} - -	if (success) -	{  		gObjectFullbrightNoColorProgram.mName = "Non Indexed no color Fullbright Shader";  		gObjectFullbrightNoColorProgram.mFeatures.calculatesAtmospherics = true;  		gObjectFullbrightNoColorProgram.mFeatures.hasGamma = true; @@ -3107,73 +3017,6 @@ BOOL LLViewerShaderMgr::loadShadersObject()  	if (success)  	{ -		gObjectShinyNonIndexedProgram.mName = "Non Indexed Shiny Shader"; -		gObjectShinyNonIndexedProgram.mFeatures.calculatesAtmospherics = true; -		gObjectShinyNonIndexedProgram.mFeatures.calculatesLighting = true; -		gObjectShinyNonIndexedProgram.mFeatures.hasGamma = true; -		gObjectShinyNonIndexedProgram.mFeatures.hasAtmospherics = true; -		gObjectShinyNonIndexedProgram.mFeatures.isShiny = true; -		gObjectShinyNonIndexedProgram.mFeatures.disableTextureIndex = true; -		gObjectShinyNonIndexedProgram.mShaderFiles.clear(); -		gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); -		gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));		 -		gObjectShinyNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		success = gObjectShinyNonIndexedProgram.createShader(NULL, NULL); -	} - -	if (success) -	{ -		gObjectShinyNonIndexedWaterProgram.mName = "Non Indexed Shiny Water Shader"; -		gObjectShinyNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; -		gObjectShinyNonIndexedWaterProgram.mFeatures.calculatesLighting = true; -		gObjectShinyNonIndexedWaterProgram.mFeatures.isShiny = true; -		gObjectShinyNonIndexedWaterProgram.mFeatures.hasWaterFog = true; -		gObjectShinyNonIndexedWaterProgram.mFeatures.hasAtmospherics = true; -		gObjectShinyNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; -		gObjectShinyNonIndexedWaterProgram.mShaderFiles.clear(); -		gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); -		gObjectShinyNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		gObjectShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gObjectShinyNonIndexedWaterProgram.createShader(NULL, NULL); -	} -	 -    if (success) -	{ -		gObjectFullbrightShinyNonIndexedProgram.mName = "Non Indexed Fullbright Shiny Shader"; -		gObjectFullbrightShinyNonIndexedProgram.mFeatures.calculatesAtmospherics = true; -		gObjectFullbrightShinyNonIndexedProgram.mFeatures.isFullbright = true; -		gObjectFullbrightShinyNonIndexedProgram.mFeatures.isShiny = true; -		gObjectFullbrightShinyNonIndexedProgram.mFeatures.hasGamma = true; -		gObjectFullbrightShinyNonIndexedProgram.mFeatures.hasTransport = true; -		gObjectFullbrightShinyNonIndexedProgram.mFeatures.disableTextureIndex = true; -		gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.clear(); -		gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); -		gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectFullbrightShinyNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		success = gObjectFullbrightShinyNonIndexedProgram.createShader(NULL, NULL); -	} - -	if (success) -	{ -		gObjectFullbrightShinyNonIndexedWaterProgram.mName = "Non Indexed Fullbright Shiny Water Shader"; -		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; -		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.isFullbright = true; -		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.isShiny = true; -		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasGamma = true; -		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasTransport = true; -		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasWaterFog = true; -		gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; -		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.clear(); -		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); -		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gObjectFullbrightShinyNonIndexedWaterProgram.createShader(NULL, NULL); -	} - -	if (success) -	{  		gImpostorProgram.mName = "Impostor Shader";  		gImpostorProgram.mFeatures.disableTextureIndex = true;  		gImpostorProgram.mFeatures.hasSrgb = true; @@ -3215,7 +3058,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectSimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		success = gObjectSimpleProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gObjectSimpleProgram, gSkinnedObjectSimpleProgram); +		success = success && gObjectSimpleProgram.createShader(NULL, NULL);  	}  	if (success) @@ -3235,8 +3079,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectSimpleImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		 -		success = gObjectSimpleImpostorProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gObjectSimpleImpostorProgram, gSkinnedObjectSimpleImpostorProgram); +		success = success && gObjectSimpleImpostorProgram.createShader(NULL, NULL);  	}  	if (success) @@ -3253,30 +3097,30 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectSimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; +        make_rigged_variant(gObjectSimpleWaterProgram, gSkinnedObjectSimpleWaterProgram);  		success = gObjectSimpleWaterProgram.createShader(NULL, NULL);  	}  	if (success)  	{  		gObjectBumpProgram.mName = "Bump Shader"; -		/*gObjectBumpProgram.mFeatures.calculatesLighting = true; -		gObjectBumpProgram.mFeatures.calculatesAtmospherics = true; -		gObjectBumpProgram.mFeatures.hasGamma = true; -		gObjectBumpProgram.mFeatures.hasAtmospherics = true; -		gObjectBumpProgram.mFeatures.hasLighting = true; -		gObjectBumpProgram.mFeatures.mIndexedTextureChannels = 0;*/  		gObjectBumpProgram.mFeatures.encodesNormal = true;  		gObjectBumpProgram.mShaderFiles.clear();  		gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectBumpProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		success = gObjectBumpProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gObjectBumpProgram, gSkinnedObjectBumpProgram); +		success = success && gObjectBumpProgram.createShader(NULL, NULL);  		if (success)  		{ //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1 -			gObjectBumpProgram.bind(); -			gObjectBumpProgram.uniform1i(sTexture0, 0); -			gObjectBumpProgram.uniform1i(sTexture1, 1); -			gObjectBumpProgram.unbind(); +            LLGLSLShader* shader[] = { &gObjectBumpProgram, &gSkinnedObjectBumpProgram }; +            for (int i = 0; i < 2; ++i) +            { +                shader[i]->bind(); +                shader[i]->uniform1i(sTexture0, 0); +                shader[i]->uniform1i(sTexture1, 1); +                shader[i]->unbind(); +            }  		}  	} @@ -3295,7 +3139,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectSimpleAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		success = gObjectSimpleAlphaMaskProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gObjectSimpleAlphaMaskProgram, gSkinnedObjectSimpleAlphaMaskProgram); +		success = success && gObjectSimpleAlphaMaskProgram.createShader(NULL, NULL);  	}  	if (success) @@ -3313,7 +3158,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectSimpleWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectSimpleWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gObjectSimpleWaterAlphaMaskProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gObjectSimpleWaterAlphaMaskProgram, gSkinnedObjectSimpleWaterAlphaMaskProgram); +		success = success && gObjectSimpleWaterAlphaMaskProgram.createShader(NULL, NULL);  	}  	if (success) @@ -3329,7 +3175,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		success = gObjectFullbrightProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gObjectFullbrightProgram, gSkinnedObjectFullbrightProgram); +        success = success && gObjectFullbrightProgram.createShader(NULL, NULL);  	}  	if (success) @@ -3337,7 +3184,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightWaterProgram.mName = "Fullbright Water Shader";  		gObjectFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true;  		gObjectFullbrightWaterProgram.mFeatures.isFullbright = true; -		gObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true;		 +		gObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true;  		gObjectFullbrightWaterProgram.mFeatures.hasTransport = true;  		gObjectFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = 0;  		gObjectFullbrightWaterProgram.mShaderFiles.clear(); @@ -3345,7 +3192,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gObjectFullbrightWaterProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gObjectFullbrightWaterProgram, gSkinnedObjectFullbrightWaterProgram); +		success = success && gObjectFullbrightWaterProgram.createShader(NULL, NULL);  	}  	if (success) @@ -3361,7 +3209,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		success = gObjectEmissiveProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gObjectEmissiveProgram, gSkinnedObjectEmissiveProgram); +		success = success && gObjectEmissiveProgram.createShader(NULL, NULL);  	}  	if (success) @@ -3377,7 +3226,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectEmissiveWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectEmissiveWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gObjectEmissiveWaterProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gObjectEmissiveWaterProgram, gSkinnedObjectEmissiveWaterProgram); +		success = success && gObjectEmissiveWaterProgram.createShader(NULL, NULL);  	}  	if (success) @@ -3394,12 +3244,13 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		success = gObjectFullbrightAlphaMaskProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gObjectFullbrightAlphaMaskProgram, gSkinnedObjectFullbrightAlphaMaskProgram); +		success = success && gObjectFullbrightAlphaMaskProgram.createShader(NULL, NULL);  	}  	if (success)  	{ -		gObjectFullbrightWaterAlphaMaskProgram.mName = "Fullbright Water Shader"; +		gObjectFullbrightWaterAlphaMaskProgram.mName = "Fullbright Water Alpha Mask Shader";  		gObjectFullbrightWaterAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;  		gObjectFullbrightWaterAlphaMaskProgram.mFeatures.isFullbright = true;  		gObjectFullbrightWaterAlphaMaskProgram.mFeatures.hasWaterFog = true;		 @@ -3411,7 +3262,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectFullbrightWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectFullbrightWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gObjectFullbrightWaterAlphaMaskProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gObjectFullbrightWaterAlphaMaskProgram, gSkinnedObjectFullbrightWaterAlphaMaskProgram); +		success = success && gObjectFullbrightWaterAlphaMaskProgram.createShader(NULL, NULL);  	}  	if (success) @@ -3427,7 +3279,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));		  		gObjectShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		success = gObjectShinyProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gObjectShinyProgram, gSkinnedObjectShinyProgram); +		success = success && gObjectShinyProgram.createShader(NULL, NULL);  	}  	if (success) @@ -3444,7 +3297,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gObjectShinyWaterProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gObjectShinyWaterProgram, gSkinnedObjectShinyWaterProgram); +		success = success && gObjectShinyWaterProgram.createShader(NULL, NULL);  	}  	if (success) @@ -3460,7 +3314,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -		success = gObjectFullbrightShinyProgram.createShader(NULL, NULL); +        success = make_rigged_variant(gObjectFullbrightShinyProgram, gSkinnedObjectFullbrightShinyProgram); +		success = success && gObjectFullbrightShinyProgram.createShader(NULL, NULL);  	}  	if (success) @@ -3478,196 +3333,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectFullbrightShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];  		gObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gObjectFullbrightShinyWaterProgram.createShader(NULL, NULL); -	} - -	if (mShaderLevel[SHADER_AVATAR] > 0) -	{ //load hardware skinned attachment shaders -		if (success) -		{ -			gSkinnedObjectSimpleProgram.mName = "Skinned Simple Shader"; -			gSkinnedObjectSimpleProgram.mFeatures.calculatesLighting = true; -			gSkinnedObjectSimpleProgram.mFeatures.calculatesAtmospherics = true; -			gSkinnedObjectSimpleProgram.mFeatures.hasGamma = true; -			gSkinnedObjectSimpleProgram.mFeatures.hasAtmospherics = true; -			gSkinnedObjectSimpleProgram.mFeatures.hasLighting = true; -			gSkinnedObjectSimpleProgram.mFeatures.hasObjectSkinning = true; -			gSkinnedObjectSimpleProgram.mFeatures.hasAlphaMask = true; -			gSkinnedObjectSimpleProgram.mFeatures.disableTextureIndex = true; -			gSkinnedObjectSimpleProgram.mShaderFiles.clear(); -			gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); -			gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectSimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -			success = gSkinnedObjectSimpleProgram.createShader(NULL, NULL); -		} - -		if (success) -		{ -			gSkinnedObjectFullbrightProgram.mName = "Skinned Fullbright Shader"; -			gSkinnedObjectFullbrightProgram.mFeatures.calculatesAtmospherics = true; -			gSkinnedObjectFullbrightProgram.mFeatures.hasGamma = true; -			gSkinnedObjectFullbrightProgram.mFeatures.hasTransport = true; -			gSkinnedObjectFullbrightProgram.mFeatures.isFullbright = true; -			gSkinnedObjectFullbrightProgram.mFeatures.hasObjectSkinning = true; -			gSkinnedObjectFullbrightProgram.mFeatures.hasAlphaMask = true;			 -			gSkinnedObjectFullbrightProgram.mFeatures.disableTextureIndex = true; -			gSkinnedObjectFullbrightProgram.mFeatures.hasSrgb = true; -			gSkinnedObjectFullbrightProgram.mShaderFiles.clear(); -			gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); -			gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -			success = gSkinnedObjectFullbrightProgram.createShader(NULL, NULL); -		} - -		if (success) -		{ -			gSkinnedObjectEmissiveProgram.mName = "Skinned Emissive Shader"; -			gSkinnedObjectEmissiveProgram.mFeatures.calculatesAtmospherics = true; -			gSkinnedObjectEmissiveProgram.mFeatures.hasGamma = true; -			gSkinnedObjectEmissiveProgram.mFeatures.hasTransport = true; -			gSkinnedObjectEmissiveProgram.mFeatures.isFullbright = true; -			gSkinnedObjectEmissiveProgram.mFeatures.hasObjectSkinning = true; -			gSkinnedObjectEmissiveProgram.mFeatures.disableTextureIndex = true; -            gSkinnedObjectEmissiveProgram.mFeatures.hasSrgb = true; -			gSkinnedObjectEmissiveProgram.mShaderFiles.clear(); -			gSkinnedObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); -			gSkinnedObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -			success = gSkinnedObjectEmissiveProgram.createShader(NULL, NULL); -		} - -		if (success) -		{ -			gSkinnedObjectEmissiveWaterProgram.mName = "Skinned Emissive Water Shader"; -			gSkinnedObjectEmissiveWaterProgram.mFeatures.calculatesAtmospherics = true; -			gSkinnedObjectEmissiveWaterProgram.mFeatures.hasGamma = true; -			gSkinnedObjectEmissiveWaterProgram.mFeatures.hasTransport = true; -			gSkinnedObjectEmissiveWaterProgram.mFeatures.isFullbright = true; -			gSkinnedObjectEmissiveWaterProgram.mFeatures.hasObjectSkinning = true; -			gSkinnedObjectEmissiveWaterProgram.mFeatures.disableTextureIndex = true; -			gSkinnedObjectEmissiveWaterProgram.mFeatures.hasWaterFog = true; -			gSkinnedObjectEmissiveWaterProgram.mShaderFiles.clear(); -			gSkinnedObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); -			gSkinnedObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectEmissiveWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -			success = gSkinnedObjectEmissiveWaterProgram.createShader(NULL, NULL); -		} - -		if (success) -		{ -			gSkinnedObjectFullbrightShinyProgram.mName = "Skinned Fullbright Shiny Shader"; -			gSkinnedObjectFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; -			gSkinnedObjectFullbrightShinyProgram.mFeatures.hasGamma = true; -			gSkinnedObjectFullbrightShinyProgram.mFeatures.hasTransport = true; -			gSkinnedObjectFullbrightShinyProgram.mFeatures.isShiny = true; -			gSkinnedObjectFullbrightShinyProgram.mFeatures.isFullbright = true; -			gSkinnedObjectFullbrightShinyProgram.mFeatures.hasObjectSkinning = true; -			gSkinnedObjectFullbrightShinyProgram.mFeatures.hasAlphaMask = true; -			gSkinnedObjectFullbrightShinyProgram.mFeatures.disableTextureIndex = true; -			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.clear(); -			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); -			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -			success = gSkinnedObjectFullbrightShinyProgram.createShader(NULL, NULL); -		} - -		if (success) -		{ -			gSkinnedObjectShinySimpleProgram.mName = "Skinned Shiny Simple Shader"; -			gSkinnedObjectShinySimpleProgram.mFeatures.calculatesLighting = true; -			gSkinnedObjectShinySimpleProgram.mFeatures.calculatesAtmospherics = true; -			gSkinnedObjectShinySimpleProgram.mFeatures.hasGamma = true; -			gSkinnedObjectShinySimpleProgram.mFeatures.hasAtmospherics = true; -			gSkinnedObjectShinySimpleProgram.mFeatures.hasObjectSkinning = true; -			gSkinnedObjectShinySimpleProgram.mFeatures.hasAlphaMask = true; -			gSkinnedObjectShinySimpleProgram.mFeatures.isShiny = true; -			gSkinnedObjectShinySimpleProgram.mFeatures.disableTextureIndex = true; -			gSkinnedObjectShinySimpleProgram.mShaderFiles.clear(); -			gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); -			gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectShinySimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -			success = gSkinnedObjectShinySimpleProgram.createShader(NULL, NULL); -		} - -		if (success) -		{ -			gSkinnedObjectSimpleWaterProgram.mName = "Skinned Simple Water Shader"; -			gSkinnedObjectSimpleWaterProgram.mFeatures.calculatesLighting = true; -			gSkinnedObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true; -			gSkinnedObjectSimpleWaterProgram.mFeatures.hasGamma = true; -			gSkinnedObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true; -			gSkinnedObjectSimpleWaterProgram.mFeatures.hasLighting = true; -			gSkinnedObjectSimpleWaterProgram.mFeatures.disableTextureIndex = true; -			gSkinnedObjectSimpleWaterProgram.mFeatures.hasWaterFog = true; -			gSkinnedObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -			gSkinnedObjectSimpleWaterProgram.mFeatures.hasObjectSkinning = true; -			gSkinnedObjectSimpleWaterProgram.mFeatures.disableTextureIndex = true; -			gSkinnedObjectSimpleWaterProgram.mFeatures.hasAlphaMask = true; -			gSkinnedObjectSimpleWaterProgram.mShaderFiles.clear(); -			gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); -			gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectSimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -			success = gSkinnedObjectSimpleWaterProgram.createShader(NULL, NULL); -		} - -		if (success) -		{ -			gSkinnedObjectFullbrightWaterProgram.mName = "Skinned Fullbright Water Shader"; -			gSkinnedObjectFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true; -			gSkinnedObjectFullbrightWaterProgram.mFeatures.hasGamma = true; -			gSkinnedObjectFullbrightWaterProgram.mFeatures.hasTransport = true; -			gSkinnedObjectFullbrightWaterProgram.mFeatures.isFullbright = true; -			gSkinnedObjectFullbrightWaterProgram.mFeatures.hasObjectSkinning = true; -			gSkinnedObjectFullbrightWaterProgram.mFeatures.hasAlphaMask = true; -			gSkinnedObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true; -			gSkinnedObjectFullbrightWaterProgram.mFeatures.disableTextureIndex = true; -			gSkinnedObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -			gSkinnedObjectFullbrightWaterProgram.mShaderFiles.clear(); -			gSkinnedObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); -			gSkinnedObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -			success = gSkinnedObjectFullbrightWaterProgram.createShader(NULL, NULL); -		} - -		if (success) -		{ -			gSkinnedObjectFullbrightShinyWaterProgram.mName = "Skinned Fullbright Shiny Water Shader"; -			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.calculatesAtmospherics = true; -			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasGamma = true; -			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasTransport = true; -			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isShiny = true; -			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true; -			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasObjectSkinning = true; -			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasAlphaMask = true; -			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true; -			gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.disableTextureIndex = true; -			gSkinnedObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -			gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.clear(); -			gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); -			gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectFullbrightShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -			success = gSkinnedObjectFullbrightShinyWaterProgram.createShader(NULL, NULL); -		} - -		if (success) -		{ -			gSkinnedObjectShinySimpleWaterProgram.mName = "Skinned Shiny Simple Water Shader"; -			gSkinnedObjectShinySimpleWaterProgram.mFeatures.calculatesLighting = true; -			gSkinnedObjectShinySimpleWaterProgram.mFeatures.calculatesAtmospherics = true; -			gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasGamma = true; -			gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasAtmospherics = true; -			gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasObjectSkinning = true; -			gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasAlphaMask = true; -			gSkinnedObjectShinySimpleWaterProgram.mFeatures.isShiny = true; -			gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasWaterFog = true; -			gSkinnedObjectShinySimpleWaterProgram.mFeatures.disableTextureIndex = true; -			gSkinnedObjectShinySimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -			gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.clear(); -			gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); -			gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); -			gSkinnedObjectShinySimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; -			success = gSkinnedObjectShinySimpleWaterProgram.createShader(NULL, NULL); -		} +        success = make_rigged_variant(gObjectFullbrightShinyWaterProgram, gSkinnedObjectFullbrightShinyWaterProgram); +		success = success && gObjectFullbrightShinyWaterProgram.createShader(NULL, NULL);  	}  	if( !success ) @@ -3995,9 +3662,21 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionV.glsl", GL_VERTEX_SHADER_ARB));  		gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB));  		gOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; +        gOcclusionProgram.mRiggedVariant = &gSkinnedOcclusionProgram;  		success = gOcclusionProgram.createShader(NULL, NULL);  	} +    if (success) +    { +        gSkinnedOcclusionProgram.mName = "Skinned Occlusion Shader"; +        gSkinnedOcclusionProgram.mFeatures.hasObjectSkinning = true; +        gSkinnedOcclusionProgram.mShaderFiles.clear(); +        gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); +        gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB)); +        gSkinnedOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; +        success = gSkinnedOcclusionProgram.createShader(NULL, NULL); +    } +  	if (success)  	{  		gOcclusionCubeProgram.mName = "Occlusion Cube Shader"; @@ -4014,10 +3693,22 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  		gDebugProgram.mShaderFiles.clear();  		gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER_ARB));  		gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER_ARB)); +        gDebugProgram.mRiggedVariant = &gSkinnedDebugProgram;  		gDebugProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];  		success = gDebugProgram.createShader(NULL, NULL);  	} +    if (success) +    { +        gSkinnedDebugProgram.mName = "Skinned Debug Shader"; +        gSkinnedDebugProgram.mFeatures.hasObjectSkinning = true; +        gSkinnedDebugProgram.mShaderFiles.clear(); +        gSkinnedDebugProgram.mShaderFiles.push_back(make_pair("interface/debugSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); +        gSkinnedDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER_ARB)); +        gSkinnedDebugProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; +        success = gSkinnedDebugProgram.createShader(NULL, NULL); +    } +  	if (success)  	{  		gClipProgram.mName = "Clip Shader"; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 081221f15b..297cfb6e68 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -184,10 +184,8 @@ extern LLGLSLShader			gObjectPreviewProgram;  extern LLGLSLShader			gObjectSimpleAlphaMaskProgram;  extern LLGLSLShader			gObjectSimpleWaterProgram;  extern LLGLSLShader			gObjectSimpleWaterAlphaMaskProgram; -extern LLGLSLShader			gObjectSimpleNonIndexedProgram;  extern LLGLSLShader			gObjectSimpleNonIndexedTexGenProgram;  extern LLGLSLShader			gObjectSimpleNonIndexedTexGenWaterProgram; -extern LLGLSLShader			gObjectSimpleNonIndexedWaterProgram;  extern LLGLSLShader			gObjectAlphaMaskNonIndexedProgram;  extern LLGLSLShader			gObjectAlphaMaskNonIndexedWaterProgram;  extern LLGLSLShader			gObjectAlphaMaskNoColorProgram; @@ -200,8 +198,6 @@ extern LLGLSLShader			gObjectEmissiveProgram;  extern LLGLSLShader			gObjectEmissiveWaterProgram;  extern LLGLSLShader			gObjectFullbrightAlphaMaskProgram;  extern LLGLSLShader			gObjectFullbrightWaterAlphaMaskProgram; -extern LLGLSLShader			gObjectFullbrightNonIndexedProgram; -extern LLGLSLShader			gObjectFullbrightNonIndexedWaterProgram;  extern LLGLSLShader			gObjectEmissiveNonIndexedProgram;  extern LLGLSLShader			gObjectEmissiveNonIndexedWaterProgram;  extern LLGLSLShader			gObjectBumpProgram; @@ -213,25 +209,9 @@ extern LLGLSLShader			gObjectFullbrightLODProgram;  extern LLGLSLShader			gObjectFullbrightShinyProgram;  extern LLGLSLShader			gObjectFullbrightShinyWaterProgram; -extern LLGLSLShader			gObjectFullbrightShinyNonIndexedProgram; -extern LLGLSLShader			gObjectFullbrightShinyNonIndexedWaterProgram;  extern LLGLSLShader			gObjectShinyProgram;  extern LLGLSLShader			gObjectShinyWaterProgram; -extern LLGLSLShader			gObjectShinyNonIndexedProgram; -extern LLGLSLShader			gObjectShinyNonIndexedWaterProgram; - -extern LLGLSLShader			gSkinnedObjectSimpleProgram; -extern LLGLSLShader			gSkinnedObjectFullbrightProgram; -extern LLGLSLShader			gSkinnedObjectEmissiveProgram; -extern LLGLSLShader			gSkinnedObjectFullbrightShinyProgram; -extern LLGLSLShader			gSkinnedObjectShinySimpleProgram; - -extern LLGLSLShader			gSkinnedObjectSimpleWaterProgram; -extern LLGLSLShader			gSkinnedObjectFullbrightWaterProgram; -extern LLGLSLShader			gSkinnedObjectEmissiveWaterProgram; -extern LLGLSLShader			gSkinnedObjectFullbrightShinyWaterProgram; -extern LLGLSLShader			gSkinnedObjectShinySimpleWaterProgram;  //environment shaders  extern LLGLSLShader			gTerrainProgram; @@ -281,9 +261,6 @@ extern LLGLSLShader			gDeferredDiffuseAlphaMaskProgram;  extern LLGLSLShader			gDeferredNonIndexedDiffuseAlphaMaskProgram;  extern LLGLSLShader			gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;  extern LLGLSLShader			gDeferredNonIndexedDiffuseProgram; -extern LLGLSLShader			gDeferredSkinnedDiffuseProgram; -extern LLGLSLShader			gDeferredSkinnedBumpProgram; -extern LLGLSLShader			gDeferredSkinnedAlphaProgram;  extern LLGLSLShader			gDeferredBumpProgram;  extern LLGLSLShader			gDeferredTerrainProgram;  extern LLGLSLShader			gDeferredTerrainWaterProgram; @@ -330,8 +307,6 @@ extern LLGLSLShader			gDeferredWLSunProgram;  extern LLGLSLShader			gDeferredWLMoonProgram;  extern LLGLSLShader			gDeferredStarProgram;  extern LLGLSLShader			gDeferredFullbrightShinyProgram; -extern LLGLSLShader			gDeferredSkinnedFullbrightShinyProgram; -extern LLGLSLShader			gDeferredSkinnedFullbrightProgram;  extern LLGLSLShader			gNormalMapGenProgram;  // Deferred materials shaders diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 310a6a2adb..84bb67a03d 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -111,6 +111,7 @@  #include "llsdserialize.h"  #include "llcallstack.h"  #include "llrendersphere.h" +#include "llskinningutil.h"  #include <boost/lexical_cast.hpp> @@ -9445,6 +9446,54 @@ LLViewerTexture* LLVOAvatar::getBakedTexture(const U8 te)  } +const LLVOAvatar::MatrixPaletteCache& LLVOAvatar::updateSkinInfoMatrixPalette(const LLMeshSkinInfo* skin, LLVOVolume* requesting_obj) +{ +    U64 hash = skin->mHash; +    MatrixPaletteCache& entry = mMatrixPaletteCache[hash]; + +    if (entry.mFrame != gFrameCount) +    { +        LL_PROFILE_ZONE_SCOPED; + +        entry.mFrame = gFrameCount; + +        //build matrix palette +        U32 count = LLSkinningUtil::getMeshJointCount(skin); +        entry.mMatrixPalette.resize(count); +        LLSkinningUtil::initSkinningMatrixPalette(&(entry.mMatrixPalette[0]), count, skin, this); + +        const LLMatrix4a* mat = &(entry.mMatrixPalette[0]); + +        entry.mGLMp.resize(count * 12); + +        F32* mp = &(entry.mGLMp[0]); + +        for (U32 i = 0; i < count; ++i) +        { +            F32* m = (F32*)mat[i].mMatrix[0].getF32ptr(); + +            U32 idx = i * 12; + +            mp[idx + 0] = m[0]; +            mp[idx + 1] = m[1]; +            mp[idx + 2] = m[2]; +            mp[idx + 3] = m[12]; + +            mp[idx + 4] = m[4]; +            mp[idx + 5] = m[5]; +            mp[idx + 6] = m[6]; +            mp[idx + 7] = m[13]; + +            mp[idx + 8] = m[8]; +            mp[idx + 9] = m[9]; +            mp[idx + 10] = m[10]; +            mp[idx + 11] = m[14]; +        } +    } + +    return entry; +} +  // static  void LLVOAvatar::getAnimLabels( std::vector<std::string>* labels )  { diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index aeac23ad92..b85400866e 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -53,6 +53,8 @@  #include "llviewerstats.h"  #include "llvovolume.h"  #include "llavatarrendernotifier.h" +#include "llmodel.h" +  extern const LLUUID ANIM_AGENT_BODY_NOISE;  extern const LLUUID ANIM_AGENT_BREATHE_ROT; @@ -77,6 +79,7 @@ class LLViewerJointMesh;  const F32 MAX_AVATAR_LOD_FACTOR = 1.0f; +extern U32 gFrameCount;  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // LLVOAvatar @@ -746,6 +749,26 @@ public:  	void			updateMeshVisibility();  	LLViewerTexture*		getBakedTexture(const U8 te); +    class alignas(16) MatrixPaletteCache +    { +    public: +        U32 mFrame; +        LLMeshSkinInfo::matrix_list_t mMatrixPalette; + +        // Float array ready to be sent to GL +        std::vector<F32> mGLMp; + +        MatrixPaletteCache() : +            mFrame(gFrameCount - 1) +        { +        } +    }; + +    const MatrixPaletteCache& updateSkinInfoMatrixPalette(const LLMeshSkinInfo* skinInfo, LLVOVolume* requesting_obj = nullptr); + +    typedef std::unordered_map<U64, MatrixPaletteCache> matrix_palette_cache_t; +    matrix_palette_cache_t mMatrixPaletteCache; +  protected:  	void 			releaseMeshData();  	virtual void restoreMeshData(); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 755a70599a..f4f9154fed 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1740,7 +1740,17 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)  		}  	} -    if (any_valid_boxes) +    if (isRiggedMesh()) +    { +        min.set(-1, -1, -1, 0); +        max.set(1, 1, 1, 0); + +        mDrawable->setSpatialExtents(min, max); +        mDrawable->setPositionGroup(LLVector4a(0, 0, 0)); +        updateRadius(); +        mDrawable->movePartition(); +    } +    else if (any_valid_boxes)      {          if (rebuild)          { @@ -5010,13 +5020,13 @@ bool can_batch_texture(LLFace* facep)  const static U32 MAX_FACE_COUNT = 4096U;  int32_t LLVolumeGeometryManager::sInstanceCount = 0; -LLFace** LLVolumeGeometryManager::sFullbrightFaces = NULL; -LLFace** LLVolumeGeometryManager::sBumpFaces = NULL; -LLFace** LLVolumeGeometryManager::sSimpleFaces = NULL; -LLFace** LLVolumeGeometryManager::sNormFaces = NULL; -LLFace** LLVolumeGeometryManager::sSpecFaces = NULL; -LLFace** LLVolumeGeometryManager::sNormSpecFaces = NULL; -LLFace** LLVolumeGeometryManager::sAlphaFaces = NULL; +LLFace** LLVolumeGeometryManager::sFullbrightFaces[2] = { NULL }; +LLFace** LLVolumeGeometryManager::sBumpFaces[2] = { NULL }; +LLFace** LLVolumeGeometryManager::sSimpleFaces[2] = { NULL }; +LLFace** LLVolumeGeometryManager::sNormFaces[2] = { NULL }; +LLFace** LLVolumeGeometryManager::sSpecFaces[2] = { NULL }; +LLFace** LLVolumeGeometryManager::sNormSpecFaces[2] = { NULL }; +LLFace** LLVolumeGeometryManager::sAlphaFaces[2] = { NULL };  LLVolumeGeometryManager::LLVolumeGeometryManager()  	: LLGeometryManager() @@ -5044,32 +5054,38 @@ LLVolumeGeometryManager::~LLVolumeGeometryManager()  void LLVolumeGeometryManager::allocateFaces(U32 pMaxFaceCount)  { -	sFullbrightFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); -	sBumpFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); -	sSimpleFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); -	sNormFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); -	sSpecFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); -	sNormSpecFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); -	sAlphaFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); +    for (int i = 0; i < 2; ++i) +    { +        sFullbrightFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*))); +        sBumpFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*))); +        sSimpleFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*))); +        sNormFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*))); +        sSpecFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*))); +        sNormSpecFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*))); +        sAlphaFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*))); +    }  }  void LLVolumeGeometryManager::freeFaces()  { -	ll_aligned_free<64>(sFullbrightFaces); -	ll_aligned_free<64>(sBumpFaces); -	ll_aligned_free<64>(sSimpleFaces); -	ll_aligned_free<64>(sNormFaces); -	ll_aligned_free<64>(sSpecFaces); -	ll_aligned_free<64>(sNormSpecFaces); -	ll_aligned_free<64>(sAlphaFaces); - -	sFullbrightFaces = NULL; -	sBumpFaces = NULL; -	sSimpleFaces = NULL; -	sNormFaces = NULL; -	sSpecFaces = NULL; -	sNormSpecFaces = NULL; -	sAlphaFaces = NULL; +    for (int i = 0; i < 2; ++i) +    { +        ll_aligned_free<64>(sFullbrightFaces[i]); +        ll_aligned_free<64>(sBumpFaces[i]); +        ll_aligned_free<64>(sSimpleFaces[i]); +        ll_aligned_free<64>(sNormFaces[i]); +        ll_aligned_free<64>(sSpecFaces[i]); +        ll_aligned_free<64>(sNormSpecFaces[i]); +        ll_aligned_free<64>(sAlphaFaces[i]); + +        sFullbrightFaces[i] = NULL; +        sBumpFaces[i] = NULL; +        sSimpleFaces[i] = NULL; +        sNormFaces[i] = NULL; +        sSpecFaces[i] = NULL; +        sNormSpecFaces[i] = NULL; +        sAlphaFaces[i] = NULL; +    }  }  void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type) @@ -5090,8 +5106,18 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		return;  	} +    U32 passType = type; + +    bool rigged = facep->isState(LLFace::RIGGED); + +    if (rigged && type != LLRenderPass::PASS_ALPHA) +    { +        // hacky, should probably clean up -- if this face is rigged, put it in "type + 1" +        // See LLRenderPass PASS_foo enum +        passType += 1; +    }  	//add face to drawmap -	LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[type];	 +	LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[passType];  	S32 idx = draw_vec.size()-1; @@ -5117,7 +5143,12 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  	LLDrawable* drawable = facep->getDrawable(); -	if (drawable->isState(LLDrawable::ANIMATED_CHILD)) +    if (rigged) +    { +        // rigged meshes ignore their model matrix +        model_mat = nullptr; +    } +	else if (drawable->isState(LLDrawable::ANIMATED_CHILD))  	{  		model_mat = &drawable->getWorldMatrix();  	} @@ -5191,7 +5222,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange &&  		draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&  #endif -		draw_vec[idx]->mMaterial == mat && +		//draw_vec[idx]->mMaterial == mat &&  		draw_vec[idx]->mMaterialID == mat_id &&  		draw_vec[idx]->mFullbright == fullbright &&  		draw_vec[idx]->mBump == bump && @@ -5199,7 +5230,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		draw_vec[idx]->mTextureMatrix == tex_mat &&  		draw_vec[idx]->mModelMatrix == model_mat &&  		draw_vec[idx]->mShaderMask == shader_mask && -		draw_vec[idx]->mSelected == selected) +		draw_vec[idx]->mSelected == selected && +        draw_vec[idx]->mAvatar == facep->mAvatar && +        draw_vec[idx]->getSkinHash() == facep->getSkinHash())  	{  		draw_vec[idx]->mCount += facep->getIndicesCount();  		draw_vec[idx]->mEnd += facep->getGeomCount(); @@ -5245,6 +5278,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		draw_info->mSpecularMap = NULL;  		draw_info->mMaterial = mat;  		draw_info->mShaderMask = shader_mask; +        draw_info->mAvatar = facep->mAvatar; +        draw_info->mSkinInfo = facep->mSkinInfo;  		if (mat)  		{ @@ -5411,11 +5446,21 @@ void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value)  // add a face pointer to a list of face pointers without going over MAX_COUNT faces  template<typename T> -static inline void add_face(T** list, U32& count, T* face) +static inline void add_face(T*** list, U32* count, T* face)  { -    if (count < MAX_FACE_COUNT) +    if (face->isState(LLFace::RIGGED)) +    { +        if (count[1] < MAX_FACE_COUNT) +        { +            list[1][count[1]++] = face; +        } +    } +    else      { -        list[count++] = face; +        if (count[0] < MAX_FACE_COUNT) +        { +            list[0][count[0]++] = face; +        }      }  } @@ -5465,14 +5510,13 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	mFaceList.clear(); -	U32 fullbright_count = 0; -	U32 bump_count = 0; -	U32 simple_count = 0; -	U32 alpha_count = 0; -	U32 norm_count = 0; -	U32 spec_count = 0; -	U32 normspec_count = 0; - +    U32 fullbright_count[2] = { 0 }; +	U32 bump_count[2] = { 0 }; +	U32 simple_count[2] = { 0 }; +	U32 alpha_count[2] = { 0 }; +	U32 norm_count[2] = { 0 }; +	U32 spec_count[2] = { 0 }; +	U32 normspec_count[2] = { 0 };  	U32 useage = group->getSpatialPartition()->mBufferUsage; @@ -5521,7 +5565,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)              std::string vobj_name = llformat("Vol%p", vobj); -			if (vobj->isMesh() && +            bool is_mesh = vobj->isMesh(); +			if (is_mesh &&  				((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled()))  			{  				continue; @@ -5534,7 +5579,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  				group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]);  			} -            bool is_mesh = vobj->isMesh(); +                          F32 est_tris = vobj->getEstTrianglesMax();              vobj->updateControlAvatar(); @@ -5558,15 +5603,32 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  			drawablep->clearState(LLDrawable::HAS_ALPHA); -            if (vobj->isRiggedMesh() && -                ((vobj->isAnimatedObject() && vobj->getControlAvatar()) || -                 (!vobj->isAnimatedObject() && vobj->getAvatar()))) +            LLVOAvatar* avatar = nullptr; +            const LLMeshSkinInfo* skinInfo = nullptr; +            if (is_mesh) +            { +                skinInfo = vobj->getSkinInfo(); +            } + +            if (skinInfo) +            { +                if (vobj->isAnimatedObject()) +                { +                    avatar = vobj->getControlAvatar(); +                } +                else +                { +                    avatar = vobj->getAvatar(); +                } +            } + +            if (avatar != nullptr)              { -                vobj->getAvatar()->addAttachmentOverridesForObject(vobj, NULL, false); +                avatar->addAttachmentOverridesForObject(vobj, NULL, false);              }              // Standard rigged mesh attachments:  -			bool rigged = !vobj->isAnimatedObject() && vobj->isRiggedMesh() && vobj->isAttachment(); +			bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment();              // Animated objects. Have to check for isRiggedMesh() to              // exclude static objects in animated object linksets.  			rigged = rigged || (vobj->isAnimatedObject() && vobj->isRiggedMesh() && @@ -5590,183 +5652,19 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  				//sum up face verts and indices  				drawablep->updateFaceSize(i); -			 -				if (rigged) -				{ -					if (!facep->isState(LLFace::RIGGED)) -					{ //completely reset vertex buffer -						facep->clearVertexBuffer(); -					} -		 -					facep->setState(LLFace::RIGGED); -					any_rigged_face = true; -				 -					//get drawpool of avatar with rigged face -					LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj);				 -					 -					if (pool) -					{ -						const LLTextureEntry* te = facep->getTextureEntry(); - -						//remove face from old pool if it exists -						LLDrawPool* old_pool = facep->getPool(); -						if (old_pool -							&& (old_pool->getType() == LLDrawPool::POOL_AVATAR || old_pool->getType() == LLDrawPool::POOL_CONTROL_AV)) -						{ -							((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep); -						} - -						//add face to new pool -						LLViewerTexture* tex = facep->getTexture(); -						U32 type = gPipeline.getPoolTypeFromTE(te, tex); - -                        F32 te_alpha = te->getColor().mV[3]; - -						if (te->getGlow()) -						{ -							pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW); -						} - -						LLMaterial* mat = te->getMaterialParams().get(); -                        bool fullbright = te->getFullbright(); - -						if (mat && LLPipeline::sRenderDeferred) -						{ -							U8 alpha_mode = mat->getDiffuseAlphaMode(); - -							bool is_alpha = type == LLDrawPool::POOL_ALPHA && -								(alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND || -								te_alpha < 0.999f); - -							if (is_alpha) -							{ //this face needs alpha blending, override alpha mode -								alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; -							} - -                            if (fullbright && (alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE)) -                            { -                                pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); -                            } -							else if (!is_alpha || te_alpha > 0.f)  // //only add the face if it will actually be visible -							{  -								U32 mask = mat->getShaderMask(alpha_mode); -								pool->addRiggedFace(facep, mask); -							} - -							if(vobj->isAnimatedObject() && vobj->isRiggedMesh()) -							{ -								pool->updateRiggedVertexBuffers(vobj->getAvatar()); -							} -						} -						else if (mat) -						{							 -							bool is_alpha = type == LLDrawPool::POOL_ALPHA; -							U8 mode = mat->getDiffuseAlphaMode(); -							bool can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE || -												mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE; -							 -							if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && te->getColor().mV[3] >= 0.999f) -							{ -								pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE); -							} -							else if (is_alpha || (te->getColor().mV[3] < 0.999f)) -							{ -								if (te->getColor().mV[3] > 0.f) -								{ -									pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA : LLDrawPoolAvatar::RIGGED_ALPHA); -								} -							} -							else if (gPipeline.canUseVertexShaders() -								&& LLPipeline::sRenderBump  -								&& te->getShiny()  -								&& can_be_shiny) -							{ -								pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY : LLDrawPoolAvatar::RIGGED_SHINY); -							} -							else -							{ -								pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE); -							} -						} -						else -						{ -						if (type == LLDrawPool::POOL_ALPHA) -						{ -							if (te->getColor().mV[3] > 0.f) -							{ -								if (te->getFullbright()) -								{ -									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); -								} -								else -								{ -									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); -								} -							} -						} -						else if (te->getShiny()) -						{ -							if (te->getFullbright()) -							{ -								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY); -							} -							else -							{ -								if (LLPipeline::sRenderDeferred) -								{ -									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); -								} -								else -								{ -									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY); -								} -							} -						} -						else -						{ -							if (te->getFullbright()) -							{ -								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); -							} -							else -							{ -								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); -							} -						} - - -						if (LLPipeline::sRenderDeferred) -						{ -							if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright()) -							{ -								if (te->getBumpmap()) -								{ -									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP); -								} -								else -								{ -									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE); -								} -							} -						} -					} -					} -					continue; -				} -				else -				{ -					if (facep->isState(LLFace::RIGGED)) -					{ //face is not rigged but used to be, remove from rigged face pool -						LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool(); -						if (pool) -						{ -							pool->removeRiggedFace(facep); -						} -						facep->clearState(LLFace::RIGGED); -					} -				} +                if (rigged) +                { +                    if (!facep->isState(LLFace::RIGGED)) +                    { //completely reset vertex buffer +                        facep->clearVertexBuffer(); +                    } +                    facep->setState(LLFace::RIGGED); +                    facep->mSkinInfo = (LLMeshSkinInfo*) skinInfo; // TODO -- fix ugly de-consting here +                    facep->mAvatar = avatar; +                    any_rigged_face = true; +                }  				if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0)  				{ @@ -5776,7 +5674,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  				cur_total += facep->getGeomCount(); -				if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA) +				if (facep->hasGeometry() &&  +                    (rigged ||  // <-- HACK FIXME -- getPixelArea might be incorrect for rigged objects +                        facep->getPixelArea() > FORCE_CULL_AREA)) // <-- don't render tiny faces  				{  					const LLTextureEntry* te = facep->getTextureEntry();  					LLViewerTexture* tex = facep->getTexture(); @@ -5966,6 +5866,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	BOOL batch_textures = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1; +    // add extra vertex data for deferred rendering (not necessarily for batching textures)  	if (batch_textures)  	{  		bump_mask = bump_mask | LLVertexBuffer::MAP_TANGENT; @@ -5978,13 +5879,23 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	U32 geometryBytes = 0; -	geometryBytes += genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSimpleFaces, simple_count, FALSE, batch_textures, FALSE); -	geometryBytes += genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sFullbrightFaces, fullbright_count, FALSE, batch_textures); -	geometryBytes += genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sAlphaFaces, alpha_count, TRUE, batch_textures); -	geometryBytes += genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sBumpFaces, bump_count, FALSE, FALSE); -	geometryBytes += genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormFaces, norm_count, FALSE, FALSE); -	geometryBytes += genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSpecFaces, spec_count, FALSE, FALSE); -	geometryBytes += genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormSpecFaces, normspec_count, FALSE, FALSE); +    U32 extra_mask = LLVertexBuffer::MAP_TEXTURE_INDEX; +	geometryBytes += genDrawInfo(group, simple_mask | extra_mask, sSimpleFaces[0], simple_count[0], FALSE, batch_textures); +	geometryBytes += genDrawInfo(group, fullbright_mask | extra_mask, sFullbrightFaces[0], fullbright_count[0], FALSE, batch_textures); +	geometryBytes += genDrawInfo(group, alpha_mask | extra_mask, sAlphaFaces[0], alpha_count[0], TRUE, batch_textures); +	geometryBytes += genDrawInfo(group, bump_mask | extra_mask, sBumpFaces[0], bump_count[0], FALSE, FALSE); +	geometryBytes += genDrawInfo(group, norm_mask | extra_mask, sNormFaces[0], norm_count[0], FALSE, FALSE); +	geometryBytes += genDrawInfo(group, spec_mask | extra_mask, sSpecFaces[0], spec_count[0], FALSE, FALSE); +	geometryBytes += genDrawInfo(group, normspec_mask | extra_mask, sNormSpecFaces[0], normspec_count[0], FALSE, FALSE); + +    extra_mask |= LLVertexBuffer::MAP_WEIGHT4; +    geometryBytes += genDrawInfo(group, simple_mask | extra_mask, sSimpleFaces[1], simple_count[1], FALSE, batch_textures, TRUE); +    geometryBytes += genDrawInfo(group, fullbright_mask | extra_mask, sFullbrightFaces[1], fullbright_count[1], FALSE, batch_textures, TRUE); +    geometryBytes += genDrawInfo(group, alpha_mask | extra_mask, sAlphaFaces[1], alpha_count[1], TRUE, batch_textures, TRUE); +    geometryBytes += genDrawInfo(group, bump_mask | extra_mask, sBumpFaces[1], bump_count[1], FALSE, TRUE); +    geometryBytes += genDrawInfo(group, norm_mask | extra_mask, sNormFaces[1], norm_count[1], FALSE, TRUE); +    geometryBytes += genDrawInfo(group, spec_mask | extra_mask, sSpecFaces[1], spec_count[1], FALSE, TRUE); +    geometryBytes += genDrawInfo(group, normspec_mask | extra_mask, sNormSpecFaces[1], normspec_count[1], FALSE, TRUE);  	group->mGeometryBytes = geometryBytes; @@ -6146,7 +6057,7 @@ struct CompareBatchBreakerModified  		const LLTextureEntry* lte = lhs->getTextureEntry();  		const LLTextureEntry* rte = rhs->getTextureEntry(); -		if (lte->getBumpmap() != rte->getBumpmap()) +        if (lte->getBumpmap() != rte->getBumpmap())  		{  			return lte->getBumpmap() < rte->getBumpmap();  		} @@ -6169,8 +6080,43 @@ struct CompareBatchBreakerModified  	}  }; +struct CompareBatchBreakerRigged +{ +    bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) +    { +        const LLTextureEntry* lte = lhs->getTextureEntry(); +        const LLTextureEntry* rte = rhs->getTextureEntry(); + +        if (lhs->mAvatar != rhs->mAvatar) +        { +            return lhs->mAvatar < rhs->mAvatar; +        } +        else if (lhs->mSkinInfo->mHash != rhs->mSkinInfo->mHash) +        { +            return lhs->mSkinInfo->mHash < rhs->mSkinInfo->mHash; +        } +        else if (lhs->getTexture() != rhs->getTexture()) +        { +            return lhs->getTexture() < rhs->getTexture(); +        } +        else if (lte->getBumpmap() != rte->getBumpmap()) +        { +            return lte->getBumpmap() < rte->getBumpmap(); +        } +        else if (LLPipeline::sRenderDeferred && lte->getMaterialID() != rte->getMaterialID()) +        { +            return lte->getMaterialID() < rte->getMaterialID(); +        } +        else // if (LLPipeline::sRenderDeferred && (lte->getMaterialParams() == rte->getMaterialParams()) && (lte->getShiny() != rte->getShiny())) +        { +            return lte->getShiny() < rte->getShiny(); +        } +         +    } +}; + -U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL no_materials) +U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL rigged)  {      LL_PROFILE_ZONE_SCOPED; @@ -6205,11 +6151,17 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  	{          LL_PROFILE_ZONE_NAMED("genDrawInfo - sort"); -		if (!distance_sort) -		{ -			//sort faces by things that break batches -			std::sort(faces, faces+face_count, CompareBatchBreakerModified()); -		} +         +        if (rigged) +        { +            //sort faces by things that break batches, including avatar and mesh id +            std::sort(faces, faces + face_count, CompareBatchBreakerRigged()); +        } +        else if (!distance_sort) +        { +            //sort faces by things that break batches, not including avatar and mesh id +            std::sort(faces, faces + face_count, CompareBatchBreakerModified()); +        }  		else  		{  			//sort faces by distance @@ -6226,11 +6178,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  	LLViewerTexture* last_tex = NULL;  	S32 buffer_index = 0; -	if (distance_sort) -	{ -		buffer_index = -1; -	} -  	S32 texture_index_channels = 1;  	if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30) @@ -6242,6 +6189,16 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  	{  		texture_index_channels = gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels;  	} +     +    if (rigged) +    { //don't attempt distance sorting on rigged meshes, not likely to succeed and breaks batches +        distance_sort = FALSE; +    } + +    if (distance_sort) +    { +        buffer_index = -1; +    }  	static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);  	texture_index_channels = llmin(texture_index_channels, (S32) max_texture_index); @@ -6256,7 +6213,9 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  		//pull off next face  		LLFace* facep = *face_iter;  		LLViewerTexture* tex = facep->getTexture(); -		LLMaterialPtr mat = facep->getTextureEntry()->getMaterialParams(); +        const LLTextureEntry* te = facep->getTextureEntry(); +		LLMaterialPtr mat = te->getMaterialParams(); +        LLMaterialID matId = te->getMaterialID();  		if (distance_sort)  		{ @@ -6379,11 +6338,14 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  				while (i != end_faces &&   					(LLPipeline::sTextureBindTest ||   						(distance_sort ||  -							((*i)->getTexture() == tex && -							((*i)->getTextureEntry()->getMaterialParams() == mat))))) +							((*i)->getTexture() == tex))))  				{  					facep = *i; -			 +                    const LLTextureEntry* nextTe = facep->getTextureEntry(); +                    if (nextTe->getMaterialID() != matId) +                    { +                        break; +                    }  					//face has no texture index  					facep->mDrawInfo = NULL; @@ -6473,8 +6435,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  					U32 te_idx = facep->getTEOffset(); -					llassert(!facep->isState(LLFace::RIGGED)); -  					if (!facep->getGeometryVolume(*volume, te_idx,   						vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset,true))  					{ @@ -6571,10 +6531,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  						}  					}  				} -				else if (no_materials) -				{ -					registerFace(group, facep, LLRenderPass::PASS_SIMPLE); -				}  				else if (transparent)  				{  					registerFace(group, facep, LLRenderPass::PASS_ALPHA); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index cb54b1eaed..4710fdb085 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -7408,32 +7408,91 @@ void LLPipeline::doResetVertexBuffers(bool forced)  	LLVOPartGroup::restoreGL();  } -void LLPipeline::renderObjects(U32 type, U32 mask, bool texture, bool batch_texture) +void LLPipeline::renderObjects(U32 type, U32 mask, bool texture, bool batch_texture, bool rigged)  {  	assertInitialized();  	gGL.loadMatrix(gGLModelView);  	gGLLastMatrix = NULL; -	mSimplePool->pushBatches(type, mask, texture, batch_texture); +    if (rigged) +    { +        mSimplePool->pushRiggedBatches(type + 1, mask, texture, batch_texture); +    } +    else +    { +        mSimplePool->pushBatches(type, mask, texture, batch_texture); +    }  	gGL.loadMatrix(gGLModelView);  	gGLLastMatrix = NULL;		  } -void LLPipeline::renderMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture) +void LLPipeline::renderAlphaObjects(U32 mask, bool texture, bool batch_texture, bool rigged) +{ +    LL_PROFILE_ZONE_SCOPED; +    assertInitialized(); +    gGL.loadMatrix(gGLModelView); +    gGLLastMatrix = NULL; +    U32 type = LLRenderPass::PASS_ALPHA; +    LLVOAvatar* lastAvatar = nullptr; +    U64 lastMeshId = 0; +    for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) +    { +        LLDrawInfo* pparams = *i; +        if (pparams) +        { +            if (rigged) +            { +                if (pparams->mAvatar != nullptr) +                { +                    if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash) +                    { +                        mSimplePool->uploadMatrixPalette(*pparams); +                        lastAvatar = pparams->mAvatar; +                        lastMeshId = pparams->mSkinInfo->mHash; +                    } + +                    mSimplePool->pushBatch(*pparams, mask | LLVertexBuffer::MAP_WEIGHT4, texture, batch_texture); +                } +            } +            else if (pparams->mAvatar == nullptr) +            { +                mSimplePool->pushBatch(*pparams, mask, texture, batch_texture); +            } +        } +    } +    gGL.loadMatrix(gGLModelView); +    gGLLastMatrix = NULL; +} + +void LLPipeline::renderMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture, bool rigged)  {  	assertInitialized();  	gGL.loadMatrix(gGLModelView);  	gGLLastMatrix = NULL; -	mAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture); +    if (rigged) +    { +        mAlphaMaskPool->pushRiggedMaskBatches(type+1, mask, texture, batch_texture); +    } +    else +    { +        mAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture); +    }  	gGL.loadMatrix(gGLModelView);  	gGLLastMatrix = NULL;		  } -void LLPipeline::renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture) +void LLPipeline::renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture, bool rigged)  {  	assertInitialized();  	gGL.loadMatrix(gGLModelView);  	gGLLastMatrix = NULL; -	mFullbrightAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture); +    if (rigged) +    { +        mFullbrightAlphaMaskPool->pushRiggedMaskBatches(type+1, mask, texture, batch_texture); +    } +    else +    { +        mFullbrightAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture); +    }  	gGL.loadMatrix(gGLModelView);  	gGLLastMatrix = NULL;		  } @@ -9587,198 +9646,207 @@ static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_TREE("Alpha Tree");  static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_GRASS("Alpha Grass");  static LLTrace::BlockTimerStatHandle FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED("Fullbright Alpha Masked"); -void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult &result, bool use_shader, bool use_occlusion, U32 target_width) +void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult& result, bool use_shader, bool use_occlusion, U32 target_width)  { -	LL_RECORD_BLOCK_TIME(FTM_SHADOW_RENDER); +    LL_RECORD_BLOCK_TIME(FTM_SHADOW_RENDER); -	//clip out geometry on the same side of water as the camera -	S32 occlude = LLPipeline::sUseOcclusion; -	if (!use_occlusion) -	{ -		LLPipeline::sUseOcclusion = 0; -	} -	LLPipeline::sShadowRender = true; -	 -	static const U32 types[] = {  -		LLRenderPass::PASS_SIMPLE,  -		LLRenderPass::PASS_FULLBRIGHT,  -		LLRenderPass::PASS_SHINY,  -		LLRenderPass::PASS_BUMP,  -		LLRenderPass::PASS_FULLBRIGHT_SHINY , -		LLRenderPass::PASS_MATERIAL, -		LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, -		LLRenderPass::PASS_SPECMAP, -		LLRenderPass::PASS_SPECMAP_EMISSIVE, -		LLRenderPass::PASS_NORMMAP, -		LLRenderPass::PASS_NORMMAP_EMISSIVE, -		LLRenderPass::PASS_NORMSPEC, -		LLRenderPass::PASS_NORMSPEC_EMISSIVE, -	}; +    //clip out geometry on the same side of water as the camera +    S32 occlude = LLPipeline::sUseOcclusion; +    if (!use_occlusion) +    { +        LLPipeline::sUseOcclusion = 0; +    } +    LLPipeline::sShadowRender = true; + +    static const U32 types[] = { +        LLRenderPass::PASS_SIMPLE, +        LLRenderPass::PASS_FULLBRIGHT, +        LLRenderPass::PASS_SHINY, +        LLRenderPass::PASS_BUMP, +        LLRenderPass::PASS_FULLBRIGHT_SHINY , +        LLRenderPass::PASS_MATERIAL, +        LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, +        LLRenderPass::PASS_SPECMAP, +        LLRenderPass::PASS_SPECMAP_EMISSIVE, +        LLRenderPass::PASS_NORMMAP, +        LLRenderPass::PASS_NORMMAP_EMISSIVE, +        LLRenderPass::PASS_NORMSPEC, +        LLRenderPass::PASS_NORMSPEC_EMISSIVE, +    }; + +    LLGLEnable cull(GL_CULL_FACE); + +    //enable depth clamping if available +    LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0); + +    if (use_shader) +    { +        gDeferredShadowCubeProgram.bind(); +    } -	LLGLEnable cull(GL_CULL_FACE); +    LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID - 1]; -	//enable depth clamping if available -	LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0); +    occlusion_target.bindTarget(); +    updateCull(shadow_cam, result); +    occlusion_target.flush(); -	if (use_shader) -	{ -		gDeferredShadowCubeProgram.bind(); -	} +    stateSort(shadow_cam, result); -	LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID-1]; -	occlusion_target.bindTarget(); -	updateCull(shadow_cam, result); -	occlusion_target.flush(); +    //generate shadow map +    gGL.matrixMode(LLRender::MM_PROJECTION); +    gGL.pushMatrix(); +    gGL.loadMatrix(proj.m); +    gGL.matrixMode(LLRender::MM_MODELVIEW); +    gGL.pushMatrix(); +    gGL.loadMatrix(view.m); -	stateSort(shadow_cam, result); -	 -	 -	//generate shadow map -	gGL.matrixMode(LLRender::MM_PROJECTION); -	gGL.pushMatrix(); -	gGL.loadMatrix(proj.m); -	gGL.matrixMode(LLRender::MM_MODELVIEW); -	gGL.pushMatrix(); -	gGL.loadMatrix(view.m); +    stop_glerror(); +    gGLLastMatrix = NULL; -	stop_glerror(); -	gGLLastMatrix = NULL; +    gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + +    stop_glerror(); -	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -	 -	stop_glerror(); -	      LLEnvironment& environment = LLEnvironment::instance(); -	LLVertexBuffer::unbind(); +    LLVertexBuffer::unbind(); -	{ -		if (!use_shader) -		{ //occlusion program is general purpose depth-only no-textures -			gOcclusionProgram.bind(); -		} -		else -		{ -			gDeferredShadowProgram.bind(); -            gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); -		} +    for (int j = 0; j < 2; ++j) // 0 -- static, 1 -- rigged +    { +        bool rigged = j == 1; +        if (!use_shader) +        { //occlusion program is general purpose depth-only no-textures +            gOcclusionProgram.bind(rigged); +        } +        else +        { +            gDeferredShadowProgram.bind(rigged); +            LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); +        } -		gGL.diffuseColor4f(1,1,1,1); +        gGL.diffuseColor4f(1, 1, 1, 1);          S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail");          // if not using VSM, disable color writes          if (shadow_detail <= 2)          { -		gGL.setColorMask(false, false); +            gGL.setColorMask(false, false);          } -	 -		LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE); -		 -		gGL.getTexUnit(0)->disable(); -		for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i) -		{ -			renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); -		} -		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); -		if (!use_shader) -		{ -			gOcclusionProgram.unbind(); -		} -	} -	 -	if (use_shader) -	{ + +        LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE); + +        gGL.getTexUnit(0)->disable(); +        for (U32 i = 0; i < sizeof(types) / sizeof(U32); ++i) +        { +            renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE, FALSE, rigged); +        } +        gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); +        if (!use_shader) +        { +            gOcclusionProgram.unbind(); +        } + + +    } + +    if (use_shader) +    {          LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM); -		gDeferredShadowProgram.unbind(); -		renderGeomShadow(shadow_cam); -		gDeferredShadowProgram.bind(); +        gDeferredShadowProgram.unbind(); +        renderGeomShadow(shadow_cam); +        gDeferredShadowProgram.bind();          gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); -	} -	else -	{ +    } +    else +    {          LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM); -		renderGeomShadow(shadow_cam); -	} +        renderGeomShadow(shadow_cam); +    } -	{ -		LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA); +    { +        LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA); -		gDeferredShadowAlphaMaskProgram.bind(); -		gDeferredShadowAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); -        gDeferredShadowAlphaMaskProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); +        for (int i = 0; i < 2; ++i) +        { +            bool rigged = i == 1; -		U32 mask =	LLVertexBuffer::MAP_VERTEX |  -					LLVertexBuffer::MAP_TEXCOORD0 |  -					LLVertexBuffer::MAP_COLOR |  -					LLVertexBuffer::MAP_TEXTURE_INDEX; +            gDeferredShadowAlphaMaskProgram.bind(rigged); +            LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); +            LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); -        { -            LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_MASKED); -		renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE); -        } +            U32 mask = LLVertexBuffer::MAP_VERTEX | +                LLVertexBuffer::MAP_TEXCOORD0 | +                LLVertexBuffer::MAP_COLOR | +                LLVertexBuffer::MAP_TEXTURE_INDEX; -        { -            LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_BLEND); -		gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f); -		renderObjects(LLRenderPass::PASS_ALPHA, mask, TRUE, TRUE); -        } +            { +                LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_MASKED); +                renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE, rigged); +            } -        { -            LL_RECORD_BLOCK_TIME(FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED); -            gDeferredShadowFullbrightAlphaMaskProgram.bind(); -            gDeferredShadowFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); -            gDeferredShadowFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); -            renderFullbrightMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE); -        } +            { +                LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_BLEND); +                LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(0.598f); +                renderAlphaObjects(mask, TRUE, TRUE, rigged); +            } -		mask = mask & ~LLVertexBuffer::MAP_TEXTURE_INDEX; -        { -            LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_TREE); -		gDeferredTreeShadowProgram.bind(); -            gDeferredTreeShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); -		renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, mask); -		renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, mask); -		renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, mask); -		renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, mask); +            { +                LL_RECORD_BLOCK_TIME(FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED); +                gDeferredShadowFullbrightAlphaMaskProgram.bind(rigged); +                LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); +                LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); +                renderFullbrightMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE, rigged); +            } + + +            { +                LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_GRASS); +                gDeferredTreeShadowProgram.bind(rigged); +                if (i == 0) +                { +                    LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(0.598f); +                    renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE); +                } + +                U32 no_idx_mask = mask & ~LLVertexBuffer::MAP_TEXTURE_INDEX; +                renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, no_idx_mask, true, false, rigged); +                renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, no_idx_mask, true, false, rigged); +                renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, no_idx_mask, true, false, rigged); +                renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, no_idx_mask, true, false, rigged); +            }          } -		 -        { -            LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_GRASS); -		gDeferredTreeShadowProgram.setMinimumAlpha(0.598f); -		renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE); -	}      } -	//glCullFace(GL_BACK); +    //glCullFace(GL_BACK); -	gDeferredShadowCubeProgram.bind(); -	gGLLastMatrix = NULL; -	gGL.loadMatrix(gGLModelView); +    gDeferredShadowCubeProgram.bind(); +    gGLLastMatrix = NULL; +    gGL.loadMatrix(gGLModelView); -	LLRenderTarget& occlusion_source = mShadow[LLViewerCamera::sCurCameraID-1]; +    LLRenderTarget& occlusion_source = mShadow[LLViewerCamera::sCurCameraID - 1]; -	doOcclusion(shadow_cam, occlusion_source, occlusion_target); +    doOcclusion(shadow_cam, occlusion_source, occlusion_target); -	if (use_shader) -	{ -		gDeferredShadowProgram.unbind(); -	} -	 -	gGL.setColorMask(true, true); -			 -	gGL.matrixMode(LLRender::MM_PROJECTION); -	gGL.popMatrix(); -	gGL.matrixMode(LLRender::MM_MODELVIEW); -	gGL.popMatrix(); -	gGLLastMatrix = NULL; +    if (use_shader) +    { +        gDeferredShadowProgram.unbind(); +    } -	LLPipeline::sUseOcclusion = occlude; -	LLPipeline::sShadowRender = false; +    gGL.setColorMask(true, true); + +    gGL.matrixMode(LLRender::MM_PROJECTION); +    gGL.popMatrix(); +    gGL.matrixMode(LLRender::MM_MODELVIEW); +    gGL.popMatrix(); +    gGLLastMatrix = NULL; + +    LLPipeline::sUseOcclusion = occlude; +    LLPipeline::sShadowRender = false;  }  bool LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir) @@ -10109,6 +10177,29 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  					LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND,  					LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK,  					LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE, +                    LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_SIMPLE_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_BUMP_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_SHINY_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_MATERIAL_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_SPECMAP_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_SPECMAP_BLEND_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_SPECMAP_MASK_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_SPECMAP_EMISSIVE_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_NORMMAP_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_NORMMAP_BLEND_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_NORMMAP_MASK_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_NORMMAP_EMISSIVE_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_NORMSPEC_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK_RIGGED, +                    LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED,  					END_RENDER_TYPES);  	gGL.setColorMask(false, false); @@ -10835,6 +10926,21 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, bool textu  	}  } +void LLPipeline::renderRiggedGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture) +{ +    for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) +    { +        LLSpatialGroup* group = *i; +        if (!group->isDead() && +            (!sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && +            gPipeline.hasRenderType(group->getSpatialPartition()->mDrawableType) && +            group->mDrawMap.find(type) != group->mDrawMap.end()) +        { +            pass->renderRiggedGroup(group, type, mask, texture); +        } +    } +} +  static LLTrace::BlockTimerStatHandle FTM_GENERATE_IMPOSTOR("Generate Impostor");  void LLPipeline::generateImpostor(LLVOAvatar* avatar) @@ -10870,37 +10976,31 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  	if (visually_muted || too_complex)  	{ +        // only show jelly doll geometry  		andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR,  							LLPipeline::RENDER_TYPE_CONTROL_AV,  							END_RENDER_TYPES);  	}  	else  	{ -		andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, -			LLPipeline::RENDER_TYPE_FULLBRIGHT, -			LLPipeline::RENDER_TYPE_VOLUME, -			LLPipeline::RENDER_TYPE_GLOW, -						LLPipeline::RENDER_TYPE_BUMP, -						LLPipeline::RENDER_TYPE_PASS_SIMPLE, -						LLPipeline::RENDER_TYPE_PASS_ALPHA, -						LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, -			LLPipeline::RENDER_TYPE_PASS_BUMP, -			LLPipeline::RENDER_TYPE_PASS_POST_BUMP, -						LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, -						LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, -						LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, -			LLPipeline::RENDER_TYPE_PASS_GLOW, -			LLPipeline::RENDER_TYPE_PASS_GRASS, -						LLPipeline::RENDER_TYPE_PASS_SHINY, -						LLPipeline::RENDER_TYPE_PASS_INVISIBLE, -						LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, -			LLPipeline::RENDER_TYPE_AVATAR, -			LLPipeline::RENDER_TYPE_CONTROL_AV, -			LLPipeline::RENDER_TYPE_ALPHA_MASK, -			LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, -			LLPipeline::RENDER_TYPE_INVISIBLE, -			LLPipeline::RENDER_TYPE_SIMPLE, -						END_RENDER_TYPES); +        //hide world geometry +        clearRenderTypeMask( +            RENDER_TYPE_SKY, +            RENDER_TYPE_WL_SKY, +            RENDER_TYPE_GROUND, +            RENDER_TYPE_TERRAIN, +            RENDER_TYPE_GRASS, +            RENDER_TYPE_CONTROL_AV, // Animesh +            RENDER_TYPE_TREE, +            RENDER_TYPE_VOIDWATER, +            RENDER_TYPE_WATER, +            RENDER_TYPE_PASS_GRASS, +            RENDER_TYPE_HUD, +            RENDER_TYPE_PARTICLES, +            RENDER_TYPE_CLOUDS, +            RENDER_TYPE_HUD_PARTICLES, +            END_RENDER_TYPES +         );  	}  	S32 occlusion = sUseOcclusion; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index b87a726647..110df8c979 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -266,11 +266,13 @@ public:      void touchTextures(LLDrawInfo* info);  	void forAllVisibleDrawables(void (*func)(LLDrawable*)); -	void renderObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false); -	void renderMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false); -    void renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false); +    void renderObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false); +    void renderAlphaObjects(U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false); +	void renderMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false); +    void renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false);  	void renderGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture); +    void renderRiggedGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture);  	void grabReferences(LLCullResult& result);  	void clearReferences(); @@ -457,34 +459,61 @@ public:   		RENDER_TYPE_ALPHA						= LLDrawPool::POOL_ALPHA,  		RENDER_TYPE_GLOW						= LLDrawPool::POOL_GLOW,  		RENDER_TYPE_PASS_SIMPLE 				= LLRenderPass::PASS_SIMPLE, +        RENDER_TYPE_PASS_SIMPLE_RIGGED = LLRenderPass::PASS_SIMPLE_RIGGED,  		RENDER_TYPE_PASS_GRASS					= LLRenderPass::PASS_GRASS,  		RENDER_TYPE_PASS_FULLBRIGHT				= LLRenderPass::PASS_FULLBRIGHT, +        RENDER_TYPE_PASS_FULLBRIGHT_RIGGED = LLRenderPass::PASS_FULLBRIGHT,  		RENDER_TYPE_PASS_INVISIBLE				= LLRenderPass::PASS_INVISIBLE, +        RENDER_TYPE_PASS_INVISIBLE_RIGGED = LLRenderPass::PASS_INVISIBLE_RIGGED,  		RENDER_TYPE_PASS_INVISI_SHINY			= LLRenderPass::PASS_INVISI_SHINY, +        RENDER_TYPE_PASS_INVISI_SHINY_RIGGED = LLRenderPass::PASS_INVISI_SHINY_RIGGED,  		RENDER_TYPE_PASS_FULLBRIGHT_SHINY		= LLRenderPass::PASS_FULLBRIGHT_SHINY, +        RENDER_TYPE_PASS_FULLBRIGHT_SHINY_RIGGED = LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED,  		RENDER_TYPE_PASS_SHINY					= LLRenderPass::PASS_SHINY, +        RENDER_TYPE_PASS_SHINY_RIGGED = LLRenderPass::PASS_SHINY_RIGGED,  		RENDER_TYPE_PASS_BUMP					= LLRenderPass::PASS_BUMP, +        RENDER_TYPE_PASS_BUMP_RIGGED = LLRenderPass::PASS_BUMP_RIGGED,  		RENDER_TYPE_PASS_POST_BUMP				= LLRenderPass::PASS_POST_BUMP, +        RENDER_TYPE_PASS_POST_BUMP_RIGGED = LLRenderPass::PASS_POST_BUMP_RIGGED,  		RENDER_TYPE_PASS_GLOW					= LLRenderPass::PASS_GLOW, +        RENDER_TYPE_PASS_GLOW_RIGGED = LLRenderPass::PASS_GLOW_RIGGED,  		RENDER_TYPE_PASS_ALPHA					= LLRenderPass::PASS_ALPHA,  		RENDER_TYPE_PASS_ALPHA_MASK				= LLRenderPass::PASS_ALPHA_MASK, +        RENDER_TYPE_PASS_ALPHA_MASK_RIGGED = LLRenderPass::PASS_ALPHA_MASK_RIGGED,  		RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK	= LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, +        RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK_RIGGED = LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED,  		RENDER_TYPE_PASS_MATERIAL				= LLRenderPass::PASS_MATERIAL, +        RENDER_TYPE_PASS_MATERIAL_RIGGED = LLRenderPass::PASS_MATERIAL_RIGGED,  		RENDER_TYPE_PASS_MATERIAL_ALPHA			= LLRenderPass::PASS_MATERIAL_ALPHA, +        RENDER_TYPE_PASS_MATERIAL_ALPHA_RIGGED = LLRenderPass::PASS_MATERIAL_ALPHA_RIGGED,  		RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK	= LLRenderPass::PASS_MATERIAL_ALPHA_MASK, +        RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK_RIGGED = LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED,  		RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE= LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, +        RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED = LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED,  		RENDER_TYPE_PASS_SPECMAP				= LLRenderPass::PASS_SPECMAP, +        RENDER_TYPE_PASS_SPECMAP_RIGGED = LLRenderPass::PASS_SPECMAP_RIGGED,  		RENDER_TYPE_PASS_SPECMAP_BLEND			= LLRenderPass::PASS_SPECMAP_BLEND, +        RENDER_TYPE_PASS_SPECMAP_BLEND_RIGGED = LLRenderPass::PASS_SPECMAP_BLEND_RIGGED,  		RENDER_TYPE_PASS_SPECMAP_MASK			= LLRenderPass::PASS_SPECMAP_MASK, +        RENDER_TYPE_PASS_SPECMAP_MASK_RIGGED = LLRenderPass::PASS_SPECMAP_MASK_RIGGED,  		RENDER_TYPE_PASS_SPECMAP_EMISSIVE		= LLRenderPass::PASS_SPECMAP_EMISSIVE, +        RENDER_TYPE_PASS_SPECMAP_EMISSIVE_RIGGED = LLRenderPass::PASS_SPECMAP_EMISSIVE_RIGGED,  		RENDER_TYPE_PASS_NORMMAP				= LLRenderPass::PASS_NORMMAP, +        RENDER_TYPE_PASS_NORMMAP_RIGGED = LLRenderPass::PASS_NORMMAP_RIGGED,  		RENDER_TYPE_PASS_NORMMAP_BLEND			= LLRenderPass::PASS_NORMMAP_BLEND, +        RENDER_TYPE_PASS_NORMMAP_BLEND_RIGGED = LLRenderPass::PASS_NORMMAP_BLEND_RIGGED,  		RENDER_TYPE_PASS_NORMMAP_MASK			= LLRenderPass::PASS_NORMMAP_MASK, +        RENDER_TYPE_PASS_NORMMAP_MASK_RIGGED = LLRenderPass::PASS_NORMMAP_MASK_RIGGED,  		RENDER_TYPE_PASS_NORMMAP_EMISSIVE		= LLRenderPass::PASS_NORMMAP_EMISSIVE, +        RENDER_TYPE_PASS_NORMMAP_EMISSIVE_RIGGED = LLRenderPass::PASS_NORMMAP_EMISSIVE_RIGGED,  		RENDER_TYPE_PASS_NORMSPEC				= LLRenderPass::PASS_NORMSPEC, +        RENDER_TYPE_PASS_NORMSPEC_RIGGED = LLRenderPass::PASS_NORMSPEC_RIGGED,  		RENDER_TYPE_PASS_NORMSPEC_BLEND			= LLRenderPass::PASS_NORMSPEC_BLEND, +        RENDER_TYPE_PASS_NORMSPEC_BLEND_RIGGED = LLRenderPass::PASS_NORMSPEC_BLEND_RIGGED,  		RENDER_TYPE_PASS_NORMSPEC_MASK			= LLRenderPass::PASS_NORMSPEC_MASK, +        RENDER_TYPE_PASS_NORMSPEC_MASK_RIGGED = LLRenderPass::PASS_NORMSPEC_MASK_RIGGED,  		RENDER_TYPE_PASS_NORMSPEC_EMISSIVE		= LLRenderPass::PASS_NORMSPEC_EMISSIVE, +        RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED = LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED,  		// Following are object types (only used in drawable mRenderType)  		RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES,  		RENDER_TYPE_VOLUME, | 
