diff options
Diffstat (limited to 'indra')
23 files changed, 732 insertions, 86 deletions
diff --git a/indra/llprimitive/llmaterialid.cpp b/indra/llprimitive/llmaterialid.cpp index 590f5cd91f..820f62c43c 100644 --- a/indra/llprimitive/llmaterialid.cpp +++ b/indra/llprimitive/llmaterialid.cpp @@ -150,6 +150,13 @@ std::string LLMaterialID::asString() const return materialIDString; } +std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id) +{ + s << material_id.asString(); + return s; +} + + void LLMaterialID::parseFromBinary (const LLSD::Binary& pMaterialID) { llassert(pMaterialID.size() == (MATERIAL_ID_SIZE * sizeof(U8))); diff --git a/indra/llprimitive/llmaterialid.h b/indra/llprimitive/llmaterialid.h index 9db4065302..0a95204085 100644 --- a/indra/llprimitive/llmaterialid.h +++ b/indra/llprimitive/llmaterialid.h @@ -60,6 +60,8 @@ public: LLSD asLLSD() const; std::string asString() const; + friend std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id); + static const LLMaterialID null; private: diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 39e81c4bfc..78fd4e98d7 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -386,7 +386,7 @@ void LLGLSLShader::removePermutation(std::string name) GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type) { - if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB || + if ((type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) || type == GL_SAMPLER_2D_MULTISAMPLE) { //this here is a texture glUniform1iARB(location, mActiveTextureChannels); diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 9b2874c79d..d4ddc6396b 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -650,13 +650,6 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade text[count++] = strdup("#define shadow2DRect(a,b) vec2(texture(a,b))\n"); } } - - //copy preprocessor definitions into buffer - for (std::map<std::string,std::string>::iterator iter = mDefinitions.begin(); iter != mDefinitions.end(); ++iter) - { - std::string define = "#define " + iter->first + " " + iter->second + "\n"; - text[count++] = (GLcharARB *) strdup(define.c_str()); - } for (boost::unordered_map<std::string,std::string>::iterator iter = defines.begin(); iter != defines.end(); ++iter) { 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 |