summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rwxr-xr-xindra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl21
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialF.glsl89
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialV.glsl57
-rw-r--r--indra/newview/lldrawpool.cpp4
-rw-r--r--indra/newview/lldrawpool.h2
-rw-r--r--indra/newview/lldrawpoolbump.cpp29
-rw-r--r--indra/newview/lldrawpoolmaterials.cpp237
-rw-r--r--indra/newview/lldrawpoolmaterials.h75
-rw-r--r--indra/newview/llmaterialmgr.cpp74
-rw-r--r--indra/newview/llviewerdisplay.cpp1
-rw-r--r--indra/newview/llviewerobject.cpp13
-rw-r--r--indra/newview/llviewershadermgr.cpp125
-rw-r--r--indra/newview/llviewershadermgr.h11
-rw-r--r--indra/newview/llvovolume.cpp17
-rw-r--r--indra/newview/pipeline.cpp31
-rw-r--r--indra/newview/pipeline.h4
19 files changed, 722 insertions, 78 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 85262b55a8..ca2905e963 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -153,6 +153,7 @@ set(viewer_SOURCE_FILES
lldrawpoolavatar.cpp
lldrawpoolbump.cpp
lldrawpoolground.cpp
+ lldrawpoolmaterials.cpp
lldrawpoolsimple.cpp
lldrawpoolsky.cpp
lldrawpoolterrain.cpp
@@ -730,6 +731,7 @@ set(viewer_HEADER_FILES
lldrawpoolalpha.h
lldrawpoolavatar.h
lldrawpoolbump.h
+ lldrawpoolmaterials.h
lldrawpoolground.h
lldrawpoolsimple.h
lldrawpoolsky.h
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
index 6e5cc69e39..aaf1e5e572 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
@@ -31,9 +31,6 @@ out vec4 frag_data[3];
uniform sampler2D diffuseMap;
uniform sampler2D bumpMap;
-uniform sampler2D specularMap;
-uniform float env_intensity;
-uniform vec4 specular_color;
VARYING vec3 vary_mat0;
VARYING vec3 vary_mat1;
@@ -45,17 +42,15 @@ VARYING vec2 vary_texcoord0;
void main()
{
vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb;
- vec4 spec = texture2D(specularMap, vary_texcoord0.xy);
- vec4 norm = texture2D(bumpMap, vary_texcoord0.xy);
- norm.xyz = norm.xyz * 2 - 1;
+ vec3 norm = texture2D(bumpMap, vary_texcoord0.xy).rgb * 2.0 - 1.0;
- vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
- dot(norm.xyz,vary_mat1),
- dot(norm.xyz,vary_mat2));
-
- frag_data[0] = vec4(col * (1 - spec.a * env_intensity), 0);
- frag_data[1] = vec4(spec.xyz * specular_color.xyz, specular_color.a * norm.a); // spec
+ vec3 tnorm = vec3(dot(norm,vary_mat0),
+ dot(norm,vary_mat1),
+ dot(norm,vary_mat2));
+
+ frag_data[0] = vec4(col * (1 - vertex_color.a), 0.0);
+ frag_data[1] = vertex_color.aaaa; // spec
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
vec3 nvn = normalize(tnorm);
- frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, spec.a * env_intensity);
+ frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, vertex_color.a);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
index 86390bdd83..85f28f68c0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
@@ -38,10 +38,10 @@ VARYING vec2 vary_texcoord0;
void main()
{
vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb;
- frag_data[0] = vec4(col, 0.0);
+ frag_data[0] = vec4(col * (1 - vertex_color.a), 0.0);
frag_data[1] = vertex_color.aaaa; // spec
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
+ frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, vertex_color.a);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
index 788b966af8..6b5a922c29 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
@@ -37,9 +37,9 @@ void main()
{
vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
- frag_data[0] = vec4(col, 0.0);
+ frag_data[0] = vec4(col * (1 - vertex_color.a), 0.0);
frag_data[1] = vertex_color.aaaa; // spec
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
+ frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, vertex_color.a);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
new file mode 100644
index 0000000000..4f7fc6a411
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -0,0 +1,89 @@
+/**
+ * @file materialF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+
+uniform sampler2D diffuseMap;
+
+uniform sampler2D bumpMap;
+
+uniform sampler2D specularMap;
+uniform float env_intensity;
+uniform vec4 specular_color;
+
+#ifdef ALPHA_TEST
+uniform float minimum_alpha;
+#endif
+
+VARYING vec3 vary_mat0;
+VARYING vec3 vary_mat1;
+VARYING vec3 vary_mat2;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+void main()
+{
+ vec4 col = texture2D(diffuseMap, vary_texcoord0.xy) * vertex_color;
+
+ #ifdef ALPHA_TEST
+ if (col.a < minimum_alpha)
+ {
+ discard;
+ }
+ #endif
+
+ vec4 spec = texture2D(specularMap, vary_texcoord0.xy);
+
+ vec4 norm = texture2D(bumpMap, vary_texcoord0.xy);
+
+ norm.xyz = norm.xyz * 2 - 1;
+
+ vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
+ dot(norm.xyz,vary_mat1),
+ dot(norm.xyz,vary_mat2));
+
+ vec4 final_color = col;
+ final_color.rgb *= 1 - spec.a * env_intensity;
+
+ #ifndef EMISSIVE_MASK
+ final_color.a = 0;
+ #endif
+
+ vec4 final_specular = spec;
+ final_specular.rgb *= specular_color.rgb;
+ final_specular.a = specular_color.a * norm.a;
+
+ vec4 final_normal = vec4(normalize(tnorm), spec.a * env_intensity);
+ final_normal.xyz = final_normal.xyz * 0.5 + 0.5;
+
+ frag_data[0] = final_color;
+ frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
+ frag_data[2] = final_normal; // XYZ = Normal. W = Env. intensity.
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
new file mode 100644
index 0000000000..c8d38bb8f7
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
@@ -0,0 +1,57 @@
+/**
+ * @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 mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec3 binormal;
+
+VARYING vec3 vary_mat0;
+VARYING vec3 vary_mat1;
+VARYING vec3 vary_mat2;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+void main()
+{
+ //transform vertex
+ 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 b = normalize(normal_matrix * binormal);
+ vec3 t = cross(b, n);
+
+ 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);
+
+ vertex_color = diffuse_color;
+}
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 94dd927d26..fc5571aa58 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -35,6 +35,7 @@
#include "lldrawpoolalpha.h"
#include "lldrawpoolavatar.h"
#include "lldrawpoolbump.h"
+#include "lldrawpoolmaterials.h"
#include "lldrawpoolground.h"
#include "lldrawpoolsimple.h"
#include "lldrawpoolsky.h"
@@ -98,6 +99,9 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
case POOL_BUMP:
poolp = new LLDrawPoolBump();
break;
+ case POOL_MATERIALS:
+ poolp = new LLDrawPoolMaterials();
+ break;
case POOL_WL_SKY:
poolp = new LLDrawPoolWLSky();
break;
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index ab9bb9e611..caa57ad583 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -50,6 +50,7 @@ public:
POOL_GROUND,
POOL_FULLBRIGHT,
POOL_BUMP,
+ POOL_MATERIALS,
POOL_TERRAIN,
POOL_SKY,
POOL_WL_SKY,
@@ -133,6 +134,7 @@ public:
PASS_SHINY,
PASS_BUMP,
PASS_POST_BUMP,
+ PASS_MATERIALS,
PASS_GLOW,
PASS_ALPHA,
PASS_ALPHA_MASK,
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 07384a136a..a264eae302 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -72,7 +72,7 @@ static LLGLSLShader* shader = NULL;
static S32 cube_channel = -1;
static S32 diffuse_channel = -1;
static S32 bump_channel = -1;
-static S32 spec_channel = -1;
+
// static
void LLStandardBumpmap::init()
{
@@ -153,7 +153,7 @@ void LLStandardBumpmap::addstandard()
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label;
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage =
LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id));
- gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLViewerTexture::BOOST_BUMP);
+ gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLViewerTexture::BOOST_BUMP) ;
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL );
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->forceToSaveRawImage(0) ;
LLStandardBumpmap::sStandardBumpmapCount++;
@@ -632,11 +632,6 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL
BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel)
{
U8 bump_code = params.mBump;
- if (params.mNormalMap.notNull())
- {
- bump_code = 99;
- return bindBumpMap(bump_code, params.mNormalMap, params.mVSize, channel);
- }
return bindBumpMap(bump_code, params.mTexture, params.mVSize, channel);
}
@@ -675,10 +670,7 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsi
case BE_DARKNESS:
bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code );
break;
- case 99:
- bump = tex;
- bump->addTextureStats(vsize);
- break;
+
default:
if( bump_code < LLStandardBumpmap::sStandardBumpmapCount )
{
@@ -828,7 +820,6 @@ void LLDrawPoolBump::beginDeferredPass(S32 pass)
gDeferredBumpProgram.bind();
diffuse_channel = gDeferredBumpProgram.enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
bump_channel = gDeferredBumpProgram.enableTexture(LLViewerShaderMgr::BUMP_MAP);
- spec_channel = gDeferredBumpProgram.enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(bump_channel)->unbind(LLTexUnit::TT_TEXTURE);
}
@@ -843,7 +834,6 @@ void LLDrawPoolBump::endDeferredPass(S32 pass)
mShiny = FALSE;
gDeferredBumpProgram.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
gDeferredBumpProgram.disableTexture(LLViewerShaderMgr::BUMP_MAP);
- gDeferredBumpProgram.disableTexture(LLViewerShaderMgr::SPECULAR_MAP);
gDeferredBumpProgram.unbind();
gGL.getTexUnit(0)->activate();
}
@@ -865,18 +855,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
{
LLDrawInfo& params = **i;
-
- gDeferredBumpProgram.uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);
- gDeferredBumpProgram.uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity);
-
- if (params.mSpecularMap)
- {
- params.mSpecularMap->addTextureStats(params.mVSize);
- gGL.getTexUnit(spec_channel)->bind(params.mSpecularMap);
- } else {
- gGL.getTexUnit(spec_channel)->bind(LLViewerFetchedTexture::sWhiteImagep);
- }
-
+
LLDrawPoolBump::bindBumpMap(params, bump_channel);
pushBatch(params, mask, TRUE);
}
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
new file mode 100644
index 0000000000..5eb3cb9629
--- /dev/null
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -0,0 +1,237 @@
+/**
+ * @file lldrawpool.cpp
+ * @brief LLDrawPoolMaterials class implementation
+ * @author Jonathan "Geenz" Goodman
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lldrawpoolmaterials.h"
+#include "llviewershadermgr.h"
+#include "pipeline.h"
+
+S32 diffuse_channel = -1;
+
+LLDrawPoolMaterials::LLDrawPoolMaterials()
+: LLRenderPass(LLDrawPool::POOL_MATERIALS)
+{
+
+}
+
+void LLDrawPoolMaterials::prerender()
+{
+ mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+}
+
+void LLDrawPoolMaterials::beginDeferredPass(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_MATERIALS);
+}
+
+void LLDrawPoolMaterials::endDeferredPass(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_MATERIALS);
+ LLRenderPass::endRenderPass(pass);
+}
+
+void LLDrawPoolMaterials::renderDeferred(S32 pass)
+{
+ U32 type = LLRenderPass::PASS_MATERIALS;
+ LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
+ LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
+
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
+ {
+ LLDrawInfo& params = **i;
+
+ switch (params.mDiffuseAlphaMode)
+ {
+ case 0:
+ LL_INFOS("Asdf") << "Renderererererrerererrrr!!!~!!!~!~" << LL_ENDL;
+ mShader = &gDeferredMaterialShinyNormal;
+ break;
+ case 1: // Alpha blending not supported in the opaque draw pool.
+ return;
+ case 2:
+ mShader = &gDeferredMaterialShinyNormalAlphaTest;
+ break;
+ case 3:
+ mShader = &gDeferredMaterialShinyNormalEmissive;
+ break;
+ };
+
+ mShader->bind();
+
+ mShader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);
+ mShader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity);
+
+ params.mNormalMap->addTextureStats(params.mVSize);
+ bindNormalMap(params.mNormalMap);
+
+ params.mSpecularMap->addTextureStats(params.mVSize);
+ bindSpecularMap(params.mNormalMap);
+
+ diffuse_channel = mShader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
+ pushBatch(params, VERTEX_DATA_MASK, TRUE);
+ mShader->disableTexture(LLShaderMgr::DIFFUSE_MAP);
+ mShader->unbind();
+ }
+}
+
+void LLDrawPoolMaterials::bindSpecularMap(LLViewerTexture* tex)
+{
+ mShader->bindTexture(LLShaderMgr::SPECULAR_MAP, tex);
+}
+
+void LLDrawPoolMaterials::bindNormalMap(LLViewerTexture* tex)
+{
+ mShader->bindTexture(LLShaderMgr::BUMP_MAP, tex);
+}
+
+void LLDrawPoolMaterials::beginRenderPass(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_MATERIALS);
+
+ // Materials isn't supported under forward rendering.
+ // Use the simple shaders to handle it instead.
+ // This is basically replicated from LLDrawPoolSimple.
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ mShader = &gObjectSimpleWaterProgram;
+ }
+ else
+ {
+ mShader = &gObjectSimpleProgram;
+ }
+
+ if (mVertexShaderLevel > 0)
+ {
+ mShader->bind();
+ }
+ else
+ {
+ // don't use shaders!
+ if (gGLManager.mHasShaderObjects)
+ {
+ LLGLSLShader::bindNoShader();
+ }
+ }
+}
+
+void LLDrawPoolMaterials::endRenderPass(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_MATERIALS);
+ stop_glerror();
+ LLRenderPass::endRenderPass(pass);
+ stop_glerror();
+ if (mVertexShaderLevel > 0)
+ {
+ mShader->unbind();
+ }
+}
+
+void LLDrawPoolMaterials::render(S32 pass)
+{
+ LLGLDisable blend(GL_BLEND);
+
+ { //render simple
+ LLFastTimer t(FTM_RENDER_MATERIALS);
+ gPipeline.enableLightsDynamic();
+
+ if (mVertexShaderLevel > 0)
+ {
+ U32 mask = getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX;
+
+ pushBatches(LLRenderPass::PASS_MATERIALS, mask, TRUE, TRUE);
+ }
+ else
+ {
+ LLGLDisable alpha_test(GL_ALPHA_TEST);
+ renderTexture(LLRenderPass::PASS_MATERIALS, getVertexDataMask());
+ }
+ }
+}
+
+
+void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
+{
+ applyModelMatrix(params);
+
+ bool tex_setup = false;
+
+ if (batch_textures && params.mTextureList.size() > 1)
+ {
+ for (U32 i = 0; i < params.mTextureList.size(); ++i)
+ {
+ if (params.mTextureList[i].notNull())
+ {
+ gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE);
+ }
+ }
+ }
+ else
+ { //not batching textures or batch has only 1 texture -- might need a texture matrix
+ if (params.mTextureMatrix)
+ {
+ //if (mShiny)
+ {
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ }
+
+ gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+
+ tex_setup = true;
+ }
+
+ if (mVertexShaderLevel > 1 && texture)
+ {
+ if (params.mTexture.notNull())
+ {
+ gGL.getTexUnit(diffuse_channel)->bind(params.mTexture);
+ params.mTexture->addTextureStats(params.mVSize);
+ }
+ else
+ {
+ gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+ }
+ }
+
+ if (params.mGroup)
+ {
+ params.mGroup->rebuildMesh();
+ }
+ params.mVertexBuffer->setBuffer(mask);
+ params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+ gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
+ if (tex_setup)
+ {
+ gGL.getTexUnit(0)->activate();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
+}
diff --git a/indra/newview/lldrawpoolmaterials.h b/indra/newview/lldrawpoolmaterials.h
new file mode 100644
index 0000000000..e8838c64d6
--- /dev/null
+++ b/indra/newview/lldrawpoolmaterials.h
@@ -0,0 +1,75 @@
+/**
+ * @file lldrawpoolmaterials.h
+ * @brief LLDrawPoolMaterials class definition
+ * @author Jonathan "Geenz" Goodman
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLDRAWPOOLMATERIALS_H
+#define LL_LLDRAWPOOLMATERIALS_H
+
+#include "v4coloru.h"
+#include "v2math.h"
+#include "v3math.h"
+#include "llvertexbuffer.h"
+#include "lldrawpool.h"
+
+class LLViewerTexture;
+class LLDrawInfo;
+class LLGLSLShader;
+
+class LLDrawPoolMaterials : public LLRenderPass
+{
+ LLGLSLShader *mShader;
+public:
+ LLDrawPoolMaterials();
+
+ enum
+ {
+ VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_COLOR |
+ LLVertexBuffer::MAP_BINORMAL
+ };
+
+ /*virtual*/ U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+
+ /*virtual*/ void render(S32 pass = 0);
+ /*virtual*/ void beginRenderPass( S32 pass );
+ /*virtual*/ void endRenderPass( S32 pass );
+ /*virtual*/ S32 getNumPasses() {return 1;}
+ /*virtual*/ void prerender();
+
+ /*virtual*/ S32 getNumDeferredPasses() {return 1;}
+ /*virtual*/ void beginDeferredPass(S32 pass);
+ /*virtual*/ void endDeferredPass(S32 pass);
+ /*virtual*/ void renderDeferred(S32 pass);
+
+ void bindSpecularMap(LLViewerTexture* tex);
+ void bindNormalMap(LLViewerTexture* tex);
+
+ /*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);
+};
+
+#endif //LL_LLDRAWPOOLMATERIALS_H
diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
index 6068c2606c..474e6b862e 100644
--- a/indra/newview/llmaterialmgr.cpp
+++ b/indra/newview/llmaterialmgr.cpp
@@ -2,9 +2,9 @@
* @file llmaterialmgr.cpp
* @brief Material manager
*
- * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2013, 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
@@ -96,10 +96,10 @@ void LLMaterialsResponder::result(const LLSD& pContent)
void LLMaterialsResponder::error(U32 pStatus, const std::string& pReason)
{
- LL_WARNS("debugMaterials") << "--------------------------------------------------------------------------" << LL_ENDL;
- LL_WARNS("debugMaterials") << mMethod << " Error[" << pStatus << "] cannot access cap '" << MATERIALS_CAPABILITY_NAME
+ LL_WARNS("Materials") << "--------------------------------------------------------------------------" << LL_ENDL;
+ LL_WARNS("Materials") << mMethod << " Error[" << pStatus << "] cannot access cap '" << MATERIALS_CAPABILITY_NAME
<< "' with url '" << mCapabilityURL << "' because " << pReason << LL_ENDL;
- LL_WARNS("debugMaterials") << "--------------------------------------------------------------------------" << LL_ENDL;
+ LL_WARNS("Materials") << "--------------------------------------------------------------------------" << LL_ENDL;
LLSD emptyResult;
mCallback(false, emptyResult);
@@ -128,23 +128,31 @@ bool LLMaterialMgr::isGetPending(const LLUUID& region_id, const LLMaterialID& ma
const LLMaterialPtr LLMaterialMgr::get(const LLUUID& region_id, const LLMaterialID& material_id)
{
+ LL_DEBUGS("Materials") << "region " << region_id << " material id " << material_id << LL_ENDL;
+ LLMaterialPtr material;
material_map_t::const_iterator itMaterial = mMaterials.find(material_id);
if (mMaterials.end() != itMaterial)
{
- return itMaterial->second;
+ material = itMaterial->second;
+ LL_DEBUGS("Materials") << " found material " << LL_ENDL;
}
-
- if (!isGetPending(region_id, material_id))
+ else
{
- get_queue_t::iterator itQueue = mGetQueue.find(region_id);
- if (mGetQueue.end() == itQueue)
+ if (!isGetPending(region_id, material_id))
{
- std::pair<get_queue_t::iterator, bool> ret = mGetQueue.insert(std::pair<LLUUID, material_queue_t>(region_id, material_queue_t()));
- itQueue = ret.first;
+ LL_DEBUGS("Materials") << " material pending " << material_id << LL_ENDL;
+ get_queue_t::iterator itQueue = mGetQueue.find(region_id);
+ if (mGetQueue.end() == itQueue)
+ {
+ std::pair<get_queue_t::iterator, bool> ret = mGetQueue.insert(std::pair<LLUUID, material_queue_t>(region_id, material_queue_t()));
+ itQueue = ret.first;
+ }
+ itQueue->second.insert(material_id);
}
- itQueue->second.insert(material_id);
+ LL_DEBUGS("Materials") << " returning empty material " << LL_ENDL;
+ material = LLMaterialPtr();
}
- return LLMaterialPtr();
+ return material;
}
boost::signals2::connection LLMaterialMgr::get(const LLUUID& region_id, const LLMaterialID& material_id, LLMaterialMgr::get_callback_t::slot_type cb)
@@ -188,8 +196,13 @@ void LLMaterialMgr::getAll(const LLUUID& region_id)
{
if (!isGetAllPending(region_id))
{
+ LL_DEBUGS("Materials") << "queuing for region " << region_id << LL_ENDL;
mGetAllQueue.insert(region_id);
}
+ else
+ {
+ LL_DEBUGS("Materials") << "already pending for region " << region_id << LL_ENDL;
+ }
}
boost::signals2::connection LLMaterialMgr::getAll(const LLUUID& region_id, LLMaterialMgr::getall_callback_t::slot_type cb)
@@ -210,6 +223,7 @@ boost::signals2::connection LLMaterialMgr::getAll(const LLUUID& region_id, LLMat
void LLMaterialMgr::put(const LLUUID& object_id, const U8 te, const LLMaterial& material)
{
+ LL_DEBUGS("Materials") << "object " << object_id << LL_ENDL;
put_queue_t::iterator itQueue = mPutQueue.find(object_id);
if (mPutQueue.end() == itQueue)
{
@@ -230,9 +244,11 @@ void LLMaterialMgr::put(const LLUUID& object_id, const U8 te, const LLMaterial&
const LLMaterialPtr LLMaterialMgr::setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data)
{
+ LL_DEBUGS("Materials") << "region " << region_id << " material id " << material_id << LL_ENDL;
material_map_t::const_iterator itMaterial = mMaterials.find(material_id);
if (mMaterials.end() == itMaterial)
{
+ LL_DEBUGS("Materials") << "new material" << LL_ENDL;
LLMaterialPtr newMaterial(new LLMaterial(material_data));
std::pair<material_map_t::const_iterator, bool> ret = mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(material_id, newMaterial));
itMaterial = ret.first;
@@ -257,6 +273,7 @@ void LLMaterialMgr::onGetResponse(bool success, const LLSD& content, const LLUUI
if (!success)
{
// *TODO: is there any kind of error handling we can do here?
+ LL_WARNS("Materials")<< "failed"<<LL_ENDL;
return;
}
@@ -271,11 +288,12 @@ void LLMaterialMgr::onGetResponse(bool success, const LLSD& content, const LLUUI
LLSD response_data;
if (!unzip_llsd(response_data, content_stream, content_binary.size()))
{
- LL_ERRS("debugMaterials") << "Cannot unzip LLSD binary content" << LL_ENDL;
+ LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL;
return;
}
llassert(response_data.isArray());
+ LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL;
for (LLSD::array_const_iterator itMaterial = response_data.beginArray(); itMaterial != response_data.endArray(); ++itMaterial)
{
const LLSD& material_data = *itMaterial;
@@ -297,6 +315,7 @@ void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LL
if (!success)
{
// *TODO: is there any kind of error handling we can do here?
+ LL_WARNS("Materials")<< "failed"<<LL_ENDL;
return;
}
@@ -311,7 +330,7 @@ void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LL
LLSD response_data;
if (!unzip_llsd(response_data, content_stream, content_binary.size()))
{
- LL_ERRS("debugMaterials") << "Cannot unzip LLSD binary content" << LL_ENDL;
+ LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL;
return;
}
@@ -319,6 +338,7 @@ void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LL
material_map_t materials;
llassert(response_data.isArray());
+ LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL;
for (LLSD::array_const_iterator itMaterial = response_data.beginArray(); itMaterial != response_data.endArray(); ++itMaterial)
{
const LLSD& material_data = *itMaterial;
@@ -361,6 +381,7 @@ void LLMaterialMgr::onPutResponse(bool success, const LLSD& content)
if (!success)
{
// *TODO: is there any kind of error handling we can do here?
+ LL_WARNS("Materials")<< "failed"<<LL_ENDL;
return;
}
@@ -375,13 +396,13 @@ void LLMaterialMgr::onPutResponse(bool success, const LLSD& content)
LLSD response_data;
if (!unzip_llsd(response_data, content_stream, content_binary.size()))
{
- LL_ERRS("debugMaterials") << "Cannot unzip LLSD binary content" << LL_ENDL;
+ LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL;
return;
}
else
{
llassert(response_data.isArray());
-
+ LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL;
for (LLSD::array_const_iterator faceIter = response_data.beginArray(); faceIter != response_data.endArray(); ++faceIter)
{
# ifndef LL_RELEASE_FOR_DOWNLOAD
@@ -446,7 +467,7 @@ void LLMaterialMgr::processGetQueue()
const LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
if (!regionp)
{
- LL_WARNS("debugMaterials") << "Unknown region with id " << region_id.asString() << LL_ENDL;
+ LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL;
mGetQueue.erase(itRegionQueue);
continue;
}
@@ -463,7 +484,7 @@ void LLMaterialMgr::processGetQueue()
const std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
if (capURL.empty())
{
- LL_WARNS("debugMaterials") << "Capability '" << MATERIALS_CAPABILITY_NAME
+ LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
<< "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL;
mGetQueue.erase(itRegionQueue);
continue;
@@ -491,7 +512,7 @@ void LLMaterialMgr::processGetQueue()
S32 materialSize = materialString.size();
if (materialSize <= 0)
{
- LL_ERRS("debugMaterials") << "cannot zip LLSD binary content" << LL_ENDL;
+ LL_ERRS("Materials") << "cannot zip LLSD binary content" << LL_ENDL;
return;
}
@@ -518,7 +539,7 @@ void LLMaterialMgr::processGetAllQueue()
LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
if (regionp == NULL)
{
- LL_WARNS("debugMaterials") << "Unknown region with id " << region_id.asString() << LL_ENDL;
+ LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL;
mGetAllQueue.erase(itRegion);
continue;
}
@@ -530,12 +551,13 @@ void LLMaterialMgr::processGetAllQueue()
std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
if (capURL.empty())
{
- LL_WARNS("debugMaterials") << "Capability '" << MATERIALS_CAPABILITY_NAME
+ LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
<< "' is not defined on the current region '" << regionp->getName() << "'" << LL_ENDL;
mGetAllQueue.erase(itRegion);
continue;
}
+ LL_DEBUGS("Materials") << "getAll for region " << region_id << LL_ENDL;
LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("GET", capURL, boost::bind(&LLMaterialMgr::onGetAllResponse, this, _1, _2, *itRegion));
LLHTTPClient::get(capURL, materialsResponder);
mGetAllPending.insert(std::pair<LLUUID, F64>(region_id, LLFrameTimer::getTotalSeconds()));
@@ -554,7 +576,7 @@ void LLMaterialMgr::processPutQueue()
const LLViewerObject* objectp = gObjectList.findObject(object_id);
if ( (!objectp) || (!objectp->getRegion()) )
{
- LL_WARNS("debugMaterials") << "Object or object region is NULL" << LL_ENDL;
+ LL_WARNS("Materials") << "Object or object region is NULL" << LL_ENDL;
mPutQueue.erase(itQueue);
continue;
@@ -569,7 +591,7 @@ void LLMaterialMgr::processPutQueue()
std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
if (capURL.empty())
{
- LL_WARNS("debugMaterials") << "Capability '" << MATERIALS_CAPABILITY_NAME
+ LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
<< "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL;
mPutQueue.erase(itQueue);
@@ -595,6 +617,7 @@ void LLMaterialMgr::processPutQueue()
std::string materialString = zip_llsd(materialsData);
S32 materialSize = materialString.size();
+
if (materialSize > 0)
{
LLSD::Binary materialBinary;
@@ -604,6 +627,7 @@ void LLMaterialMgr::processPutQueue()
LLSD putData = LLSD::emptyMap();
putData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;
+ LL_DEBUGS("Materials") << "put for " << facesData.size() << " faces; object " << object_id << LL_ENDL;
LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("PUT", capURL, boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2));
LLHTTPClient::put(capURL, putData, materialsResponder);
}
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index feceee5709..face1608a0 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1101,6 +1101,7 @@ void render_hud_attachments()
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_BUMP);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_MATERIALS);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY);
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index b8de345a9a..4c6d655058 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -4351,10 +4351,17 @@ S32 LLViewerObject::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID
const LLTextureEntry *tep = getTE(te);
if (!tep)
{
- llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
+ LL_WARNS("Material") << "No texture entry for te " << (S32)te
+ << ", object " << mID
+ << ", material " << pMaterialID
+ << LL_ENDL;
}
else if (pMaterialID != tep->getMaterialID())
{
+ LL_DEBUGS("Material") << "Changing texture entry for te " << (S32)te
+ << ", object " << mID
+ << ", material " << pMaterialID
+ << LL_ENDL;
retval = LLPrimitive::setTEMaterialID(te, pMaterialID);
setChanged(TEXTURE);
if (mDrawable.notNull() && retval)
@@ -4376,6 +4383,10 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri
else if (pMaterialParams != tep->getMaterialParams())
{
retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams);
+ LL_DEBUGS("Material") << "Changing material params for te " << (S32)te
+ << ", object " << mID
+ << " (" << retval << ")"
+ << LL_ENDL;
setTENormalMap(te, tep->getMaterialParams()->getNormalID());
setTESpecularMap(te, tep->getMaterialParams()->getSpecularID());
setChanged(TEXTURE);
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 43de7450c8..20e0448c1b 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -207,6 +207,17 @@ LLGLSLShader gDeferredWLCloudProgram;
LLGLSLShader gDeferredStarProgram;
LLGLSLShader gNormalMapGenProgram;
+// Deferred materials shaders
+LLGLSLShader gDeferredMaterialShiny;
+LLGLSLShader gDeferredMaterialNormal;
+LLGLSLShader gDeferredMaterialShinyNormal;
+LLGLSLShader gDeferredMaterialShinyAlphaTest;
+LLGLSLShader gDeferredMaterialNormalAlphaTest;
+LLGLSLShader gDeferredMaterialShinyNormalAlphaTest;
+LLGLSLShader gDeferredMaterialShinyEmissive;
+LLGLSLShader gDeferredMaterialNormalEmissive;
+LLGLSLShader gDeferredMaterialShinyNormalEmissive;
+
LLViewerShaderMgr::LLViewerShaderMgr() :
mVertexShaderLevel(SHADER_COUNT, 0),
mMaxAvatarShaderLevel(0)
@@ -1105,6 +1116,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWLCloudProgram.unload();
gDeferredStarProgram.unload();
gNormalMapGenProgram.unload();
+ gDeferredMaterialShiny.unload();
+ gDeferredMaterialNormal.unload();
+ gDeferredMaterialShinyAlphaTest.unload();
+ gDeferredMaterialNormalAlphaTest.unload();
+ gDeferredMaterialShinyEmissive.unload();
+ gDeferredMaterialNormalEmissive.unload();
return TRUE;
}
@@ -1218,6 +1235,114 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredBumpProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredBumpProgram.createShader(NULL, NULL);
}
+
+ if (success)
+ {
+ gDeferredMaterialShiny.mName = "Deferred Shiny Material Shader";
+ gDeferredMaterialShiny.mShaderFiles.clear();
+ gDeferredMaterialShiny.mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredMaterialShiny.mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMaterialShiny.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredMaterialShiny.addPermutation("SHINY_MATERIAL", "1");
+ success = gDeferredMaterialShiny.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredMaterialNormal.mName = "Deferred Normal Mapped Material Shader";
+ gDeferredMaterialNormal.mShaderFiles.clear();
+ gDeferredMaterialNormal.mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredMaterialNormal.mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMaterialNormal.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredMaterialNormal.addPermutation("NORMAL_MATERIAL", "1");
+ success = gDeferredMaterialNormal.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredMaterialShinyNormal.mName = "Deferred Normal Mapped Shiny Material Shader";
+ gDeferredMaterialShinyNormal.mShaderFiles.clear();
+ gDeferredMaterialShinyNormal.mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredMaterialShinyNormal.mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMaterialShinyNormal.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredMaterialShinyNormal.addPermutation("NORMAL_MATERIAL", "1");
+ gDeferredMaterialShinyNormal.addPermutation("SHINY_MATERIAL", "1");
+ success = gDeferredMaterialShinyNormal.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredMaterialShinyAlphaTest.mName = "Deferred Alpha Tested Shiny Material Shader";
+ gDeferredMaterialShinyAlphaTest.mShaderFiles.clear();
+ gDeferredMaterialShinyAlphaTest.mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredMaterialShinyAlphaTest.mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMaterialShinyAlphaTest.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredMaterialShinyAlphaTest.addPermutation("SHINY_MATERIAL", "1");
+ gDeferredMaterialShinyAlphaTest.addPermutation("ALPHA_TEST", "1");
+ success = gDeferredMaterialShinyAlphaTest.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredMaterialNormalAlphaTest.mName = "Deferred Alpha Tested Normal Mapped Material Shader";
+ gDeferredMaterialNormalAlphaTest.mShaderFiles.clear();
+ gDeferredMaterialNormalAlphaTest.mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredMaterialNormalAlphaTest.mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMaterialNormalAlphaTest.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredMaterialNormalAlphaTest.addPermutation("NORMAL_MATERIAL", "1");
+ gDeferredMaterialNormalAlphaTest.addPermutation("ALPHA_TEST", "1");
+ success = gDeferredMaterialNormalAlphaTest.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredMaterialNormalAlphaTest.mName = "Deferred Alpha Tested Shiny Normal Mapped Material Shader";
+ gDeferredMaterialShinyNormalAlphaTest.mShaderFiles.clear();
+ gDeferredMaterialShinyNormalAlphaTest.mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredMaterialShinyNormalAlphaTest.mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMaterialShinyNormalAlphaTest.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredMaterialShinyNormalAlphaTest.addPermutation("NORMAL_MATERIAL", "1");
+ gDeferredMaterialShinyNormalAlphaTest.addPermutation("SHINY_MATERIAL", "1");
+ gDeferredMaterialShinyNormalAlphaTest.addPermutation("ALPHA_TEST", "1");
+ success = gDeferredMaterialShinyNormalAlphaTest.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredMaterialShinyEmissive.mName = "Deferred Emissive Mask Shiny Material Shader";
+ gDeferredMaterialShinyEmissive.mShaderFiles.clear();
+ gDeferredMaterialShinyEmissive.mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredMaterialShinyEmissive.mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMaterialShinyEmissive.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredMaterialShinyEmissive.addPermutation("SHINY_MATERIAL", "1");
+ gDeferredMaterialShinyEmissive.addPermutation("EMISSIVE_MASK", "1");
+ success = gDeferredMaterialShinyEmissive.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredMaterialNormalEmissive.mName = "Deferred Emissive Mask Normal Mapped Material Shader";
+ gDeferredMaterialNormalEmissive.mShaderFiles.clear();
+ gDeferredMaterialNormalEmissive.mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredMaterialNormalEmissive.mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMaterialNormalEmissive.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredMaterialNormalEmissive.addPermutation("NORMAL_MATERIAL", "1");
+ gDeferredMaterialNormalEmissive.addPermutation("EMISSIVE_MASK", "1");
+ success = gDeferredMaterialNormalEmissive.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredMaterialShinyNormalEmissive.mName = "Deferred Emissive Mask Normal Mapped Material Shader";
+ gDeferredMaterialShinyNormalEmissive.mShaderFiles.clear();
+ gDeferredMaterialShinyNormalEmissive.mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredMaterialShinyNormalEmissive.mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMaterialShinyNormalEmissive.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredMaterialShinyNormalEmissive.addPermutation("NORMAL_MATERIAL", "1");
+ gDeferredMaterialShinyNormalEmissive.addPermutation("SHINY_MATERIAL", "1");
+ gDeferredMaterialShinyNormalEmissive.addPermutation("EMISSIVE_MASK", "1");
+ success = gDeferredMaterialShinyNormalEmissive.createShader(NULL, NULL);
+ }
if (success)
{
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index d6dd645e8c..15bff6882e 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -362,4 +362,15 @@ extern LLGLSLShader gDeferredWLCloudProgram;
extern LLGLSLShader gDeferredStarProgram;
extern LLGLSLShader gNormalMapGenProgram;
+// Deferred materials shaders
+extern LLGLSLShader gDeferredMaterialShiny;
+extern LLGLSLShader gDeferredMaterialNormal;
+extern LLGLSLShader gDeferredMaterialShinyNormal;
+extern LLGLSLShader gDeferredMaterialShinyAlphaTest;
+extern LLGLSLShader gDeferredMaterialNormalAlphaTest;
+extern LLGLSLShader gDeferredMaterialShinyNormalAlphaTest;
+extern LLGLSLShader gDeferredMaterialShinyEmissive;
+extern LLGLSLShader gDeferredMaterialNormalEmissive;
+extern LLGLSLShader gDeferredMaterialShinyNormalEmissive;
+
#endif
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 6c073a8e20..9ed940e61a 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -1995,7 +1995,6 @@ void LLVOVolume::setTEMaterialParamsCallback(const LLMaterialID &pMaterialID, co
{
if (getTE(i)->getMaterialID() == pMaterialID)
{
- LL_INFOS("Materials") << "Material params callback triggered!" << LL_ENDL;
setTEMaterialParams(i, pMaterialParams);
}
}
@@ -2005,13 +2004,11 @@ S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
{
if (!pMaterialID.isNull())
{
- LL_INFOS("Materials") << "Oh god it's a material! " << pMaterialID.asString() << LL_ENDL;
+ LL_INFOS("Materials") << " " << pMaterialID.asString() << LL_ENDL;
S32 res = LLViewerObject::setTEMaterialID(te, pMaterialID);
if (res)
{
- LL_INFOS("Materials") << "We have a material!" << LL_ENDL;
LLMaterialMgr::instance().get(getRegion()->getRegionID(), pMaterialID, boost::bind(&LLVOVolume::setTEMaterialParamsCallback, this, _1, _2));
- //setTEMaterialParams(te, pMatParam);
gPipeline.markTextured(mDrawable);
mFaceMappingChanged = TRUE;
}
@@ -5215,10 +5212,14 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
registerFace(group, facep, LLRenderPass::PASS_POST_BUMP);
}
}
- else if (te->getBumpmap() || te->getMaterialParams() != NULL)
+ else if (te->getBumpmap() && !te->getMaterialParams())
{ //register in deferred bump pass
registerFace(group, facep, LLRenderPass::PASS_BUMP);
}
+ else if (te->getMaterialParams())
+ {
+ registerFace(group, facep, LLRenderPass::PASS_MATERIALS);
+ }
else
{ //register in deferred simple pass (deferred simple includes shiny)
llassert(mask & LLVertexBuffer::MAP_NORMAL);
@@ -5250,10 +5251,14 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
}
else
{
- if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && (te->getBumpmap() || te->getMaterialParams()))
+ if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && (te->getBumpmap() && !te->getMaterialParams()))
{ //non-shiny or fullbright deferred bump
registerFace(group, facep, LLRenderPass::PASS_BUMP);
}
+ else if (te->getMaterialParams())
+ {
+ registerFace(group, facep, LLRenderPass::PASS_MATERIALS);
+ }
else
{ //all around simple
llassert(mask & LLVertexBuffer::MAP_NORMAL);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index ea7de6f399..8ee4cd7713 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -233,6 +233,7 @@ LLFastTimer::DeclareTimer FTM_RENDER_WL_SKY("Windlight Sky");
LLFastTimer::DeclareTimer FTM_RENDER_ALPHA("Alpha Objects");
LLFastTimer::DeclareTimer FTM_RENDER_CHARACTERS("Avatars");
LLFastTimer::DeclareTimer FTM_RENDER_BUMP("Bump");
+LLFastTimer::DeclareTimer FTM_RENDER_MATERIALS("Materials");
LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT("Fullbright");
LLFastTimer::DeclareTimer FTM_RENDER_GLOW("Glow");
LLFastTimer::DeclareTimer FTM_GEO_UPDATE("Geo Update");
@@ -262,6 +263,7 @@ std::string gPoolNames[] =
"POOL_GROUND",
"POOL_FULLBRIGHT",
"POOL_BUMP",
+ "POOL_MATERIALS",
"POOL_TERRAIN,"
"POOL_SKY",
"POOL_WL_SKY",
@@ -490,6 +492,7 @@ void LLPipeline::init()
getPool(LLDrawPool::POOL_FULLBRIGHT);
getPool(LLDrawPool::POOL_INVISIBLE);
getPool(LLDrawPool::POOL_BUMP);
+ getPool(LLDrawPool::POOL_MATERIALS);
getPool(LLDrawPool::POOL_GLOW);
LLViewerStats::getInstance()->mTrianglesDrawnStat.reset();
@@ -1520,7 +1523,9 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
case LLDrawPool::POOL_BUMP:
poolp = mBumpPool;
break;
-
+ case LLDrawPool::POOL_MATERIALS:
+ poolp = mMaterialsPool;
+ break;
case LLDrawPool::POOL_ALPHA:
poolp = mAlphaPool;
break;
@@ -1598,9 +1603,12 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
{
return LLDrawPool::POOL_ALPHA;
}
- else if ((te->getBumpmap() || te->getShiny()))
+ else if ((te->getBumpmap() || te->getShiny()) && te->getMaterialID().isNull())
{
return LLDrawPool::POOL_BUMP;
+ } else if (!te->getMaterialID().isNull() && !alpha)
+ {
+ return LLDrawPool::POOL_MATERIALS;
}
else
{
@@ -5421,7 +5429,17 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
mBumpPool = new_poolp;
}
break;
-
+ case LLDrawPool::POOL_MATERIALS:
+ if (mMaterialsPool)
+ {
+ llassert(0);
+ llwarns << "Ignorning duplicate materials pool." << llendl;
+ }
+ else
+ {
+ mMaterialsPool = new_poolp;
+ }
+ break;
case LLDrawPool::POOL_ALPHA:
if( mAlphaPool )
{
@@ -5562,7 +5580,12 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
llassert( poolp == mBumpPool );
mBumpPool = NULL;
break;
-
+
+ case LLDrawPool::POOL_MATERIALS:
+ llassert(poolp == mMaterialsPool);
+ mMaterialsPool = NULL;
+ break;
+
case LLDrawPool::POOL_ALPHA:
llassert( poolp == mAlphaPool );
mAlphaPool = NULL;
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index e264081910..22a0ca6a2f 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -95,6 +95,7 @@ extern LLFastTimer::DeclareTimer FTM_RENDER_WL_SKY;
extern LLFastTimer::DeclareTimer FTM_RENDER_ALPHA;
extern LLFastTimer::DeclareTimer FTM_RENDER_CHARACTERS;
extern LLFastTimer::DeclareTimer FTM_RENDER_BUMP;
+extern LLFastTimer::DeclareTimer FTM_RENDER_MATERIALS;
extern LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT;
extern LLFastTimer::DeclareTimer FTM_RENDER_GLOW;
extern LLFastTimer::DeclareTimer FTM_STATESORT;
@@ -419,6 +420,7 @@ public:
RENDER_TYPE_GRASS = LLDrawPool::POOL_GRASS,
RENDER_TYPE_FULLBRIGHT = LLDrawPool::POOL_FULLBRIGHT,
RENDER_TYPE_BUMP = LLDrawPool::POOL_BUMP,
+ RENDER_TYPE_MATERIALS = LLDrawPool::POOL_MATERIALS,
RENDER_TYPE_AVATAR = LLDrawPool::POOL_AVATAR,
RENDER_TYPE_TREE = LLDrawPool::POOL_TREE,
RENDER_TYPE_INVISIBLE = LLDrawPool::POOL_INVISIBLE,
@@ -435,6 +437,7 @@ public:
RENDER_TYPE_PASS_SHINY = LLRenderPass::PASS_SHINY,
RENDER_TYPE_PASS_BUMP = LLRenderPass::PASS_BUMP,
RENDER_TYPE_PASS_POST_BUMP = LLRenderPass::PASS_POST_BUMP,
+ RENDER_TYPE_PASS_MATERIALS = LLRenderPass::PASS_MATERIALS,
RENDER_TYPE_PASS_GLOW = LLRenderPass::PASS_GLOW,
RENDER_TYPE_PASS_ALPHA = LLRenderPass::PASS_ALPHA,
RENDER_TYPE_PASS_ALPHA_MASK = LLRenderPass::PASS_ALPHA_MASK,
@@ -776,6 +779,7 @@ protected:
LLDrawPool* mInvisiblePool;
LLDrawPool* mGlowPool;
LLDrawPool* mBumpPool;
+ LLDrawPool* mMaterialsPool;
LLDrawPool* mWLSkyPool;
// Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar