SL-16289 Rigged mesh rendering overhaul

master
Dave Parks 2021-11-20 18:49:19 +00:00
parent 3171aaad9b
commit 28f9fb06a9
58 changed files with 2444 additions and 4314 deletions

View File

@ -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)
{

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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();
};

View File

@ -1283,7 +1283,7 @@ void LLRender::syncLightState()
void LLRender::syncMatrices()
{
static const U32 name[] =
static const U32 name[] =
{
LLShaderMgr::MODELVIEW_MATRIX,
LLShaderMgr::PROJECTION_MATRIX,

View File

@ -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());

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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>

View File

@ -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();

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -56,5 +56,6 @@ void fullbright_lighting()
color.rgb = pow(color.rgb, vec3(1.0/texture_gamma));
frag_color = color;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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

View File

@ -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[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();
}
fullbright_shader->bind();
fullbright_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
fullbright_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
fullbright_shader->unbind();
simple_shader = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
(LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram;
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)
{
// install glow-accumulating blend mode
gGL.blendFunc(
LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color
LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow)
emissive_shader->bind();
drawEmissive(mask, draw);
// restore our alpha blend mode
gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
current_shader->bind();
}
void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives)
{
emissive_shader->bind();
emissive_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f);
emissive_shader[0]->bind();
emissive_shader[0]->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f);
gPipeline.enableLightsDynamic();
// install glow-accumulating blend mode
// don't touch color, add to alpha (glow)
gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE);
gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE);
for (LLDrawInfo* draw : emissives)
{
bool tex_setup = TexSetup(draw, false, emissive_shader);
bool tex_setup = TexSetup(draw, false);
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[0]->unbind();
}
void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives)
{
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);
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
for (LLDrawInfo* draw : emissives)
{
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);
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(&params);
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(&params, (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(&params, (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(&params);
rigged_emissives.push_back(&params);
}
else
{
drawEmissiveInline(mask, &params);
}
emissives.push_back(&params);
}
}
if (tex_setup)
@ -708,41 +748,56 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
}
}
bool rebind = false;
if (batch_fullbrights)
{
if (!fullbrights.empty())
{
light_enabled = false;
renderFullbrights(mask, fullbrights);
rebind = true;
}
}
if (batch_emissives)
{
bool rebind = false;
LLGLSLShader* lastShader = current_shader;
if (!emissives.empty())
{
light_enabled = true;
renderEmissives(mask, emissives);
rebind = true;
}
}
if (current_shader && rebind)
{
current_shader->bind();
if (!rigged_emissives.empty())
{
light_enabled = true;
renderRiggedEmissives(mask, rigged_emissives);
rebind = true;
}
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;
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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 beginDeferredRigid();
void beginDeferredImpostor();
void beginDeferredSkinned();
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 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;

View File

@ -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();
shader = &gObjectBumpProgram;
gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
if (mRigged)
{
llassert(shader->mRiggedVariant);
shader = shader->mRiggedVariant;
}
// 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
// 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);
}
}

View File

@ -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
};

View File

@ -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);

View File

@ -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

View File

@ -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)
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;
}
simple_shader->bind();
if (LLPipeline::sRenderingHUDs)
{
simple_shader = &gObjectSimpleImpostorProgram;
}
else if (LLPipeline::sUnderWaterRender)
{
simple_shader = &gObjectSimpleWaterProgram;
simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
}
else
{
simple_shader = &gObjectSimpleProgram;
}
if (mShaderLevel > 0)
{
simple_shader->bind();
if (LLPipeline::sRenderingHUDs)
{
simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
}
else
{
simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
}
}
else
{
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,28 +241,36 @@ void LLDrawPoolSimple::render(S32 pass)
LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE);
gPipeline.enableLightsDynamic();
if (mShaderLevel > 0)
{
U32 mask = getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX;
U32 mask = getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX;
pushBatches(LLRenderPass::PASS_SIMPLE, mask, TRUE, TRUE);
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
{
LLGLDisable alpha_test(GL_ALPHA_TEST);
renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask());
}
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);
}
}
}
}
@ -240,11 +278,6 @@ void LLDrawPoolSimple::render(S32 pass)
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK("Alpha Mask");
LLDrawPoolAlphaMask::LLDrawPoolAlphaMask() :
@ -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->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->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);
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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);
}
//////////////////////////
//

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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 )
{

View File

@ -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();

View File

@ -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);
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 = NULL;
sBumpFaces = NULL;
sSimpleFaces = NULL;
sNormFaces = NULL;
sSpecFaces = NULL;
sNormSpecFaces = NULL;
sAlphaFaces = NULL;
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))
{
list[count++] = face;
if (count[1] < MAX_FACE_COUNT)
{
list[1][count[1]++] = face;
}
}
else
{
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)
{
vobj->getAvatar()->addAttachmentOverridesForObject(vobj, NULL, false);
skinInfo = vobj->getSkinInfo();
}
if (skinInfo)
{
if (vobj->isAnimatedObject())
{
avatar = vobj->getControlAvatar();
}
else
{
avatar = vobj->getAvatar();
}
}
if (avatar != nullptr)
{
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();
U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL no_materials)
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 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);

View File

@ -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;
LLGLEnable cull(GL_CULL_FACE);
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,
};
//enable depth clamping if available
LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
LLGLEnable cull(GL_CULL_FACE);
if (use_shader)
{
gDeferredShadowCubeProgram.bind();
}
//enable depth clamping if available
LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID-1];
if (use_shader)
{
gDeferredShadowCubeProgram.bind();
}
occlusion_target.bindTarget();
updateCull(shadow_cam, result);
occlusion_target.flush();
LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID - 1];
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);
occlusion_target.bindTarget();
updateCull(shadow_cam, result);
occlusion_target.flush();
stop_glerror();
gGLLastMatrix = NULL;
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;
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);
}
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_GEOM);
gDeferredShadowProgram.unbind();
renderGeomShadow(shadow_cam);
gDeferredShadowProgram.bind();
gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
}
else
{
LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM);
renderGeomShadow(shadow_cam);
}
{
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);
U32 mask = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_TEXTURE_INDEX;
{
LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_MASKED);
renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE);
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)
{
LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_BLEND);
gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f);
renderObjects(LLRenderPass::PASS_ALPHA, mask, TRUE, TRUE);
renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE, FALSE, rigged);
}
gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
if (!use_shader)
{
gOcclusionProgram.unbind();
}
{
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);
}
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_ALPHA_GRASS);
gDeferredTreeShadowProgram.setMinimumAlpha(0.598f);
renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE);
}
}
//glCullFace(GL_BACK);
if (use_shader)
{
LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM);
gDeferredShadowCubeProgram.bind();
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
gDeferredShadowProgram.unbind();
renderGeomShadow(shadow_cam);
gDeferredShadowProgram.bind();
gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
}
else
{
LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM);
LLRenderTarget& occlusion_source = mShadow[LLViewerCamera::sCurCameraID-1];
renderGeomShadow(shadow_cam);
}
doOcclusion(shadow_cam, occlusion_source, occlusion_target);
{
LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA);
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;
for (int i = 0; i < 2; ++i)
{
bool rigged = i == 1;
LLPipeline::sUseOcclusion = occlude;
LLPipeline::sShadowRender = false;
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);
U32 mask = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_TEXTURE_INDEX;
{
LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_MASKED);
renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE, rigged);
}
{
LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_BLEND);
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(0.598f);
renderAlphaObjects(mask, TRUE, TRUE, rigged);
}
{
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);
}
}
}
//glCullFace(GL_BACK);
gDeferredShadowCubeProgram.bind();
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
LLRenderTarget& occlusion_source = mShadow[LLViewerCamera::sCurCameraID - 1];
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;
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;

View File

@ -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,