diff options
Diffstat (limited to 'indra')
37 files changed, 10807 insertions, 10931 deletions
diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index 13c08694f0..e6cc06e8d0 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -70,33 +70,32 @@ LLAssetDictionary::LLAssetDictionary() { // DESCRIPTION TYPE NAME HUMAN NAME CAN LINK? CAN FETCH? CAN KNOW? // |--------------------|-----------|-------------------|-----------|-----------|---------| - addEntry(LLAssetType::AT_TEXTURE, new AssetEntry("TEXTURE", "texture", "texture", true, false, true)); - addEntry(LLAssetType::AT_SOUND, new AssetEntry("SOUND", "sound", "sound", true, true, true)); - addEntry(LLAssetType::AT_CALLINGCARD, new AssetEntry("CALLINGCARD", "callcard", "calling card", true, false, false)); - addEntry(LLAssetType::AT_LANDMARK, new AssetEntry("LANDMARK", "landmark", "landmark", true, true, true)); - addEntry(LLAssetType::AT_SCRIPT, new AssetEntry("SCRIPT", "script", "legacy script", true, false, false)); - addEntry(LLAssetType::AT_CLOTHING, new AssetEntry("CLOTHING", "clothing", "clothing", true, true, true)); - addEntry(LLAssetType::AT_OBJECT, new AssetEntry("OBJECT", "object", "object", true, false, false)); - addEntry(LLAssetType::AT_NOTECARD, new AssetEntry("NOTECARD", "notecard", "note card", true, false, true)); - addEntry(LLAssetType::AT_CATEGORY, new AssetEntry("CATEGORY", "category", "folder", true, false, false)); - addEntry(LLAssetType::AT_LSL_TEXT, new AssetEntry("LSL_TEXT", "lsltext", "lsl2 script", true, false, false)); - addEntry(LLAssetType::AT_LSL_BYTECODE, new AssetEntry("LSL_BYTECODE", "lslbyte", "lsl bytecode", true, false, false)); - addEntry(LLAssetType::AT_TEXTURE_TGA, new AssetEntry("TEXTURE_TGA", "txtr_tga", "tga texture", true, false, false)); - addEntry(LLAssetType::AT_BODYPART, new AssetEntry("BODYPART", "bodypart", "body part", true, true, true)); - addEntry(LLAssetType::AT_SOUND_WAV, new AssetEntry("SOUND_WAV", "snd_wav", "sound", true, false, false)); - addEntry(LLAssetType::AT_IMAGE_TGA, new AssetEntry("IMAGE_TGA", "img_tga", "targa image", true, false, false)); - addEntry(LLAssetType::AT_IMAGE_JPEG, new AssetEntry("IMAGE_JPEG", "jpeg", "jpeg image", true, false, false)); - addEntry(LLAssetType::AT_ANIMATION, new AssetEntry("ANIMATION", "animatn", "animation", true, true, true)); - addEntry(LLAssetType::AT_GESTURE, new AssetEntry("GESTURE", "gesture", "gesture", true, true, true)); - addEntry(LLAssetType::AT_SIMSTATE, new AssetEntry("SIMSTATE", "simstate", "simstate", false, false, false)); - - addEntry(LLAssetType::AT_LINK, new AssetEntry("LINK", "link", "sym link", false, false, true)); - addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "sym folder link", false, false, true)); - addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false)); - addEntry(LLAssetType::AT_WIDGET, new AssetEntry("WIDGET", "widget", "widget", false, false, false)); - addEntry(LLAssetType::AT_PERSON, new AssetEntry("PERSON", "person", "person", false, false, false)); - addEntry(LLAssetType::AT_SETTINGS, new AssetEntry("SETTINGS", "settings", "settings blob", true, true, true)); - + addEntry(LLAssetType::AT_TEXTURE, new AssetEntry("TEXTURE", "texture", "texture", true, false, true)); + addEntry(LLAssetType::AT_SOUND, new AssetEntry("SOUND", "sound", "sound", true, true, true)); + addEntry(LLAssetType::AT_CALLINGCARD, new AssetEntry("CALLINGCARD", "callcard", "calling card", true, false, false)); + addEntry(LLAssetType::AT_LANDMARK, new AssetEntry("LANDMARK", "landmark", "landmark", true, true, true)); + addEntry(LLAssetType::AT_SCRIPT, new AssetEntry("SCRIPT", "script", "legacy script", true, false, false)); + addEntry(LLAssetType::AT_CLOTHING, new AssetEntry("CLOTHING", "clothing", "clothing", true, true, true)); + addEntry(LLAssetType::AT_OBJECT, new AssetEntry("OBJECT", "object", "object", true, false, false)); + addEntry(LLAssetType::AT_NOTECARD, new AssetEntry("NOTECARD", "notecard", "note card", true, false, true)); + addEntry(LLAssetType::AT_CATEGORY, new AssetEntry("CATEGORY", "category", "folder", true, false, false)); + addEntry(LLAssetType::AT_LSL_TEXT, new AssetEntry("LSL_TEXT", "lsltext", "lsl2 script", true, false, false)); + addEntry(LLAssetType::AT_LSL_BYTECODE, new AssetEntry("LSL_BYTECODE", "lslbyte", "lsl bytecode", true, false, false)); + addEntry(LLAssetType::AT_TEXTURE_TGA, new AssetEntry("TEXTURE_TGA", "txtr_tga", "tga texture", true, false, false)); + addEntry(LLAssetType::AT_BODYPART, new AssetEntry("BODYPART", "bodypart", "body part", true, true, true)); + addEntry(LLAssetType::AT_SOUND_WAV, new AssetEntry("SOUND_WAV", "snd_wav", "sound", true, false, false)); + addEntry(LLAssetType::AT_IMAGE_TGA, new AssetEntry("IMAGE_TGA", "img_tga", "targa image", true, false, false)); + addEntry(LLAssetType::AT_IMAGE_JPEG, new AssetEntry("IMAGE_JPEG", "jpeg", "jpeg image", true, false, false)); + addEntry(LLAssetType::AT_ANIMATION, new AssetEntry("ANIMATION", "animatn", "animation", true, true, true)); + addEntry(LLAssetType::AT_GESTURE, new AssetEntry("GESTURE", "gesture", "gesture", true, true, true)); + addEntry(LLAssetType::AT_SIMSTATE, new AssetEntry("SIMSTATE", "simstate", "simstate", false, false, false)); + + addEntry(LLAssetType::AT_LINK, new AssetEntry("LINK", "link", "sym link", false, false, true)); + addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "sym folder link", false, false, true)); + addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false)); + addEntry(LLAssetType::AT_WIDGET, new AssetEntry("WIDGET", "widget", "widget", false, false, false)); + addEntry(LLAssetType::AT_PERSON, new AssetEntry("PERSON", "person", "person", false, false, false)); + addEntry(LLAssetType::AT_SETTINGS, new AssetEntry("SETTINGS", "settings", "settings blob", true, true, true)); addEntry(LLAssetType::AT_UNKNOWN, new AssetEntry("UNKNOWN", "invalid", NULL, false, false, false)); addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE)); diff --git a/indra/llcommon/lllivefile.cpp b/indra/llcommon/lllivefile.cpp index 4b73ff691a..ea485c2d86 100644 --- a/indra/llcommon/lllivefile.cpp +++ b/indra/llcommon/lllivefile.cpp @@ -150,7 +150,6 @@ bool LLLiveFile::checkAndReload() } else { - LL_WARNS() << "Failed to load live file " << filename() << LL_ENDL; changed = false; } } diff --git a/indra/llcorehttp/tests/test_refcounted.hpp b/indra/llcorehttp/tests/test_refcounted.hpp index 6a516f60c0..5dff143e5d 100644 --- a/indra/llcorehttp/tests/test_refcounted.hpp +++ b/indra/llcorehttp/tests/test_refcounted.hpp @@ -30,7 +30,7 @@ #include "test_allocator.h" -#if WANT_TESTS_WITH_RACES_THAT_HANG +#if 0 // disable all of this because it's hanging win64 builds? using namespace LLCoreInt; namespace tut @@ -153,6 +153,5 @@ namespace tut ensure(mMemTotal == (GetMemTotal() - sizeof(RefCounted))); } } -#endif - +#endif // if 0 #endif // TEST_LLCOREINT_REF_COUNTED_H_ diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index 744c5853e4..f1bea326c1 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -1281,19 +1281,18 @@ void LLSettingsSky::calculateLightSettings() const // and vary_sunlight will work properly with moon light F32 lighty = lightnorm[1]; - - lighty = llmax(0.f, lighty); - if(lighty > 0.f) + if(fabs(lighty) > 0.001f) { lighty = 1.f / lighty; } + lighty = llmax(0.001f, lighty); componentMultBy(sunlight, componentExp((light_atten * -1.f) * lighty)); //increase ambient when there are more clouds LLColor3 tmpAmbient = ambient + (smear(1.f) - ambient) * cloud_shadow * 0.5f; //brightness of surface both sunlight and ambient - mSunDiffuse = gammaCorrect(componentMult(sunlight, light_transmittance)); + mSunDiffuse = gammaCorrect(componentMult(sunlight, light_transmittance)); mSunAmbient = gammaCorrect(componentMult(tmpAmbient, light_transmittance) * 0.5); mMoonDiffuse = gammaCorrect(componentMult(LLColor3::white, light_transmittance) * 0.5f); diff --git a/indra/llmath/llquaternion.cpp b/indra/llmath/llquaternion.cpp index a8d9eba2a0..57a976b57a 100644 --- a/indra/llmath/llquaternion.cpp +++ b/indra/llmath/llquaternion.cpp @@ -103,6 +103,7 @@ LLQuaternion::LLQuaternion(const LLVector3 &x_axis, *this = mat.quaternion(); normalize(); } + LLQuaternion::LLQuaternion(const LLSD &sd) { setValue(sd); diff --git a/indra/llmath/llquaternion.h b/indra/llmath/llquaternion.h index e2cdad548b..51ce163b4e 100644 --- a/indra/llmath/llquaternion.h +++ b/indra/llmath/llquaternion.h @@ -191,7 +191,6 @@ inline void LLQuaternion::setValue(const LLSD& sd) mQ[3] = sd[3].asReal(); } - // checker inline BOOL LLQuaternion::isFinite() const { diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 0e1748b337..605032e0a8 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2204,7 +2204,6 @@ BOOL LLVolume::generate() { rot_mat.rotate(*profile++, tmp); dst->setAdd(tmp,offset); - ++dst; } } diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 0a81c1c6dd..589cf86745 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -107,8 +107,7 @@ if (BUILD_HEADLESS) ${LLXML_LIBRARIES} ${LLVFS_LIBRARIES} ${LLWINDOW_HEADLESS_LIBRARIES} - ${OPENGL_HEADLESS_LIBRARIES} - ) + ${OPENGL_HEADLESS_LIBRARIES}) endif (BUILD_HEADLESS) @@ -131,6 +130,5 @@ target_link_libraries(llrender ${LLVFS_LIBRARIES} ${LLWINDOW_LIBRARIES} ${FREETYPE_LIBRARIES} - ${OPENGL_LIBRARIES} - ) + ${OPENGL_LIBRARIES}) diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index b6300578e6..54a41c9d23 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -1353,8 +1353,8 @@ void LLGLManager::initExtensions() // nSight doesn't support use of ARB funcs that have been normalized in the API if (!LLRender::sNsightDebugSupport) { - glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB"); - glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB"); + glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB"); + glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB"); } else { diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 471d73febf..8f3a56e1cf 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -401,7 +401,7 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes, // work-around missing mix(vec3,vec3,bvec3) mDefines["OLD_SELECT"] = "1"; #endif - + //compile new source vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin(); for ( ; fileIter != mShaderFiles.end(); fileIter++ ) diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 830bad2aef..c1ce3d3aad 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -229,4 +229,5 @@ extern LLGLSLShader gSolidColorProgram; //Alpha mask shader (declared here so llappearance can access properly) extern LLGLSLShader gAlphaMaskProgram; + #endif diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp index e9a39d8acb..ad501687ed 100644 --- a/indra/llrender/llgltexture.cpp +++ b/indra/llrender/llgltexture.cpp @@ -30,20 +30,20 @@ // static S32 LLGLTexture::getTotalNumOfCategories() { - return MAX_GL_IMAGE_CATEGORY - (BOOST_HIGH - BOOST_SCULPTED) + 2; + return MAX_GL_IMAGE_CATEGORY - (BOOST_HIGH - BOOST_SCULPTED) + 2 ; } // static //index starts from zero. S32 LLGLTexture::getIndexFromCategory(S32 category) { - return (category < BOOST_HIGH) ? category : category - (BOOST_HIGH - BOOST_SCULPTED) + 1; + return (category < BOOST_HIGH) ? category : category - (BOOST_HIGH - BOOST_SCULPTED) + 1 ; } //static S32 LLGLTexture::getCategoryFromIndex(S32 index) { - return (index < BOOST_HIGH) ? index : index + (BOOST_HIGH - BOOST_SCULPTED) - 1; + return (index < BOOST_HIGH) ? index : index + (BOOST_HIGH - BOOST_SCULPTED) - 1 ; } LLGLTexture::LLGLTexture(BOOL usemipmaps) @@ -55,19 +55,19 @@ LLGLTexture::LLGLTexture(BOOL usemipmaps) LLGLTexture::LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) { init(); - mFullWidth = width; - mFullHeight = height; + mFullWidth = width ; + mFullHeight = height ; mUseMipMaps = usemipmaps; - mComponents = components; + mComponents = components ; setTexelsPerImage(); } LLGLTexture::LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps) { init(); - mUseMipMaps = usemipmaps; + mUseMipMaps = usemipmaps ; // Create an empty image of the specified size and width - mGLTexturep = new LLImageGL(raw, usemipmaps); + mGLTexturep = new LLImageGL(raw, usemipmaps) ; } LLGLTexture::~LLGLTexture() @@ -81,13 +81,13 @@ void LLGLTexture::init() mFullWidth = 0; mFullHeight = 0; - mTexelsPerImage = 0; - mUseMipMaps = FALSE; - mComponents = 0; + mTexelsPerImage = 0 ; + mUseMipMaps = FALSE ; + mComponents = 0 ; - mTextureState = NO_DELETE; + mTextureState = NO_DELETE ; mDontDiscard = FALSE; - mNeedsGLTexture = FALSE; + mNeedsGLTexture = FALSE ; } void LLGLTexture::cleanup() @@ -111,181 +111,181 @@ void LLGLTexture::setBoostLevel(S32 level) { if(mBoostLevel != level) { - mBoostLevel = level; + mBoostLevel = level ; if(mBoostLevel != LLGLTexture::BOOST_NONE && mBoostLevel != LLGLTexture::BOOST_ICON) { - setNoDelete(); + setNoDelete() ; } } } void LLGLTexture::forceActive() { - mTextureState = ACTIVE; + mTextureState = ACTIVE ; } void LLGLTexture::setActive() { if(mTextureState != NO_DELETE) { - mTextureState = ACTIVE; + mTextureState = ACTIVE ; } } //set the texture to stay in memory void LLGLTexture::setNoDelete() { - mTextureState = NO_DELETE; + mTextureState = NO_DELETE ; } void LLGLTexture::generateGLTexture() { if(mGLTexturep.isNull()) { - mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps); + mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ; } } LLImageGL* LLGLTexture::getGLTexture() const { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - return mGLTexturep; + return mGLTexturep ; } BOOL LLGLTexture::createGLTexture() { if(mGLTexturep.isNull()) { - generateGLTexture(); + generateGLTexture() ; } - return mGLTexturep->createGLTexture(); + return mGLTexturep->createGLTexture() ; } BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category) { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category); + BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category) ; if(ret) { - mFullWidth = mGLTexturep->getCurrentWidth(); - mFullHeight = mGLTexturep->getCurrentHeight(); - mComponents = mGLTexturep->getComponents(); + mFullWidth = mGLTexturep->getCurrentWidth() ; + mFullHeight = mGLTexturep->getCurrentHeight() ; + mComponents = mGLTexturep->getComponents() ; setTexelsPerImage(); } - return ret; + return ret ; } void LLGLTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes) { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes); + mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ; } void LLGLTexture::setAddressMode(LLTexUnit::eTextureAddressMode mode) { - llassert(mGLTexturep.notNull()); - mGLTexturep->setAddressMode(mode); + llassert(mGLTexturep.notNull()) ; + mGLTexturep->setAddressMode(mode) ; } void LLGLTexture::setFilteringOption(LLTexUnit::eTextureFilterOptions option) { - llassert(mGLTexturep.notNull()); - mGLTexturep->setFilteringOption(option); + llassert(mGLTexturep.notNull()) ; + mGLTexturep->setFilteringOption(option) ; } //virtual S32 LLGLTexture::getWidth(S32 discard_level) const { - llassert(mGLTexturep.notNull()); - return mGLTexturep->getWidth(discard_level); + llassert(mGLTexturep.notNull()) ; + return mGLTexturep->getWidth(discard_level) ; } //virtual S32 LLGLTexture::getHeight(S32 discard_level) const { - llassert(mGLTexturep.notNull()); - return mGLTexturep->getHeight(discard_level); + llassert(mGLTexturep.notNull()) ; + return mGLTexturep->getHeight(discard_level) ; } S32 LLGLTexture::getMaxDiscardLevel() const { - llassert(mGLTexturep.notNull()); - return mGLTexturep->getMaxDiscardLevel(); + llassert(mGLTexturep.notNull()) ; + return mGLTexturep->getMaxDiscardLevel() ; } S32 LLGLTexture::getDiscardLevel() const { - llassert(mGLTexturep.notNull()); - return mGLTexturep->getDiscardLevel(); + llassert(mGLTexturep.notNull()) ; + return mGLTexturep->getDiscardLevel() ; } S8 LLGLTexture::getComponents() const { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getComponents(); + return mGLTexturep->getComponents() ; } LLGLuint LLGLTexture::getTexName() const { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getTexName(); + return mGLTexturep->getTexName() ; } BOOL LLGLTexture::hasGLTexture() const { if(mGLTexturep.notNull()) { - return mGLTexturep->getHasGLTexture(); + return mGLTexturep->getHasGLTexture() ; } - return FALSE; + return FALSE ; } BOOL LLGLTexture::getBoundRecently() const { if(mGLTexturep.notNull()) { - return mGLTexturep->getBoundRecently(); + return mGLTexturep->getBoundRecently() ; } - return FALSE; + return FALSE ; } LLTexUnit::eTextureType LLGLTexture::getTarget(void) const { - llassert(mGLTexturep.notNull()); - return mGLTexturep->getTarget(); + llassert(mGLTexturep.notNull()) ; + return mGLTexturep->getTarget() ; } BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height) { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height); + return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ; } BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height) { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height); + return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ; } void LLGLTexture::setGLTextureCreated (bool initialized) { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - mGLTexturep->setGLTextureCreated (initialized); + mGLTexturep->setGLTextureCreated (initialized) ; } void LLGLTexture::setCategory(S32 category) { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - mGLTexturep->setCategory(category); + mGLTexturep->setCategory(category) ; } void LLGLTexture::setTexName(LLGLuint texName) @@ -302,107 +302,107 @@ void LLGLTexture::setTarget(const LLGLenum target, const LLTexUnit::eTextureType LLTexUnit::eTextureAddressMode LLGLTexture::getAddressMode(void) const { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getAddressMode(); + return mGLTexturep->getAddressMode() ; } S32Bytes LLGLTexture::getTextureMemory() const { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->mTextureMemory; + return mGLTexturep->mTextureMemory ; } LLGLenum LLGLTexture::getPrimaryFormat() const { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getPrimaryFormat(); + return mGLTexturep->getPrimaryFormat() ; } BOOL LLGLTexture::getIsAlphaMask() const { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getIsAlphaMask(); + return mGLTexturep->getIsAlphaMask() ; } BOOL LLGLTexture::getMask(const LLVector2 &tc) { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getMask(tc); + return mGLTexturep->getMask(tc) ; } F32 LLGLTexture::getTimePassedSinceLastBound() { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getTimePassedSinceLastBound(); + return mGLTexturep->getTimePassedSinceLastBound() ; } BOOL LLGLTexture::getMissed() const { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getMissed(); + return mGLTexturep->getMissed() ; } BOOL LLGLTexture::isJustBound() const { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->isJustBound(); + return mGLTexturep->isJustBound() ; } void LLGLTexture::forceUpdateBindStats(void) const { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->forceUpdateBindStats(); + return mGLTexturep->forceUpdateBindStats() ; } U32 LLGLTexture::getTexelsInAtlas() const { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getTexelsInAtlas(); + return mGLTexturep->getTexelsInAtlas() ; } U32 LLGLTexture::getTexelsInGLTexture() const { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getTexelsInGLTexture(); + return mGLTexturep->getTexelsInGLTexture() ; } BOOL LLGLTexture::isGLTextureCreated() const { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->isGLTextureCreated(); + return mGLTexturep->isGLTextureCreated() ; } S32 LLGLTexture::getDiscardLevelInAtlas() const { - llassert(mGLTexturep.notNull()); + llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getDiscardLevelInAtlas(); + return mGLTexturep->getDiscardLevelInAtlas() ; } void LLGLTexture::destroyGLTexture() { if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture()) { - mGLTexturep->destroyGLTexture(); - mTextureState = DELETED; + mGLTexturep->destroyGLTexture() ; + mTextureState = DELETED ; } } void LLGLTexture::setTexelsPerImage() { - U32 fullwidth = llmin(mFullWidth, (U32)MAX_IMAGE_SIZE_DEFAULT); - U32 fullheight = llmin(mFullHeight, (U32)MAX_IMAGE_SIZE_DEFAULT); + U32 fullwidth = llmin(mFullWidth,U32(MAX_IMAGE_SIZE_DEFAULT)); + U32 fullheight = llmin(mFullHeight,U32(MAX_IMAGE_SIZE_DEFAULT)); mTexelsPerImage = (U32)fullwidth * fullheight; } diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 25ec493fa2..7d8f512c93 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -352,6 +352,7 @@ BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, B } //---------------------------------------------------------------------------- + LLImageGL::LLImageGL(BOOL usemipmaps) : LLTrace::MemTrackable<LLImageGL>("LLImageGL"), mSaveData(0), mExternalTexture(FALSE) diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index e3bb9298cb..dc662bf898 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -1180,8 +1180,6 @@ void LLRender::syncLightState() shader->uniform4fv(LLShaderMgr::LIGHT_ATTENUATION, 8, attenuation[0].mV); shader->uniform3fv(LLShaderMgr::LIGHT_DIFFUSE, 8, diffuse[0].mV); shader->uniform4fv(LLShaderMgr::LIGHT_AMBIENT, 1, mAmbientLightColor.mV); - shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, 1, diffuse[0].mV); - shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, diffuseB[0].mV); } } diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index a5076ef609..fdbf5ec840 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -118,7 +118,7 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec float amb_da = ambiance; amb_da *= dist_atten; amb_da += (da*0.5) * ambiance; - amb_da += (da*da*0.5 + 0.5) * ambiance; + amb_da += (da*da*0.5 + 0.25) * ambiance; amb_da = min(amb_da, 1.0f - lit); col.rgb += amb_da * light_col * diffuse; @@ -198,7 +198,7 @@ void main() float ambient = abs(da); ambient *= 0.5; ambient *= ambient; - ambient = 1.0 - ambient * smoothstep(0.0, 0.3, shadow); + ambient = 1.0 - ambient; vec3 sun_contrib = min(da, shadow) * sunlit; @@ -228,7 +228,6 @@ void main() color.rgb += light.rgb; color.rgb = linear_to_srgb(color.rgb); - #endif #ifdef WATER_FOG diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index 5f4f1677d7..ae2dd24b19 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -112,7 +112,6 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe //angular attenuation da = dot(n, lv); da *= clamp(da, 0.0, 1.0); - da *= pow(da, 1.0 / 1.3); float lit = max(da * dist_atten, 0.0); @@ -294,16 +293,15 @@ void main() da = clamp(da, 0.0, 1.0); da = pow(da, 1.0 / 1.3); - col.rgb = amblit; - float ambient = abs(da); ambient *= 0.5; ambient *= ambient; - ambient = 1.0 - ambient * smoothstep(0.0, 0.3, shadow); + ambient = 1.0 - ambient; float final_da = min(da, shadow); vec3 sun_contrib = final_da * sunlit; + col.rgb = amblit; col.rgb *= ambient; col.rgb += sun_contrib; col.rgb *= diffuse.rgb; diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 484c0cae3e..27532ce458 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -123,7 +123,7 @@ void main() float ambient = abs(da); ambient *= 0.5; ambient *= ambient; - ambient = 1.0 - ambient * smoothstep(0.0, 0.3, scol); + ambient = 1.0 - ambient; vec3 sun_contrib = min(da,scol) * sunlit; diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl index 565c00ba79..14af657e67 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl @@ -96,7 +96,11 @@ void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit, //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) temp2.y = max(0.0, tmpLightnorm.y); - temp2.y = 1. / temp2.y; + if (temp2.y > 0.001f) + { + temp2.y = 1. / temp2.y; + } + temp2.y = max(0.001f, temp2.y); sunlight *= exp(-light_atten * temp2.y); // main atmospheric scattering line integral diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl index bef7a8827a..6c4098b9fb 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl @@ -91,7 +91,11 @@ void calcAtmospherics(vec3 inPositionEye) { //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) temp2.y = max(0.0, tmpLightnorm.y); - temp2.y = 1. / temp2.y; + if (temp2.y > 0.001f) + { + temp2.y = 1. / temp2.y; + } + temp2.y = max(0.001f, temp2.y); sunlight *= exp( - light_atten * temp2.y); // main atmospheric scattering line integral diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 7aaab2e3af..4c625eb684 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -67,6 +67,7 @@ static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS("Alp static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS("Alpha Def Tex Binds"); static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MESH_REBUILD("Alpha Mesh Rebuild"); static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_EMISSIVE("Alpha Emissive"); +static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_LIGHT_SETUP("Alpha Light Setup"); LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) : LLRenderPass(type), current_shader(NULL), target_shader(NULL), @@ -640,11 +641,13 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) } } +#if BATCH_FULLBRIGHTS if (params.mFullbright) { fullbrights.push_back(¶ms); continue; } +#endif LLRenderPass::applyModelMatrix(params); @@ -654,10 +657,31 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) { mat = params.mMaterial; } - + + if (params.mFullbright) + { + // Turn off lighting if it hasn't already been so. + if (light_enabled || !initialized_lighting) + { + LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_LIGHT_SETUP); + + initialized_lighting = TRUE; + if (use_shaders) + { + target_shader = fullbright_shader; + } + else + { + gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); + } + light_enabled = FALSE; + } + } // Turn on lighting if it isn't already. - if (!light_enabled || !initialized_lighting) + else if (!light_enabled || !initialized_lighting) { + LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_LIGHT_SETUP); + initialized_lighting = TRUE; if (use_shaders) { @@ -689,10 +713,14 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) current_shader = target_shader; } } - else + else if (!params.mFullbright) { target_shader = simple_shader; } + else + { + target_shader = fullbright_shader; + } if(use_shaders && (current_shader != target_shader)) {// If we need shaders, and we're not ALREADY using the proper shader, then bind it @@ -754,7 +782,26 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE)) { LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_EMISSIVE); +#if BATCH_EMISSIVES emissives.push_back(¶ms); +#else +// install glow-accumulating blend mode + gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color + LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow) + + emissive_shader->bind(); + + params.mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE); + + // do the actual drawing, again + params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); + gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); + + // restore our alpha blend mode + gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); + + current_shader->bind(); +#endif } if (tex_setup) @@ -766,9 +813,13 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) } } +#if BATCH_FULLBRIGHTS renderFullbrights(mask, fullbrights); - renderEmissives(mask, emissives); +#endif +#if BATCH_EMISSIVES + renderEmissives(mask, emissives); +#endif if (current_shader) { current_shader->bind(); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index e96e7cbe6c..f0a0851b2e 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -493,7 +493,7 @@ void LLDrawPoolAvatar::renderShadow(S32 pass) } LLVOAvatar *avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get(); - if (avatarp->isDead() || avatarp->mIsDummy || avatarp->mDrawable.isNull()) + if (avatarp->isDead() || avatarp->isUIAvatar() || avatarp->mDrawable.isNull()) { return; } @@ -1820,7 +1820,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) { - if (avatar->isSelf() && !gAgent.needsRenderAvatar()) + if (!avatar->shouldRenderRigged()) { return; } @@ -2208,7 +2208,6 @@ void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type) { LL_ERRS() << "Invalid rigged face type." << LL_ENDL; } - if (facep->getRiggedIndex(type) != -1) { LL_ERRS() << "Tried to add a rigged face that's referenced elsewhere." << LL_ENDL; diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h index f94baefc41..d436557e1c 100644 --- a/indra/newview/lldrawpoolwater.h +++ b/indra/newview/lldrawpoolwater.h @@ -47,8 +47,6 @@ public: static BOOL sSkipScreenCopy; static BOOL sNeedsReflectionUpdate; static BOOL sNeedsDistortionUpdate; -// static LLVector3 sLightDir; -// static LLColor4 sWaterFogColor; static F32 sWaterFogEnd; enum diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 8a739d91f8..e608f6eaf2 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -48,7 +48,6 @@ static LLStaticHashedString sCamPosLocal("camPosLocal"); static LLStaticHashedString sCustomAlpha("custom_alpha"); static LLGLSLShader* cloud_shader = NULL; -static LLGLSLShader* cloud_shadow_shader = NULL; static LLGLSLShader* sky_shader = NULL; static LLGLSLShader* sun_shader = NULL; static LLGLSLShader* moon_shader = NULL; @@ -124,29 +123,6 @@ void LLDrawPoolWLSky::endDeferredPass(S32 pass) moon_shader = nullptr; } -S32 LLDrawPoolWLSky::getNumShadowPasses() { return 0; } - -void LLDrawPoolWLSky::beginShadowPass(S32 pass) -{ - //cloud_shadow_shader = LLPipeline::sRenderDeferred ? &gDeferredWLCloudShadowProgram : &gWLCloudShadowProgram; -} - -void LLDrawPoolWLSky::endShadowPass(S32 pass) -{ - cloud_shadow_shader = nullptr; -} - -void LLDrawPoolWLSky::renderShadow(S32 pass) -{ - if (cloud_shadow_shader) - { - const F32 camHeightLocal = LLEnvironment::instance().getCamHeight(); - LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); - - renderSkyClouds(origin, camHeightLocal, cloud_shadow_shader); - } -} - void LLDrawPoolWLSky::renderFsSky(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const { gSky.mVOWLSkyp->drawFsSky(); diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h index b05f0f8605..3acfda4eee 100644 --- a/indra/newview/lldrawpoolwlsky.h +++ b/indra/newview/lldrawpoolwlsky.h @@ -34,14 +34,12 @@ class LLGLSLShader; class LLDrawPoolWLSky : public LLDrawPool { public: - static const U32 SKY_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX - | LLVertexBuffer::MAP_TEXCOORD0; - static const U32 STAR_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX - | LLVertexBuffer::MAP_COLOR - | LLVertexBuffer::MAP_TEXCOORD0; + static const U32 SKY_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer::MAP_TEXCOORD0; + static const U32 STAR_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0; static const U32 ADV_ATMO_SKY_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0; - LLDrawPoolWLSky(void); /*virtual*/ ~LLDrawPoolWLSky(); @@ -52,22 +50,10 @@ public: /*virtual*/ void endDeferredPass(S32 pass); /*virtual*/ void renderDeferred(S32 pass); - - /*virtual*/ S32 getNumPostDeferredPasses() { return 0; } - /*virtual*/ void beginPostDeferredPass(S32 pass) {} - /*virtual*/ void endPostDeferredPass(S32 pass) {} - /*virtual*/ void renderPostDeferred(S32 pass) {} - /*virtual*/ LLViewerTexture *getDebugTexture(); /*virtual*/ void beginRenderPass( S32 pass ); /*virtual*/ void endRenderPass( S32 pass ); /*virtual*/ S32 getNumPasses() { return 1; } - - /*virtual*/ S32 getNumShadowPasses(); - /*virtual*/ void beginShadowPass(S32 pass); - /*virtual*/ void endShadowPass(S32 pass); - /*virtual*/ void renderShadow(S32 pass); - /*virtual*/ void render(S32 pass = 0); /*virtual*/ void prerender(); /*virtual*/ U32 getVertexDataMask() { return SKY_VERTEX_DATA_MASK; } diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index c934cd2980..e38bd8846d 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -2663,7 +2663,7 @@ void LLMeshUploadThread::requestWholeModelFee() { ms_sleep(sleep_time); sleep_time = llmin(250U, sleep_time + sleep_time); - mHttpRequest->update(0); + mHttpRequest->update(0); } if (isDiscarded()) { diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 3d3826064f..2e5807cab9 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -1036,7 +1036,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI"); if (!for_snapshot) - { + { render_ui(); swap(); } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index c9b13f92d3..68a91968ea 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1211,20 +1211,6 @@ class LLAdvancedSelectedTextureInfo : public view_listener_t } }; -//////////////////////////// -// TOGGLE SH LIGHTING VIS // -//////////////////////////// - -class LLAdvancedToggleDebugSH : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_SH); - gSavedSettings.setBOOL("RenderDebugSH", gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SH)); - return true; - } -}; - ////////////////////// // TOGGLE WIREFRAME // ////////////////////// @@ -6115,7 +6101,12 @@ class LLAvatarResetSkeleton: public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); + LLVOAvatar* avatar = NULL; + LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (obj) + { + avatar = obj->getAvatar(); + } if(avatar) { avatar->resetSkeleton(false); @@ -8658,6 +8649,7 @@ class LLWorldEnableEnvPreset : public view_listener_t } }; + /// Post-Process callbacks class LLWorldPostProcess : public view_listener_t { @@ -8998,7 +8990,6 @@ void initialize_menus() commit.add("Advanced.SelectedMaterialInfo", boost::bind(&handle_selected_material_info)); view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe"); view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe"); - view_listener_t::addMenu(new LLAdvancedToggleDebugSH(), "Advanced.ToggleDebugSH"); // Develop > Render view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion"); view_listener_t::addMenu(new LLAdvancedEnableRenderFBO(), "Advanced.EnableRenderFBO"); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index e30ff42b4f..5f35f71742 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -63,325 +63,319 @@ using std::pair; using std::make_pair; using std::string; -BOOL LLViewerShaderMgr::sInitialized = FALSE; -bool LLViewerShaderMgr::sSkipReload = false; +BOOL LLViewerShaderMgr::sInitialized = FALSE; +bool LLViewerShaderMgr::sSkipReload = false; -LLVector4 gShinyOrigin; +LLVector4 gShinyOrigin; //transform shaders -LLGLSLShader gTransformPositionProgram; -LLGLSLShader gTransformTexCoordProgram; -LLGLSLShader gTransformNormalProgram; -LLGLSLShader gTransformColorProgram; -LLGLSLShader gTransformTangentProgram; +LLGLSLShader gTransformPositionProgram; +LLGLSLShader gTransformTexCoordProgram; +LLGLSLShader gTransformNormalProgram; +LLGLSLShader gTransformColorProgram; +LLGLSLShader gTransformTangentProgram; //utility shaders -LLGLSLShader gOcclusionProgram; -LLGLSLShader gOcclusionCubeProgram; -LLGLSLShader gCustomAlphaProgram; -LLGLSLShader gGlowCombineProgram; -LLGLSLShader gSplatTextureRectProgram; -LLGLSLShader gGlowCombineFXAAProgram; -LLGLSLShader gTwoTextureAddProgram; -LLGLSLShader gTwoTextureCompareProgram; -LLGLSLShader gOneTextureFilterProgram; -LLGLSLShader gOneTextureNoColorProgram; -LLGLSLShader gDebugProgram; -LLGLSLShader gClipProgram; -LLGLSLShader gDownsampleDepthProgram; -LLGLSLShader gDownsampleDepthRectProgram; -LLGLSLShader gDownsampleMinMaxDepthRectProgram; -LLGLSLShader gInscatterRectProgram; -LLGLSLShader gAlphaMaskProgram; -LLGLSLShader gBenchmarkProgram; +LLGLSLShader gOcclusionProgram; +LLGLSLShader gOcclusionCubeProgram; +LLGLSLShader gCustomAlphaProgram; +LLGLSLShader gGlowCombineProgram; +LLGLSLShader gSplatTextureRectProgram; +LLGLSLShader gGlowCombineFXAAProgram; +LLGLSLShader gTwoTextureAddProgram; +LLGLSLShader gTwoTextureCompareProgram; +LLGLSLShader gOneTextureFilterProgram; +LLGLSLShader gOneTextureNoColorProgram; +LLGLSLShader gDebugProgram; +LLGLSLShader gClipProgram; +LLGLSLShader gDownsampleDepthProgram; +LLGLSLShader gDownsampleDepthRectProgram; +LLGLSLShader gAlphaMaskProgram; +LLGLSLShader gBenchmarkProgram; //object shaders -LLGLSLShader gObjectSimpleProgram; -LLGLSLShader gObjectSimpleImpostorProgram; -LLGLSLShader gObjectPreviewProgram; -LLGLSLShader gObjectSimpleWaterProgram; -LLGLSLShader gObjectSimpleAlphaMaskProgram; -LLGLSLShader gObjectSimpleWaterAlphaMaskProgram; -LLGLSLShader gObjectFullbrightProgram; -LLGLSLShader gObjectFullbrightWaterProgram; -LLGLSLShader gObjectEmissiveProgram; -LLGLSLShader gObjectEmissiveWaterProgram; -LLGLSLShader gObjectFullbrightAlphaMaskProgram; -LLGLSLShader gObjectFullbrightWaterAlphaMaskProgram; -LLGLSLShader gObjectFullbrightShinyProgram; -LLGLSLShader gObjectFullbrightShinyWaterProgram; -LLGLSLShader gObjectShinyProgram; -LLGLSLShader gObjectShinyWaterProgram; -LLGLSLShader gObjectBumpProgram; -LLGLSLShader gTreeProgram; -LLGLSLShader gTreeWaterProgram; -LLGLSLShader gObjectFullbrightNoColorProgram; -LLGLSLShader gObjectFullbrightNoColorWaterProgram; - -LLGLSLShader gObjectSimpleNonIndexedProgram; -LLGLSLShader gObjectSimpleNonIndexedTexGenProgram; -LLGLSLShader gObjectSimpleNonIndexedTexGenWaterProgram; -LLGLSLShader gObjectSimpleNonIndexedWaterProgram; -LLGLSLShader gObjectAlphaMaskNonIndexedProgram; -LLGLSLShader gObjectAlphaMaskNonIndexedWaterProgram; -LLGLSLShader gObjectAlphaMaskNoColorProgram; -LLGLSLShader gObjectAlphaMaskNoColorWaterProgram; -LLGLSLShader gObjectFullbrightNonIndexedProgram; -LLGLSLShader gObjectFullbrightNonIndexedWaterProgram; -LLGLSLShader gObjectEmissiveNonIndexedProgram; -LLGLSLShader gObjectEmissiveNonIndexedWaterProgram; -LLGLSLShader gObjectFullbrightShinyNonIndexedProgram; -LLGLSLShader gObjectFullbrightShinyNonIndexedWaterProgram; -LLGLSLShader gObjectShinyNonIndexedProgram; -LLGLSLShader gObjectShinyNonIndexedWaterProgram; +LLGLSLShader gObjectSimpleProgram; +LLGLSLShader gObjectSimpleImpostorProgram; +LLGLSLShader gObjectPreviewProgram; +LLGLSLShader gObjectSimpleWaterProgram; +LLGLSLShader gObjectSimpleAlphaMaskProgram; +LLGLSLShader gObjectSimpleWaterAlphaMaskProgram; +LLGLSLShader gObjectFullbrightProgram; +LLGLSLShader gObjectFullbrightWaterProgram; +LLGLSLShader gObjectEmissiveProgram; +LLGLSLShader gObjectEmissiveWaterProgram; +LLGLSLShader gObjectFullbrightAlphaMaskProgram; +LLGLSLShader gObjectFullbrightWaterAlphaMaskProgram; +LLGLSLShader gObjectFullbrightShinyProgram; +LLGLSLShader gObjectFullbrightShinyWaterProgram; +LLGLSLShader gObjectShinyProgram; +LLGLSLShader gObjectShinyWaterProgram; +LLGLSLShader gObjectBumpProgram; +LLGLSLShader gTreeProgram; +LLGLSLShader gTreeWaterProgram; +LLGLSLShader gObjectFullbrightNoColorProgram; +LLGLSLShader gObjectFullbrightNoColorWaterProgram; + +LLGLSLShader gObjectSimpleNonIndexedProgram; +LLGLSLShader gObjectSimpleNonIndexedTexGenProgram; +LLGLSLShader gObjectSimpleNonIndexedTexGenWaterProgram; +LLGLSLShader gObjectSimpleNonIndexedWaterProgram; +LLGLSLShader gObjectAlphaMaskNonIndexedProgram; +LLGLSLShader gObjectAlphaMaskNonIndexedWaterProgram; +LLGLSLShader gObjectAlphaMaskNoColorProgram; +LLGLSLShader gObjectAlphaMaskNoColorWaterProgram; +LLGLSLShader gObjectFullbrightNonIndexedProgram; +LLGLSLShader gObjectFullbrightNonIndexedWaterProgram; +LLGLSLShader gObjectEmissiveNonIndexedProgram; +LLGLSLShader gObjectEmissiveNonIndexedWaterProgram; +LLGLSLShader gObjectFullbrightShinyNonIndexedProgram; +LLGLSLShader gObjectFullbrightShinyNonIndexedWaterProgram; +LLGLSLShader gObjectShinyNonIndexedProgram; +LLGLSLShader gObjectShinyNonIndexedWaterProgram; //object hardware skinning shaders -LLGLSLShader gSkinnedObjectSimpleProgram; -LLGLSLShader gSkinnedObjectFullbrightProgram; -LLGLSLShader gSkinnedObjectEmissiveProgram; -LLGLSLShader gSkinnedObjectFullbrightShinyProgram; -LLGLSLShader gSkinnedObjectShinySimpleProgram; - -LLGLSLShader gSkinnedObjectSimpleWaterProgram; -LLGLSLShader gSkinnedObjectFullbrightWaterProgram; -LLGLSLShader gSkinnedObjectEmissiveWaterProgram; -LLGLSLShader gSkinnedObjectFullbrightShinyWaterProgram; -LLGLSLShader gSkinnedObjectShinySimpleWaterProgram; +LLGLSLShader gSkinnedObjectSimpleProgram; +LLGLSLShader gSkinnedObjectFullbrightProgram; +LLGLSLShader gSkinnedObjectEmissiveProgram; +LLGLSLShader gSkinnedObjectFullbrightShinyProgram; +LLGLSLShader gSkinnedObjectShinySimpleProgram; + +LLGLSLShader gSkinnedObjectSimpleWaterProgram; +LLGLSLShader gSkinnedObjectFullbrightWaterProgram; +LLGLSLShader gSkinnedObjectEmissiveWaterProgram; +LLGLSLShader gSkinnedObjectFullbrightShinyWaterProgram; +LLGLSLShader gSkinnedObjectShinySimpleWaterProgram; //environment shaders -LLGLSLShader gTerrainProgram; -LLGLSLShader gTerrainWaterProgram; -LLGLSLShader gWaterProgram; +LLGLSLShader gTerrainProgram; +LLGLSLShader gTerrainWaterProgram; +LLGLSLShader gWaterProgram; LLGLSLShader gWaterEdgeProgram; -LLGLSLShader gUnderWaterProgram; +LLGLSLShader gUnderWaterProgram; //interface shaders -LLGLSLShader gHighlightProgram; -LLGLSLShader gHighlightNormalProgram; -LLGLSLShader gHighlightSpecularProgram; +LLGLSLShader gHighlightProgram; +LLGLSLShader gHighlightNormalProgram; +LLGLSLShader gHighlightSpecularProgram; -LLGLSLShader gPathfindingProgram; -LLGLSLShader gPathfindingNoNormalsProgram; +LLGLSLShader gPathfindingProgram; +LLGLSLShader gPathfindingNoNormalsProgram; //avatar shader handles -LLGLSLShader gAvatarProgram; -LLGLSLShader gAvatarWaterProgram; -LLGLSLShader gAvatarEyeballProgram; -LLGLSLShader gAvatarPickProgram; -LLGLSLShader gImpostorProgram; +LLGLSLShader gAvatarProgram; +LLGLSLShader gAvatarWaterProgram; +LLGLSLShader gAvatarEyeballProgram; +LLGLSLShader gAvatarPickProgram; +LLGLSLShader gImpostorProgram; // WindLight shader handles -LLGLSLShader gWLSkyProgram; -LLGLSLShader gWLCloudProgram; -LLGLSLShader gWLCloudShadowProgram; +LLGLSLShader gWLSkyProgram; +LLGLSLShader gWLCloudProgram; LLGLSLShader gWLSunProgram; LLGLSLShader gWLMoonProgram; // Effects Shaders -LLGLSLShader gGlowProgram; -LLGLSLShader gGlowExtractProgram; -LLGLSLShader gPostColorFilterProgram; -LLGLSLShader gPostNightVisionProgram; +LLGLSLShader gGlowProgram; +LLGLSLShader gGlowExtractProgram; +LLGLSLShader gPostColorFilterProgram; +LLGLSLShader gPostNightVisionProgram; // Deferred rendering shaders -LLGLSLShader gDeferredImpostorProgram; -LLGLSLShader gDeferredWaterProgram; -LLGLSLShader gDeferredUnderWaterProgram; -LLGLSLShader gDeferredDiffuseProgram; -LLGLSLShader gDeferredDiffuseAlphaMaskProgram; -LLGLSLShader gDeferredNonIndexedDiffuseProgram; -LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram; -LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram; -LLGLSLShader gDeferredSkinnedDiffuseProgram; -LLGLSLShader gDeferredSkinnedBumpProgram; -LLGLSLShader gDeferredSkinnedAlphaProgram; -LLGLSLShader gDeferredBumpProgram; -LLGLSLShader gDeferredTerrainProgram; +LLGLSLShader gDeferredImpostorProgram; +LLGLSLShader gDeferredWaterProgram; +LLGLSLShader gDeferredUnderWaterProgram; +LLGLSLShader gDeferredDiffuseProgram; +LLGLSLShader gDeferredDiffuseAlphaMaskProgram; +LLGLSLShader gDeferredNonIndexedDiffuseProgram; +LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram; +LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram; +LLGLSLShader gDeferredSkinnedDiffuseProgram; +LLGLSLShader gDeferredSkinnedBumpProgram; +LLGLSLShader gDeferredSkinnedAlphaProgram; +LLGLSLShader gDeferredBumpProgram; +LLGLSLShader gDeferredTerrainProgram; LLGLSLShader gDeferredTerrainWaterProgram; -LLGLSLShader gDeferredTreeProgram; -LLGLSLShader gDeferredTreeShadowProgram; -LLGLSLShader gDeferredAvatarProgram; -LLGLSLShader gDeferredAvatarAlphaProgram; -LLGLSLShader gDeferredLightProgram; -LLGLSLShader gDeferredMultiLightProgram[16]; -LLGLSLShader gDeferredSpotLightProgram; -LLGLSLShader gDeferredMultiSpotLightProgram; -LLGLSLShader gDeferredSunProgram; -LLGLSLShader gDeferredBlurLightProgram; -LLGLSLShader gDeferredSoftenProgram; -LLGLSLShader gDeferredSoftenWaterProgram; -LLGLSLShader gDeferredShadowProgram; -LLGLSLShader gDeferredShadowCubeProgram; -LLGLSLShader gDeferredShadowAlphaMaskProgram; -LLGLSLShader gDeferredAvatarShadowProgram; -LLGLSLShader gDeferredAttachmentShadowProgram; -LLGLSLShader gDeferredAlphaProgram; -LLGLSLShader gDeferredAlphaImpostorProgram; -LLGLSLShader gDeferredAlphaWaterProgram; -LLGLSLShader gDeferredAvatarEyesProgram; -LLGLSLShader gDeferredFullbrightProgram; -LLGLSLShader gDeferredFullbrightAlphaMaskProgram; -LLGLSLShader gDeferredFullbrightWaterProgram; -LLGLSLShader gDeferredFullbrightAlphaMaskWaterProgram; -LLGLSLShader gDeferredEmissiveProgram; -LLGLSLShader gDeferredPostProgram; -LLGLSLShader gDeferredCoFProgram; -LLGLSLShader gDeferredDoFCombineProgram; -LLGLSLShader gDeferredPostGammaCorrectProgram; -LLGLSLShader gFXAAProgram; -LLGLSLShader gDeferredPostNoDoFProgram; -LLGLSLShader gDeferredWLSkyProgram; -LLGLSLShader gDeferredWLCloudProgram; -LLGLSLShader gDeferredWLCloudShadowProgram; -LLGLSLShader gDeferredWLSunProgram; -LLGLSLShader gDeferredWLMoonProgram; -LLGLSLShader gDeferredStarProgram; -LLGLSLShader gDeferredFullbrightShinyProgram; -LLGLSLShader gDeferredSkinnedFullbrightShinyProgram; -LLGLSLShader gDeferredSkinnedFullbrightProgram; -LLGLSLShader gNormalMapGenProgram; +LLGLSLShader gDeferredTreeProgram; +LLGLSLShader gDeferredTreeShadowProgram; +LLGLSLShader gDeferredAvatarProgram; +LLGLSLShader gDeferredAvatarAlphaProgram; +LLGLSLShader gDeferredLightProgram; +LLGLSLShader gDeferredMultiLightProgram[16]; +LLGLSLShader gDeferredSpotLightProgram; +LLGLSLShader gDeferredMultiSpotLightProgram; +LLGLSLShader gDeferredSunProgram; +LLGLSLShader gDeferredBlurLightProgram; +LLGLSLShader gDeferredSoftenProgram; +LLGLSLShader gDeferredSoftenWaterProgram; +LLGLSLShader gDeferredShadowProgram; +LLGLSLShader gDeferredShadowCubeProgram; +LLGLSLShader gDeferredShadowAlphaMaskProgram; +LLGLSLShader gDeferredAvatarShadowProgram; +LLGLSLShader gDeferredAttachmentShadowProgram; +LLGLSLShader gDeferredAlphaProgram; +LLGLSLShader gDeferredAlphaImpostorProgram; +LLGLSLShader gDeferredAlphaWaterProgram; +LLGLSLShader gDeferredAvatarEyesProgram; +LLGLSLShader gDeferredFullbrightProgram; +LLGLSLShader gDeferredFullbrightAlphaMaskProgram; +LLGLSLShader gDeferredFullbrightWaterProgram; +LLGLSLShader gDeferredFullbrightAlphaMaskWaterProgram; +LLGLSLShader gDeferredEmissiveProgram; +LLGLSLShader gDeferredPostProgram; +LLGLSLShader gDeferredCoFProgram; +LLGLSLShader gDeferredDoFCombineProgram; +LLGLSLShader gDeferredPostGammaCorrectProgram; +LLGLSLShader gFXAAProgram; +LLGLSLShader gDeferredPostNoDoFProgram; +LLGLSLShader gDeferredWLSkyProgram; +LLGLSLShader gDeferredWLCloudProgram; +LLGLSLShader gDeferredWLSunProgram; +LLGLSLShader gDeferredWLMoonProgram; +LLGLSLShader gDeferredStarProgram; +LLGLSLShader gDeferredFullbrightShinyProgram; +LLGLSLShader gDeferredSkinnedFullbrightShinyProgram; +LLGLSLShader gDeferredSkinnedFullbrightProgram; +LLGLSLShader gNormalMapGenProgram; // Deferred materials shaders -LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; -LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2]; +LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; +LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2]; LLViewerShaderMgr::LLViewerShaderMgr() : - mShaderLevel(SHADER_COUNT, 0), - mMaxAvatarShaderLevel(0) + mShaderLevel(SHADER_COUNT, 0), + mMaxAvatarShaderLevel(0) { /// Make sure WL Sky is the first program //ONLY shaders that need WL Param management should be added here - mShaderList.push_back(&gWLSkyProgram); - mShaderList.push_back(&gWLCloudProgram); - mShaderList.push_back(&gWLCloudShadowProgram); - mShaderList.push_back(&gWLSunProgram); - mShaderList.push_back(&gWLMoonProgram); - mShaderList.push_back(&gAvatarProgram); - mShaderList.push_back(&gObjectShinyProgram); - mShaderList.push_back(&gObjectShinyNonIndexedProgram); - mShaderList.push_back(&gWaterProgram); - mShaderList.push_back(&gWaterEdgeProgram); - mShaderList.push_back(&gAvatarEyeballProgram); - mShaderList.push_back(&gObjectSimpleProgram); - mShaderList.push_back(&gObjectSimpleImpostorProgram); - mShaderList.push_back(&gObjectPreviewProgram); - mShaderList.push_back(&gImpostorProgram); - mShaderList.push_back(&gObjectFullbrightNoColorProgram); - mShaderList.push_back(&gObjectFullbrightNoColorWaterProgram); - mShaderList.push_back(&gObjectSimpleAlphaMaskProgram); - mShaderList.push_back(&gObjectBumpProgram); - mShaderList.push_back(&gObjectEmissiveProgram); - mShaderList.push_back(&gObjectEmissiveWaterProgram); - mShaderList.push_back(&gObjectFullbrightProgram); - mShaderList.push_back(&gObjectFullbrightAlphaMaskProgram); - mShaderList.push_back(&gObjectFullbrightShinyProgram); - mShaderList.push_back(&gObjectFullbrightShinyWaterProgram); - mShaderList.push_back(&gObjectSimpleNonIndexedProgram); - mShaderList.push_back(&gObjectSimpleNonIndexedTexGenProgram); - mShaderList.push_back(&gObjectSimpleNonIndexedTexGenWaterProgram); - mShaderList.push_back(&gObjectSimpleNonIndexedWaterProgram); - mShaderList.push_back(&gObjectAlphaMaskNonIndexedProgram); - mShaderList.push_back(&gObjectAlphaMaskNonIndexedWaterProgram); - mShaderList.push_back(&gObjectAlphaMaskNoColorProgram); - mShaderList.push_back(&gObjectAlphaMaskNoColorWaterProgram); - mShaderList.push_back(&gTreeProgram); - mShaderList.push_back(&gTreeWaterProgram); - mShaderList.push_back(&gObjectFullbrightNonIndexedProgram); - mShaderList.push_back(&gObjectFullbrightNonIndexedWaterProgram); - mShaderList.push_back(&gObjectEmissiveNonIndexedProgram); - mShaderList.push_back(&gObjectEmissiveNonIndexedWaterProgram); - mShaderList.push_back(&gObjectFullbrightShinyNonIndexedProgram); - mShaderList.push_back(&gObjectFullbrightShinyNonIndexedWaterProgram); - mShaderList.push_back(&gSkinnedObjectSimpleProgram); - mShaderList.push_back(&gSkinnedObjectFullbrightProgram); - mShaderList.push_back(&gSkinnedObjectEmissiveProgram); - mShaderList.push_back(&gSkinnedObjectFullbrightShinyProgram); - mShaderList.push_back(&gSkinnedObjectShinySimpleProgram); - mShaderList.push_back(&gSkinnedObjectSimpleWaterProgram); - mShaderList.push_back(&gSkinnedObjectFullbrightWaterProgram); - mShaderList.push_back(&gSkinnedObjectEmissiveWaterProgram); - mShaderList.push_back(&gSkinnedObjectFullbrightShinyWaterProgram); - mShaderList.push_back(&gSkinnedObjectShinySimpleWaterProgram); - mShaderList.push_back(&gTerrainProgram); - mShaderList.push_back(&gTerrainWaterProgram); - mShaderList.push_back(&gObjectSimpleWaterProgram); - mShaderList.push_back(&gObjectFullbrightWaterProgram); - mShaderList.push_back(&gObjectSimpleWaterAlphaMaskProgram); - mShaderList.push_back(&gObjectFullbrightWaterAlphaMaskProgram); - mShaderList.push_back(&gAvatarWaterProgram); - mShaderList.push_back(&gObjectShinyWaterProgram); - mShaderList.push_back(&gObjectShinyNonIndexedWaterProgram); - mShaderList.push_back(&gUnderWaterProgram); - mShaderList.push_back(&gDeferredSunProgram); - mShaderList.push_back(&gDeferredSoftenProgram); - mShaderList.push_back(&gDeferredSoftenWaterProgram); - mShaderList.push_back(&gDeferredAlphaProgram); - mShaderList.push_back(&gDeferredAlphaImpostorProgram); - mShaderList.push_back(&gDeferredAlphaWaterProgram); - mShaderList.push_back(&gDeferredSkinnedAlphaProgram); - mShaderList.push_back(&gDeferredFullbrightProgram); - mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram); - mShaderList.push_back(&gDeferredFullbrightWaterProgram); - mShaderList.push_back(&gDeferredFullbrightAlphaMaskWaterProgram); - mShaderList.push_back(&gDeferredFullbrightShinyProgram); - mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram); - mShaderList.push_back(&gDeferredSkinnedFullbrightProgram); - mShaderList.push_back(&gDeferredEmissiveProgram); - mShaderList.push_back(&gDeferredAvatarEyesProgram); - mShaderList.push_back(&gDeferredWaterProgram); - mShaderList.push_back(&gDeferredUnderWaterProgram); + mShaderList.push_back(&gWLSkyProgram); + mShaderList.push_back(&gWLCloudProgram); + mShaderList.push_back(&gWLSunProgram); + mShaderList.push_back(&gWLMoonProgram); + mShaderList.push_back(&gAvatarProgram); + mShaderList.push_back(&gObjectShinyProgram); + mShaderList.push_back(&gObjectShinyNonIndexedProgram); + mShaderList.push_back(&gWaterProgram); + mShaderList.push_back(&gWaterEdgeProgram); + mShaderList.push_back(&gAvatarEyeballProgram); + mShaderList.push_back(&gObjectSimpleProgram); + mShaderList.push_back(&gObjectSimpleImpostorProgram); + mShaderList.push_back(&gObjectPreviewProgram); + mShaderList.push_back(&gImpostorProgram); + mShaderList.push_back(&gObjectFullbrightNoColorProgram); + mShaderList.push_back(&gObjectFullbrightNoColorWaterProgram); + mShaderList.push_back(&gObjectSimpleAlphaMaskProgram); + mShaderList.push_back(&gObjectBumpProgram); + mShaderList.push_back(&gObjectEmissiveProgram); + mShaderList.push_back(&gObjectEmissiveWaterProgram); + mShaderList.push_back(&gObjectFullbrightProgram); + mShaderList.push_back(&gObjectFullbrightAlphaMaskProgram); + mShaderList.push_back(&gObjectFullbrightShinyProgram); + mShaderList.push_back(&gObjectFullbrightShinyWaterProgram); + mShaderList.push_back(&gObjectSimpleNonIndexedProgram); + mShaderList.push_back(&gObjectSimpleNonIndexedTexGenProgram); + mShaderList.push_back(&gObjectSimpleNonIndexedTexGenWaterProgram); + mShaderList.push_back(&gObjectSimpleNonIndexedWaterProgram); + mShaderList.push_back(&gObjectAlphaMaskNonIndexedProgram); + mShaderList.push_back(&gObjectAlphaMaskNonIndexedWaterProgram); + mShaderList.push_back(&gObjectAlphaMaskNoColorProgram); + mShaderList.push_back(&gObjectAlphaMaskNoColorWaterProgram); + mShaderList.push_back(&gTreeProgram); + mShaderList.push_back(&gTreeWaterProgram); + mShaderList.push_back(&gObjectFullbrightNonIndexedProgram); + mShaderList.push_back(&gObjectFullbrightNonIndexedWaterProgram); + mShaderList.push_back(&gObjectEmissiveNonIndexedProgram); + mShaderList.push_back(&gObjectEmissiveNonIndexedWaterProgram); + mShaderList.push_back(&gObjectFullbrightShinyNonIndexedProgram); + mShaderList.push_back(&gObjectFullbrightShinyNonIndexedWaterProgram); + mShaderList.push_back(&gSkinnedObjectSimpleProgram); + mShaderList.push_back(&gSkinnedObjectFullbrightProgram); + mShaderList.push_back(&gSkinnedObjectEmissiveProgram); + mShaderList.push_back(&gSkinnedObjectFullbrightShinyProgram); + mShaderList.push_back(&gSkinnedObjectShinySimpleProgram); + mShaderList.push_back(&gSkinnedObjectSimpleWaterProgram); + mShaderList.push_back(&gSkinnedObjectFullbrightWaterProgram); + mShaderList.push_back(&gSkinnedObjectEmissiveWaterProgram); + mShaderList.push_back(&gSkinnedObjectFullbrightShinyWaterProgram); + mShaderList.push_back(&gSkinnedObjectShinySimpleWaterProgram); + mShaderList.push_back(&gTerrainProgram); + mShaderList.push_back(&gTerrainWaterProgram); + mShaderList.push_back(&gObjectSimpleWaterProgram); + mShaderList.push_back(&gObjectFullbrightWaterProgram); + mShaderList.push_back(&gObjectSimpleWaterAlphaMaskProgram); + mShaderList.push_back(&gObjectFullbrightWaterAlphaMaskProgram); + mShaderList.push_back(&gAvatarWaterProgram); + mShaderList.push_back(&gObjectShinyWaterProgram); + mShaderList.push_back(&gObjectShinyNonIndexedWaterProgram); + mShaderList.push_back(&gUnderWaterProgram); + mShaderList.push_back(&gDeferredSunProgram); + mShaderList.push_back(&gDeferredSoftenProgram); + mShaderList.push_back(&gDeferredSoftenWaterProgram); + mShaderList.push_back(&gDeferredAlphaProgram); + mShaderList.push_back(&gDeferredAlphaImpostorProgram); + mShaderList.push_back(&gDeferredAlphaWaterProgram); + mShaderList.push_back(&gDeferredSkinnedAlphaProgram); + mShaderList.push_back(&gDeferredFullbrightProgram); + mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram); + mShaderList.push_back(&gDeferredFullbrightWaterProgram); + mShaderList.push_back(&gDeferredFullbrightAlphaMaskWaterProgram); + mShaderList.push_back(&gDeferredFullbrightShinyProgram); + mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram); + mShaderList.push_back(&gDeferredSkinnedFullbrightProgram); + mShaderList.push_back(&gDeferredEmissiveProgram); + mShaderList.push_back(&gDeferredAvatarEyesProgram); + mShaderList.push_back(&gDeferredWaterProgram); + mShaderList.push_back(&gDeferredUnderWaterProgram); mShaderList.push_back(&gDeferredTerrainWaterProgram); - mShaderList.push_back(&gDeferredAvatarAlphaProgram); - mShaderList.push_back(&gDeferredWLSkyProgram); - mShaderList.push_back(&gDeferredWLCloudProgram); - mShaderList.push_back(&gDeferredWLCloudShadowProgram); + mShaderList.push_back(&gDeferredAvatarAlphaProgram); + mShaderList.push_back(&gDeferredWLSkyProgram); + mShaderList.push_back(&gDeferredWLCloudProgram); mShaderList.push_back(&gDeferredWLMoonProgram); mShaderList.push_back(&gDeferredWLSunProgram); } LLViewerShaderMgr::~LLViewerShaderMgr() { - mShaderLevel.clear(); - mShaderList.clear(); + mShaderLevel.clear(); + mShaderList.clear(); } // static LLViewerShaderMgr * LLViewerShaderMgr::instance() { - if(NULL == sInstance) - { - sInstance = new LLViewerShaderMgr(); - } + if(NULL == sInstance) + { + sInstance = new LLViewerShaderMgr(); + } - return static_cast<LLViewerShaderMgr*>(sInstance); + return static_cast<LLViewerShaderMgr*>(sInstance); } // static void LLViewerShaderMgr::releaseInstance() { - if (sInstance != NULL) - { - delete sInstance; - sInstance = NULL; - } + if (sInstance != NULL) + { + delete sInstance; + sInstance = NULL; + } } void LLViewerShaderMgr::initAttribsAndUniforms(void) { - if (mReservedAttribs.empty()) - { - LLShaderMgr::initAttribsAndUniforms(); - } + if (mReservedAttribs.empty()) + { + LLShaderMgr::initAttribsAndUniforms(); + } } - + //============================================================================ // Set Levels S32 LLViewerShaderMgr::getShaderLevel(S32 type) { - return LLPipeline::sDisableShaders ? 0 : mShaderLevel[type]; + return LLPipeline::sDisableShaders ? 0 : mShaderLevel[type]; } //============================================================================ @@ -389,82 +383,82 @@ S32 LLViewerShaderMgr::getShaderLevel(S32 type) void LLViewerShaderMgr::setShaders() { - //setShaders might be called redundantly by gSavedSettings, so return on reentrance - static bool reentrance = false; - - if (!gPipeline.mInitialized || !sInitialized || reentrance || sSkipReload) - { - return; - } - - LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits, (S32) gSavedSettings.getU32("RenderMaxTextureIndex")), 1); - - //NEVER use more than 16 texture channels (work around for prevalent driver bug) - LLGLSLShader::sIndexedTextureChannels = llmin(LLGLSLShader::sIndexedTextureChannels, 16); - - if (gGLManager.mGLSLVersionMajor < 1 || - (gGLManager.mGLSLVersionMajor == 1 && gGLManager.mGLSLVersionMinor <= 20)) - { //NEVER use indexed texture rendering when GLSL version is 1.20 or earlier - LLGLSLShader::sIndexedTextureChannels = 1; - } - - reentrance = true; - - if (LLRender::sGLCoreProfile) - { - if (!gSavedSettings.getBOOL("VertexShaderEnable")) - { //vertex shaders MUST be enabled to use core profile - gSavedSettings.setBOOL("VertexShaderEnable", TRUE); - } - } - - //setup preprocessor definitions - LLShaderMgr::instance()->mDefinitions["NUM_TEX_UNITS"] = llformat("%d", gGLManager.mNumTextureImageUnits); - - // Make sure the compiled shader map is cleared before we recompile shaders. - mShaderObjects.clear(); - - initAttribsAndUniforms(); - gPipeline.releaseGLBuffers(); - - if (gSavedSettings.getBOOL("VertexShaderEnable")) - { - LLPipeline::sWaterReflections = gGLManager.mHasCubeMap; - LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow"); - LLPipeline::updateRenderDeferred(); - } - else - { - LLPipeline::sRenderGlow = FALSE; - LLPipeline::sWaterReflections = FALSE; - } - - //hack to reset buffers that change behavior with shaders - gPipeline.resetVertexBuffers(); - - if (gViewerWindow) - { - gViewerWindow->setCursor(UI_CURSOR_WAIT); - } - - // Lighting - gPipeline.setLightingDetail(-1); - - // Shaders - LL_INFOS("ShaderLoading") << "\n~~~~~~~~~~~~~~~~~~\n Loading Shaders:\n~~~~~~~~~~~~~~~~~~" << LL_ENDL; - LL_INFOS("ShaderLoading") << llformat("Using GLSL %d.%d", gGLManager.mGLSLVersionMajor, gGLManager.mGLSLVersionMinor) << LL_ENDL; - - for (S32 i = 0; i < SHADER_COUNT; i++) - { - mShaderLevel[i] = 0; - } - mMaxAvatarShaderLevel = 0; - - LLGLSLShader::sNoFixedFunction = false; - LLVertexBuffer::unbind(); - if (LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") - && (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 10) - && gSavedSettings.getBOOL("VertexShaderEnable")) + //setShaders might be called redundantly by gSavedSettings, so return on reentrance + static bool reentrance = false; + + if (!gPipeline.mInitialized || !sInitialized || reentrance || sSkipReload) + { + return; + } + + LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits, (S32) gSavedSettings.getU32("RenderMaxTextureIndex")), 1); + + //NEVER use more than 16 texture channels (work around for prevalent driver bug) + LLGLSLShader::sIndexedTextureChannels = llmin(LLGLSLShader::sIndexedTextureChannels, 16); + + if (gGLManager.mGLSLVersionMajor < 1 || + (gGLManager.mGLSLVersionMajor == 1 && gGLManager.mGLSLVersionMinor <= 20)) + { //NEVER use indexed texture rendering when GLSL version is 1.20 or earlier + LLGLSLShader::sIndexedTextureChannels = 1; + } + + reentrance = true; + + if (LLRender::sGLCoreProfile) + { + if (!gSavedSettings.getBOOL("VertexShaderEnable")) + { //vertex shaders MUST be enabled to use core profile + gSavedSettings.setBOOL("VertexShaderEnable", TRUE); + } + } + + //setup preprocessor definitions + LLShaderMgr::instance()->mDefinitions["NUM_TEX_UNITS"] = llformat("%d", gGLManager.mNumTextureImageUnits); + + // Make sure the compiled shader map is cleared before we recompile shaders. + mShaderObjects.clear(); + + initAttribsAndUniforms(); + gPipeline.releaseGLBuffers(); + + if (gSavedSettings.getBOOL("VertexShaderEnable")) + { + LLPipeline::sWaterReflections = gGLManager.mHasCubeMap; + LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow"); + LLPipeline::updateRenderDeferred(); + } + else + { + LLPipeline::sRenderGlow = FALSE; + LLPipeline::sWaterReflections = FALSE; + } + + //hack to reset buffers that change behavior with shaders + gPipeline.resetVertexBuffers(); + + if (gViewerWindow) + { + gViewerWindow->setCursor(UI_CURSOR_WAIT); + } + + // Lighting + gPipeline.setLightingDetail(-1); + + // Shaders + LL_INFOS("ShaderLoading") << "\n~~~~~~~~~~~~~~~~~~\n Loading Shaders:\n~~~~~~~~~~~~~~~~~~" << LL_ENDL; + LL_INFOS("ShaderLoading") << llformat("Using GLSL %d.%d", gGLManager.mGLSLVersionMajor, gGLManager.mGLSLVersionMinor) << LL_ENDL; + + for (S32 i = 0; i < SHADER_COUNT; i++) + { + mShaderLevel[i] = 0; + } + mMaxAvatarShaderLevel = 0; + + LLGLSLShader::sNoFixedFunction = false; + LLVertexBuffer::unbind(); + if (LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") + && (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 10) + && gSavedSettings.getBOOL("VertexShaderEnable")) { bool canRenderDeferred = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"); bool hasWindLightShaders = LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"); @@ -472,23 +466,23 @@ void LLViewerShaderMgr::setShaders() bool useRenderDeferred = canRenderDeferred && gSavedSettings.getBOOL("RenderDeferred") && gSavedSettings.getBOOL("RenderAvatarVP"); bool doingWindLight = hasWindLightShaders && gSavedSettings.getBOOL("WindLightUseAtmosShaders"); - //using shaders, disable fixed function - LLGLSLShader::sNoFixedFunction = true; + //using shaders, disable fixed function + LLGLSLShader::sNoFixedFunction = true; - S32 light_class = 2; - S32 env_class = 2; - S32 obj_class = 2; - S32 effect_class = 2; - S32 wl_class = 1; - S32 water_class = 2; - S32 deferred_class = 0; - S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0; + S32 light_class = 2; + S32 env_class = 2; + S32 obj_class = 2; + S32 effect_class = 2; + S32 wl_class = 2; + S32 water_class = 2; + S32 deferred_class = 0; + S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0; - static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false); - if (!use_transform_feedback) - { - transform_class = 0; - } + static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false); + if (!use_transform_feedback) + { + transform_class = 0; + } if (useRenderDeferred) { @@ -517,55 +511,55 @@ void LLViewerShaderMgr::setShaders() wl_class = 2; } - // Trigger a full rebuild of the fallback skybox / cubemap if we've toggled windlight shaders - if (mShaderLevel[SHADER_WINDLIGHT] != wl_class && gSky.mVOSkyp.notNull()) - { - gSky.mVOSkyp->forceSkyUpdate(); - } - - // Load lighting shaders - mShaderLevel[SHADER_LIGHTING] = light_class; - mShaderLevel[SHADER_INTERFACE] = light_class; - mShaderLevel[SHADER_ENVIRONMENT] = env_class; - mShaderLevel[SHADER_WATER] = water_class; - mShaderLevel[SHADER_OBJECT] = obj_class; - mShaderLevel[SHADER_EFFECT] = effect_class; - mShaderLevel[SHADER_WINDLIGHT] = wl_class; - mShaderLevel[SHADER_DEFERRED] = deferred_class; - mShaderLevel[SHADER_TRANSFORM] = transform_class; + // Trigger a full rebuild of the fallback skybox / cubemap if we've toggled windlight shaders + if (mShaderLevel[SHADER_WINDLIGHT] != wl_class && gSky.mVOSkyp.notNull()) + { + gSky.mVOSkyp->forceSkyUpdate(); + } + + // Load lighting shaders + mShaderLevel[SHADER_LIGHTING] = light_class; + mShaderLevel[SHADER_INTERFACE] = light_class; + mShaderLevel[SHADER_ENVIRONMENT] = env_class; + mShaderLevel[SHADER_WATER] = water_class; + mShaderLevel[SHADER_OBJECT] = obj_class; + mShaderLevel[SHADER_EFFECT] = effect_class; + mShaderLevel[SHADER_WINDLIGHT] = wl_class; + mShaderLevel[SHADER_DEFERRED] = deferred_class; + mShaderLevel[SHADER_TRANSFORM] = transform_class; BOOL loaded = loadBasicShaders(); - if (loaded) - { - LL_INFOS() << "Loaded basic shaders." << LL_ENDL; - } - else - { - LL_WARNS() << "Failed to load basic shaders." << LL_ENDL; - llassert(loaded); - } - - if (loaded) - { - gPipeline.mVertexShadersEnabled = TRUE; - gPipeline.mVertexShadersLoaded = 1; - - // Load all shaders to set max levels - loaded = loadShadersEnvironment(); - - if (loaded) - { - LL_INFOS() << "Loaded environment shaders." << LL_ENDL; - } - else - { - LL_WARNS() << "Failed to load environment shaders." << LL_ENDL; - llassert(loaded); - } - - if (loaded) - { - loaded = loadShadersWater(); + if (loaded) + { + LL_INFOS() << "Loaded basic shaders." << LL_ENDL; + } + else + { + LL_WARNS() << "Failed to load basic shaders." << LL_ENDL; + llassert(loaded); + } + + if (loaded) + { + gPipeline.mVertexShadersEnabled = TRUE; + gPipeline.mVertexShadersLoaded = 1; + + // Load all shaders to set max levels + loaded = loadShadersEnvironment(); + + if (loaded) + { + LL_INFOS() << "Loaded environment shaders." << LL_ENDL; + } + else + { + LL_WARNS() << "Failed to load environment shaders." << LL_ENDL; + llassert(loaded); + } + + if (loaded) + { + loaded = loadShadersWater(); if (loaded) { LL_INFOS() << "Loaded water shaders." << LL_ENDL; @@ -575,10 +569,10 @@ void LLViewerShaderMgr::setShaders() LL_WARNS() << "Failed to load water shaders." << LL_ENDL; llassert(loaded); } - } + } - if (loaded) - { + if (loaded) + { loaded = loadShadersWindLight(); if (loaded) { @@ -589,10 +583,10 @@ void LLViewerShaderMgr::setShaders() LL_WARNS() << "Failed to load windlight shaders." << LL_ENDL; llassert(loaded); } - } + } - if (loaded) - { + if (loaded) + { loaded = loadShadersEffects(); if (loaded) { @@ -603,25 +597,25 @@ void LLViewerShaderMgr::setShaders() LL_WARNS() << "Failed to load effects shaders." << LL_ENDL; llassert(loaded); } - } - - if (loaded) - { - loaded = loadShadersInterface(); - if (loaded) - { - LL_INFOS() << "Loaded interface shaders." << LL_ENDL; - } - else - { - LL_WARNS() << "Failed to load interface shaders." << LL_ENDL; - llassert(loaded); - } - } - - if (loaded) - - { + } + + if (loaded) + { + loaded = loadShadersInterface(); + if (loaded) + { + LL_INFOS() << "Loaded interface shaders." << LL_ENDL; + } + else + { + LL_WARNS() << "Failed to load interface shaders." << LL_ENDL; + llassert(loaded); + } + } + + if (loaded) + + { loaded = loadTransformShaders(); if (loaded) { @@ -757,464 +751,461 @@ void LLViewerShaderMgr::setShaders() } gPipeline.createGLBuffers(); - reentrance = false; + reentrance = false; } void LLViewerShaderMgr::unloadShaders() { - gOcclusionProgram.unload(); - gOcclusionCubeProgram.unload(); - gDebugProgram.unload(); - gClipProgram.unload(); - gDownsampleDepthProgram.unload(); - gDownsampleDepthRectProgram.unload(); - gDownsampleMinMaxDepthRectProgram.unload(); - gInscatterRectProgram.unload(); - gBenchmarkProgram.unload(); - gAlphaMaskProgram.unload(); - gUIProgram.unload(); - gPathfindingProgram.unload(); - gPathfindingNoNormalsProgram.unload(); - gCustomAlphaProgram.unload(); - gGlowCombineProgram.unload(); - gSplatTextureRectProgram.unload(); - gGlowCombineFXAAProgram.unload(); - gTwoTextureAddProgram.unload(); - gTwoTextureCompareProgram.unload(); - gOneTextureFilterProgram.unload(); - gOneTextureNoColorProgram.unload(); - gSolidColorProgram.unload(); - - gObjectFullbrightNoColorProgram.unload(); - gObjectFullbrightNoColorWaterProgram.unload(); - gObjectSimpleProgram.unload(); - gObjectSimpleImpostorProgram.unload(); - gObjectPreviewProgram.unload(); - gImpostorProgram.unload(); - gObjectSimpleAlphaMaskProgram.unload(); - gObjectBumpProgram.unload(); - gObjectSimpleWaterProgram.unload(); - gObjectSimpleWaterAlphaMaskProgram.unload(); - gObjectFullbrightProgram.unload(); - gObjectFullbrightWaterProgram.unload(); - gObjectEmissiveProgram.unload(); - gObjectEmissiveWaterProgram.unload(); - gObjectFullbrightAlphaMaskProgram.unload(); - gObjectFullbrightWaterAlphaMaskProgram.unload(); - - gObjectShinyProgram.unload(); - gObjectFullbrightShinyProgram.unload(); - gObjectFullbrightShinyWaterProgram.unload(); - gObjectShinyWaterProgram.unload(); - - gObjectSimpleNonIndexedProgram.unload(); - gObjectSimpleNonIndexedTexGenProgram.unload(); - gObjectSimpleNonIndexedTexGenWaterProgram.unload(); - gObjectSimpleNonIndexedWaterProgram.unload(); - gObjectAlphaMaskNonIndexedProgram.unload(); - gObjectAlphaMaskNonIndexedWaterProgram.unload(); - gObjectAlphaMaskNoColorProgram.unload(); - gObjectAlphaMaskNoColorWaterProgram.unload(); - gObjectFullbrightNonIndexedProgram.unload(); - gObjectFullbrightNonIndexedWaterProgram.unload(); - gObjectEmissiveNonIndexedProgram.unload(); - gObjectEmissiveNonIndexedWaterProgram.unload(); - gTreeProgram.unload(); - gTreeWaterProgram.unload(); - - gObjectShinyNonIndexedProgram.unload(); - gObjectFullbrightShinyNonIndexedProgram.unload(); - gObjectFullbrightShinyNonIndexedWaterProgram.unload(); - gObjectShinyNonIndexedWaterProgram.unload(); - - gSkinnedObjectSimpleProgram.unload(); - gSkinnedObjectFullbrightProgram.unload(); - gSkinnedObjectEmissiveProgram.unload(); - gSkinnedObjectFullbrightShinyProgram.unload(); - gSkinnedObjectShinySimpleProgram.unload(); - - gSkinnedObjectSimpleWaterProgram.unload(); - gSkinnedObjectFullbrightWaterProgram.unload(); - gSkinnedObjectEmissiveWaterProgram.unload(); - gSkinnedObjectFullbrightShinyWaterProgram.unload(); - gSkinnedObjectShinySimpleWaterProgram.unload(); - - - gWaterProgram.unload(); + gOcclusionProgram.unload(); + gOcclusionCubeProgram.unload(); + gDebugProgram.unload(); + gClipProgram.unload(); + gDownsampleDepthProgram.unload(); + gDownsampleDepthRectProgram.unload(); + gBenchmarkProgram.unload(); + gAlphaMaskProgram.unload(); + gUIProgram.unload(); + gPathfindingProgram.unload(); + gPathfindingNoNormalsProgram.unload(); + gCustomAlphaProgram.unload(); + gGlowCombineProgram.unload(); + gSplatTextureRectProgram.unload(); + gGlowCombineFXAAProgram.unload(); + gTwoTextureAddProgram.unload(); + gTwoTextureCompareProgram.unload(); + gOneTextureFilterProgram.unload(); + gOneTextureNoColorProgram.unload(); + gSolidColorProgram.unload(); + + gObjectFullbrightNoColorProgram.unload(); + gObjectFullbrightNoColorWaterProgram.unload(); + gObjectSimpleProgram.unload(); + gObjectSimpleImpostorProgram.unload(); + gObjectPreviewProgram.unload(); + gImpostorProgram.unload(); + gObjectSimpleAlphaMaskProgram.unload(); + gObjectBumpProgram.unload(); + gObjectSimpleWaterProgram.unload(); + gObjectSimpleWaterAlphaMaskProgram.unload(); + gObjectFullbrightProgram.unload(); + gObjectFullbrightWaterProgram.unload(); + gObjectEmissiveProgram.unload(); + gObjectEmissiveWaterProgram.unload(); + gObjectFullbrightAlphaMaskProgram.unload(); + gObjectFullbrightWaterAlphaMaskProgram.unload(); + + gObjectShinyProgram.unload(); + gObjectFullbrightShinyProgram.unload(); + gObjectFullbrightShinyWaterProgram.unload(); + gObjectShinyWaterProgram.unload(); + + gObjectSimpleNonIndexedProgram.unload(); + gObjectSimpleNonIndexedTexGenProgram.unload(); + gObjectSimpleNonIndexedTexGenWaterProgram.unload(); + gObjectSimpleNonIndexedWaterProgram.unload(); + gObjectAlphaMaskNonIndexedProgram.unload(); + gObjectAlphaMaskNonIndexedWaterProgram.unload(); + gObjectAlphaMaskNoColorProgram.unload(); + gObjectAlphaMaskNoColorWaterProgram.unload(); + gObjectFullbrightNonIndexedProgram.unload(); + gObjectFullbrightNonIndexedWaterProgram.unload(); + gObjectEmissiveNonIndexedProgram.unload(); + gObjectEmissiveNonIndexedWaterProgram.unload(); + gTreeProgram.unload(); + gTreeWaterProgram.unload(); + + gObjectShinyNonIndexedProgram.unload(); + gObjectFullbrightShinyNonIndexedProgram.unload(); + gObjectFullbrightShinyNonIndexedWaterProgram.unload(); + gObjectShinyNonIndexedWaterProgram.unload(); + + gSkinnedObjectSimpleProgram.unload(); + gSkinnedObjectFullbrightProgram.unload(); + gSkinnedObjectEmissiveProgram.unload(); + gSkinnedObjectFullbrightShinyProgram.unload(); + gSkinnedObjectShinySimpleProgram.unload(); + + gSkinnedObjectSimpleWaterProgram.unload(); + gSkinnedObjectFullbrightWaterProgram.unload(); + gSkinnedObjectEmissiveWaterProgram.unload(); + gSkinnedObjectFullbrightShinyWaterProgram.unload(); + gSkinnedObjectShinySimpleWaterProgram.unload(); + + + gWaterProgram.unload(); gWaterEdgeProgram.unload(); - gUnderWaterProgram.unload(); - gTerrainProgram.unload(); - gTerrainWaterProgram.unload(); - gGlowProgram.unload(); - gGlowExtractProgram.unload(); - gAvatarProgram.unload(); - gAvatarWaterProgram.unload(); - gAvatarEyeballProgram.unload(); - gAvatarPickProgram.unload(); - gHighlightProgram.unload(); - gHighlightNormalProgram.unload(); - gHighlightSpecularProgram.unload(); - - gWLSkyProgram.unload(); - gWLCloudProgram.unload(); - gWLCloudShadowProgram.unload(); + gUnderWaterProgram.unload(); + gTerrainProgram.unload(); + gTerrainWaterProgram.unload(); + gGlowProgram.unload(); + gGlowExtractProgram.unload(); + gAvatarProgram.unload(); + gAvatarWaterProgram.unload(); + gAvatarEyeballProgram.unload(); + gAvatarPickProgram.unload(); + gHighlightProgram.unload(); + gHighlightNormalProgram.unload(); + gHighlightSpecularProgram.unload(); + + gWLSkyProgram.unload(); + gWLCloudProgram.unload(); gWLSunProgram.unload(); gWLMoonProgram.unload(); - gPostColorFilterProgram.unload(); - gPostNightVisionProgram.unload(); - - gDeferredDiffuseProgram.unload(); - gDeferredDiffuseAlphaMaskProgram.unload(); - gDeferredNonIndexedDiffuseAlphaMaskProgram.unload(); - gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload(); - gDeferredNonIndexedDiffuseProgram.unload(); - gDeferredSkinnedDiffuseProgram.unload(); - gDeferredSkinnedBumpProgram.unload(); - gDeferredSkinnedAlphaProgram.unload(); - - gTransformPositionProgram.unload(); - gTransformTexCoordProgram.unload(); - gTransformNormalProgram.unload(); - gTransformColorProgram.unload(); - gTransformTangentProgram.unload(); - - mShaderLevel[SHADER_LIGHTING] = 0; - mShaderLevel[SHADER_OBJECT] = 0; - mShaderLevel[SHADER_AVATAR] = 0; - mShaderLevel[SHADER_ENVIRONMENT] = 0; - mShaderLevel[SHADER_WATER] = 0; - mShaderLevel[SHADER_INTERFACE] = 0; - mShaderLevel[SHADER_EFFECT] = 0; - mShaderLevel[SHADER_WINDLIGHT] = 0; - mShaderLevel[SHADER_TRANSFORM] = 0; - - gPipeline.mVertexShadersLoaded = 0; + gPostColorFilterProgram.unload(); + gPostNightVisionProgram.unload(); + + gDeferredDiffuseProgram.unload(); + gDeferredDiffuseAlphaMaskProgram.unload(); + gDeferredNonIndexedDiffuseAlphaMaskProgram.unload(); + gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload(); + gDeferredNonIndexedDiffuseProgram.unload(); + gDeferredSkinnedDiffuseProgram.unload(); + gDeferredSkinnedBumpProgram.unload(); + gDeferredSkinnedAlphaProgram.unload(); + + gTransformPositionProgram.unload(); + gTransformTexCoordProgram.unload(); + gTransformNormalProgram.unload(); + gTransformColorProgram.unload(); + gTransformTangentProgram.unload(); + + mShaderLevel[SHADER_LIGHTING] = 0; + mShaderLevel[SHADER_OBJECT] = 0; + mShaderLevel[SHADER_AVATAR] = 0; + mShaderLevel[SHADER_ENVIRONMENT] = 0; + mShaderLevel[SHADER_WATER] = 0; + mShaderLevel[SHADER_INTERFACE] = 0; + mShaderLevel[SHADER_EFFECT] = 0; + mShaderLevel[SHADER_WINDLIGHT] = 0; + mShaderLevel[SHADER_TRANSFORM] = 0; + + gPipeline.mVertexShadersLoaded = 0; } BOOL LLViewerShaderMgr::loadBasicShaders() { - // Load basic dependency shaders first - // All of these have to load for any shaders to function - - S32 sum_lights_class = 3; - - // class one cards will get the lower sum lights - // class zero we're not going to think about - // since a class zero card COULD be a ridiculous new card - // and old cards should have the features masked - if(LLFeatureManager::getInstance()->getGPUClass() == GPU_CLASS_1) - { - sum_lights_class = 2; - } - - // If we have sun and moon only checked, then only sum those lights. - if (gPipeline.getLightingDetail() == 0) - { - sum_lights_class = 1; - } + // Load basic dependency shaders first + // All of these have to load for any shaders to function + + S32 sum_lights_class = 3; + + // class one cards will get the lower sum lights + // class zero we're not going to think about + // since a class zero card COULD be a ridiculous new card + // and old cards should have the features masked + if(LLFeatureManager::getInstance()->getGPUClass() == GPU_CLASS_1) + { + sum_lights_class = 2; + } + + // If we have sun and moon only checked, then only sum those lights. + if (gPipeline.getLightingDetail() == 0) + { + sum_lights_class = 1; + } #if LL_DARWIN - // Work around driver crashes on older Macs when using deferred rendering - // NORSPEC-59 - // - if (gGLManager.mIsMobileGF) - sum_lights_class = 3; + // Work around driver crashes on older Macs when using deferred rendering + // NORSPEC-59 + // + if (gGLManager.mIsMobileGF) + sum_lights_class = 3; #endif - - // Use the feature table to mask out the max light level to use. Also make sure it's at least 1. - S32 max_light_class = gSavedSettings.getS32("RenderShaderLightingMaxLevel"); - sum_lights_class = llclamp(sum_lights_class, 1, max_light_class); - - // Load the Basic Vertex Shaders at the appropriate level. - // (in order of shader function call depth for reference purposes, deepest level first) - - vector< pair<string, S32> > shaders; - shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); - shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); - shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); - shaders.push_back( make_pair( "lighting/lightFuncV.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "lighting/sumLightsV.glsl", sum_lights_class ) ); - shaders.push_back( make_pair( "lighting/lightV.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "lighting/lightFuncSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "lighting/sumLightsSpecularV.glsl", sum_lights_class ) ); - shaders.push_back( make_pair( "lighting/lightSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "windlight/atmosphericsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); - shaders.push_back( make_pair( "avatar/avatarSkinV.glsl", 1 ) ); - shaders.push_back( make_pair( "avatar/objectSkinV.glsl", 1 ) ); - if (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30) - { - shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) ); - } - shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) ); - - boost::unordered_map<std::string, std::string> attribs; - attribs["MAX_JOINTS_PER_MESH_OBJECT"] = - boost::lexical_cast<std::string>(LLSkinningUtil::getMaxJointCount()); - - // We no longer have to bind the shaders to global glhandles, they are automatically added to a map now. - for (U32 i = 0; i < shaders.size(); i++) - { - // Note usage of GL_VERTEX_SHADER_ARB - if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB, &attribs) == 0) - { - LL_SHADER_LOADING_WARNS() << "Failed to load vertex shader " << shaders[i].first << LL_ENDL; - return FALSE; - } - } - - // Load the Basic Fragment Shaders at the appropriate level. - // (in order of shader function call depth for reference purposes, deepest level first) - - shaders.clear(); - S32 ch = 1; - - if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30) - { //use indexed texture rendering for GLSL >= 1.30 - ch = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1); - } - - std::vector<S32> index_channels; - index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsHelpersF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/gammaF.glsl", mShaderLevel[SHADER_WINDLIGHT]) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/transportF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "environment/waterFogF.glsl", mShaderLevel[SHADER_WATER] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "environment/encodeNormF.glsl", mShaderLevel[SHADER_ENVIRONMENT] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "environment/srgbF.glsl", mShaderLevel[SHADER_ENVIRONMENT] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/deferredUtil.glsl", 1) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightWaterNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightWaterAlphaMaskNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightWaterNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightShinyNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightShinyNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightShinyWaterNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightWaterF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightWaterAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightWaterF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightWaterAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightShinyF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + + // Use the feature table to mask out the max light level to use. Also make sure it's at least 1. + S32 max_light_class = gSavedSettings.getS32("RenderShaderLightingMaxLevel"); + sum_lights_class = llclamp(sum_lights_class, 1, max_light_class); + + // Load the Basic Vertex Shaders at the appropriate level. + // (in order of shader function call depth for reference purposes, deepest level first) + + vector< pair<string, S32> > shaders; + shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); + shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); + shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); + shaders.push_back( make_pair( "lighting/lightFuncV.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + shaders.push_back( make_pair( "lighting/sumLightsV.glsl", sum_lights_class ) ); + shaders.push_back( make_pair( "lighting/lightV.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + shaders.push_back( make_pair( "lighting/lightFuncSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + shaders.push_back( make_pair( "lighting/sumLightsSpecularV.glsl", sum_lights_class ) ); + shaders.push_back( make_pair( "lighting/lightSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + shaders.push_back( make_pair( "windlight/atmosphericsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); + shaders.push_back( make_pair( "avatar/avatarSkinV.glsl", 1 ) ); + shaders.push_back( make_pair( "avatar/objectSkinV.glsl", 1 ) ); + if (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30) + { + shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) ); + } + shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) ); + + boost::unordered_map<std::string, std::string> attribs; + attribs["MAX_JOINTS_PER_MESH_OBJECT"] = + boost::lexical_cast<std::string>(LLSkinningUtil::getMaxJointCount()); + + // We no longer have to bind the shaders to global glhandles, they are automatically added to a map now. + for (U32 i = 0; i < shaders.size(); i++) + { + // Note usage of GL_VERTEX_SHADER_ARB + if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB, &attribs) == 0) + { + LL_SHADER_LOADING_WARNS() << "Failed to load vertex shader " << shaders[i].first << LL_ENDL; + return FALSE; + } + } + + // Load the Basic Fragment Shaders at the appropriate level. + // (in order of shader function call depth for reference purposes, deepest level first) + + shaders.clear(); + S32 ch = 1; + + if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30) + { //use indexed texture rendering for GLSL >= 1.30 + ch = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1); + } + + std::vector<S32> index_channels; + index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsHelpersF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/gammaF.glsl", mShaderLevel[SHADER_WINDLIGHT]) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/transportF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "environment/waterFogF.glsl", mShaderLevel[SHADER_WATER] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "environment/encodeNormF.glsl", mShaderLevel[SHADER_ENVIRONMENT] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "environment/srgbF.glsl", mShaderLevel[SHADER_ENVIRONMENT] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/deferredUtil.glsl", 1) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightWaterNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightWaterAlphaMaskNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightWaterNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightShinyNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightShinyNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightShinyWaterNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightWaterF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightWaterAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightWaterF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightWaterAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightShinyF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); + index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); - for (U32 i = 0; i < shaders.size(); i++) - { - // Note usage of GL_FRAGMENT_SHADER_ARB - if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, &attribs, index_channels[i]) == 0) - { - LL_SHADER_LOADING_WARNS() << "Failed to load fragment shader " << shaders[i].first << LL_ENDL; - return FALSE; - } - } - - return TRUE; + for (U32 i = 0; i < shaders.size(); i++) + { + // Note usage of GL_FRAGMENT_SHADER_ARB + if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, &attribs, index_channels[i]) == 0) + { + LL_SHADER_LOADING_WARNS() << "Failed to load fragment shader " << shaders[i].first << LL_ENDL; + return FALSE; + } + } + + return TRUE; } BOOL LLViewerShaderMgr::loadShadersEnvironment() { - BOOL success = TRUE; - - if (mShaderLevel[SHADER_ENVIRONMENT] == 0) - { - gTerrainProgram.unload(); - return TRUE; - } - - if (success) - { - gTerrainProgram.mName = "Terrain Shader"; - gTerrainProgram.mFeatures.calculatesLighting = true; - gTerrainProgram.mFeatures.calculatesAtmospherics = true; - gTerrainProgram.mFeatures.hasAtmospherics = true; - gTerrainProgram.mFeatures.hasTransport = true; - gTerrainProgram.mFeatures.hasGamma = true; - gTerrainProgram.mFeatures.hasSrgb = true; - gTerrainProgram.mFeatures.mIndexedTextureChannels = 0; - gTerrainProgram.mFeatures.disableTextureIndex = true; - gTerrainProgram.mFeatures.hasGamma = true; + BOOL success = TRUE; + + if (mShaderLevel[SHADER_ENVIRONMENT] == 0) + { + gTerrainProgram.unload(); + return TRUE; + } + + if (success) + { + gTerrainProgram.mName = "Terrain Shader"; + gTerrainProgram.mFeatures.calculatesLighting = true; + gTerrainProgram.mFeatures.calculatesAtmospherics = true; + gTerrainProgram.mFeatures.hasAtmospherics = true; + gTerrainProgram.mFeatures.hasTransport = true; + gTerrainProgram.mFeatures.hasGamma = true; + gTerrainProgram.mFeatures.hasSrgb = true; + gTerrainProgram.mFeatures.mIndexedTextureChannels = 0; + gTerrainProgram.mFeatures.disableTextureIndex = true; + gTerrainProgram.mFeatures.hasGamma = true; gTerrainProgram.mShaderFiles.clear(); gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB)); gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainF.glsl", GL_FRAGMENT_SHADER_ARB)); gTerrainProgram.mShaderLevel = mShaderLevel[SHADER_ENVIRONMENT]; success = gTerrainProgram.createShader(NULL, NULL); - llassert(success); - } - - if (!success) - { - mShaderLevel[SHADER_ENVIRONMENT] = 0; - return FALSE; - } - - LLWorld::getInstance()->updateWaterObjects(); - - return TRUE; + llassert(success); + } + + if (!success) + { + mShaderLevel[SHADER_ENVIRONMENT] = 0; + return FALSE; + } + + LLWorld::getInstance()->updateWaterObjects(); + + return TRUE; } BOOL LLViewerShaderMgr::loadShadersWater() { - BOOL success = TRUE; - BOOL terrainWaterSuccess = TRUE; - - if (mShaderLevel[SHADER_WATER] == 0) - { - gWaterProgram.unload(); - gWaterEdgeProgram.unload(); - gUnderWaterProgram.unload(); - gTerrainWaterProgram.unload(); - return TRUE; - } - - if (success) - { - // load water shader - gWaterProgram.mName = "Water Shader"; - gWaterProgram.mFeatures.calculatesAtmospherics = true; - gWaterProgram.mFeatures.hasGamma = true; - gWaterProgram.mFeatures.hasTransport = true; - gWaterProgram.mShaderFiles.clear(); - gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB)); - gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER]; - success = gWaterProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - // load water shader - gWaterEdgeProgram.mName = "Water Edge Shader"; - gWaterEdgeProgram.mFeatures.calculatesAtmospherics = true; - gWaterEdgeProgram.mFeatures.hasGamma = true; - gWaterEdgeProgram.mFeatures.hasTransport = true; - gWaterEdgeProgram.mShaderFiles.clear(); - gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB)); - gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gWaterEdgeProgram.addPermutation("WATER_EDGE", "1"); - gWaterEdgeProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gWaterEdgeProgram.mShaderLevel = mShaderLevel[SHADER_WATER]; - success = gWaterEdgeProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - //load under water vertex shader - gUnderWaterProgram.mName = "Underwater Shader"; - gUnderWaterProgram.mFeatures.calculatesAtmospherics = true; - gUnderWaterProgram.mFeatures.hasWaterFog = true; - gUnderWaterProgram.mShaderFiles.clear(); - gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB)); - gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER]; - gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gUnderWaterProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - //load terrain water shader - gTerrainWaterProgram.mName = "Terrain Water Shader"; - gTerrainWaterProgram.mFeatures.calculatesLighting = true; - gTerrainWaterProgram.mFeatures.calculatesAtmospherics = true; - gTerrainWaterProgram.mFeatures.hasAtmospherics = true; - gTerrainWaterProgram.mFeatures.hasWaterFog = true; - gTerrainWaterProgram.mFeatures.mIndexedTextureChannels = 0; - gTerrainWaterProgram.mFeatures.disableTextureIndex = true; - gTerrainWaterProgram.mShaderFiles.clear(); - gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB)); - gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gTerrainWaterProgram.mShaderLevel = mShaderLevel[SHADER_ENVIRONMENT]; - gTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - terrainWaterSuccess = gTerrainWaterProgram.createShader(NULL, NULL); - llassert(terrainWaterSuccess); - } - - /// Keep track of water shader levels - if (gWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER] - || gUnderWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER]) - { - mShaderLevel[SHADER_WATER] = llmin(gWaterProgram.mShaderLevel, gUnderWaterProgram.mShaderLevel); - } - - if (!success) - { - mShaderLevel[SHADER_WATER] = 0; - return FALSE; - } - - // if we failed to load the terrain water shaders and we need them (using class2 water), - // then drop down to class1 water. - if (mShaderLevel[SHADER_WATER] > 1 && !terrainWaterSuccess) - { - mShaderLevel[SHADER_WATER]--; - return loadShadersWater(); - } - - LLWorld::getInstance()->updateWaterObjects(); - - return TRUE; + BOOL success = TRUE; + BOOL terrainWaterSuccess = TRUE; + + if (mShaderLevel[SHADER_WATER] == 0) + { + gWaterProgram.unload(); + gWaterEdgeProgram.unload(); + gUnderWaterProgram.unload(); + gTerrainWaterProgram.unload(); + return TRUE; + } + + if (success) + { + // load water shader + gWaterProgram.mName = "Water Shader"; + gWaterProgram.mFeatures.calculatesAtmospherics = true; + gWaterProgram.mFeatures.hasGamma = true; + gWaterProgram.mFeatures.hasTransport = true; + gWaterProgram.mShaderFiles.clear(); + gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB)); + gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER]; + success = gWaterProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + // load water shader + gWaterEdgeProgram.mName = "Water Edge Shader"; + gWaterEdgeProgram.mFeatures.calculatesAtmospherics = true; + gWaterEdgeProgram.mFeatures.hasGamma = true; + gWaterEdgeProgram.mFeatures.hasTransport = true; + gWaterEdgeProgram.mShaderFiles.clear(); + gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB)); + gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gWaterEdgeProgram.addPermutation("WATER_EDGE", "1"); + gWaterEdgeProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gWaterEdgeProgram.mShaderLevel = mShaderLevel[SHADER_WATER]; + success = gWaterEdgeProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + //load under water vertex shader + gUnderWaterProgram.mName = "Underwater Shader"; + gUnderWaterProgram.mFeatures.calculatesAtmospherics = true; + gUnderWaterProgram.mFeatures.hasWaterFog = true; + gUnderWaterProgram.mShaderFiles.clear(); + gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB)); + gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER]; + gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gUnderWaterProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + //load terrain water shader + gTerrainWaterProgram.mName = "Terrain Water Shader"; + gTerrainWaterProgram.mFeatures.calculatesLighting = true; + gTerrainWaterProgram.mFeatures.calculatesAtmospherics = true; + gTerrainWaterProgram.mFeatures.hasAtmospherics = true; + gTerrainWaterProgram.mFeatures.hasWaterFog = true; + gTerrainWaterProgram.mFeatures.mIndexedTextureChannels = 0; + gTerrainWaterProgram.mFeatures.disableTextureIndex = true; + gTerrainWaterProgram.mShaderFiles.clear(); + gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB)); + gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gTerrainWaterProgram.mShaderLevel = mShaderLevel[SHADER_ENVIRONMENT]; + gTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + terrainWaterSuccess = gTerrainWaterProgram.createShader(NULL, NULL); + llassert(terrainWaterSuccess); + } + + /// Keep track of water shader levels + if (gWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER] + || gUnderWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER]) + { + mShaderLevel[SHADER_WATER] = llmin(gWaterProgram.mShaderLevel, gUnderWaterProgram.mShaderLevel); + } + + if (!success) + { + mShaderLevel[SHADER_WATER] = 0; + return FALSE; + } + + // if we failed to load the terrain water shaders and we need them (using class2 water), + // then drop down to class1 water. + if (mShaderLevel[SHADER_WATER] > 1 && !terrainWaterSuccess) + { + mShaderLevel[SHADER_WATER]--; + return loadShadersWater(); + } + + LLWorld::getInstance()->updateWaterObjects(); + + return TRUE; } BOOL LLViewerShaderMgr::loadShadersEffects() { - BOOL success = TRUE; - - if (mShaderLevel[SHADER_EFFECT] == 0) - { - gGlowProgram.unload(); - gGlowExtractProgram.unload(); - gPostColorFilterProgram.unload(); - gPostNightVisionProgram.unload(); - return TRUE; - } - - if (success) - { - gGlowProgram.mName = "Glow Shader (Post)"; - gGlowProgram.mShaderFiles.clear(); - gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER_ARB)); - gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER_ARB)); - gGlowProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT]; - success = gGlowProgram.createShader(NULL, NULL); - if (!success) - { - LLPipeline::sRenderGlow = FALSE; - } - } - - if (success) - { - gGlowExtractProgram.mName = "Glow Extract Shader (Post)"; - gGlowExtractProgram.mShaderFiles.clear(); - gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB)); - gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB)); - gGlowExtractProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT]; - success = gGlowExtractProgram.createShader(NULL, NULL); - if (!success) - { - LLPipeline::sRenderGlow = FALSE; - } - } - - return success; + BOOL success = TRUE; + + if (mShaderLevel[SHADER_EFFECT] == 0) + { + gGlowProgram.unload(); + gGlowExtractProgram.unload(); + gPostColorFilterProgram.unload(); + gPostNightVisionProgram.unload(); + return TRUE; + } + + if (success) + { + gGlowProgram.mName = "Glow Shader (Post)"; + gGlowProgram.mShaderFiles.clear(); + gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER_ARB)); + gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER_ARB)); + gGlowProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT]; + success = gGlowProgram.createShader(NULL, NULL); + if (!success) + { + LLPipeline::sRenderGlow = FALSE; + } + } + + if (success) + { + gGlowExtractProgram.mName = "Glow Extract Shader (Post)"; + gGlowExtractProgram.mShaderFiles.clear(); + gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB)); + gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB)); + gGlowExtractProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT]; + success = gGlowExtractProgram.createShader(NULL, NULL); + if (!success) + { + LLPipeline::sRenderGlow = FALSE; + } + } + + return success; } @@ -1222,260 +1213,257 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1; - if (mShaderLevel[SHADER_DEFERRED] == 0) - { - gDeferredTreeProgram.unload(); - gDeferredTreeShadowProgram.unload(); - gDeferredDiffuseProgram.unload(); - gDeferredDiffuseAlphaMaskProgram.unload(); - gDeferredNonIndexedDiffuseAlphaMaskProgram.unload(); - gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload(); - gDeferredNonIndexedDiffuseProgram.unload(); - gDeferredSkinnedDiffuseProgram.unload(); - gDeferredSkinnedBumpProgram.unload(); - gDeferredSkinnedAlphaProgram.unload(); - gDeferredBumpProgram.unload(); - gDeferredImpostorProgram.unload(); - gDeferredTerrainProgram.unload(); - gDeferredTerrainWaterProgram.unload(); - gDeferredLightProgram.unload(); - for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; ++i) - { - gDeferredMultiLightProgram[i].unload(); - } - gDeferredSpotLightProgram.unload(); - gDeferredMultiSpotLightProgram.unload(); - gDeferredSunProgram.unload(); - gDeferredBlurLightProgram.unload(); - gDeferredSoftenProgram.unload(); - gDeferredSoftenWaterProgram.unload(); - gDeferredShadowProgram.unload(); - gDeferredShadowCubeProgram.unload(); - gDeferredShadowAlphaMaskProgram.unload(); - gDeferredAvatarShadowProgram.unload(); - gDeferredAttachmentShadowProgram.unload(); - gDeferredAvatarProgram.unload(); - gDeferredAvatarAlphaProgram.unload(); - gDeferredAlphaProgram.unload(); - gDeferredAlphaWaterProgram.unload(); - gDeferredFullbrightProgram.unload(); - gDeferredFullbrightAlphaMaskProgram.unload(); - gDeferredFullbrightWaterProgram.unload(); - gDeferredFullbrightAlphaMaskWaterProgram.unload(); - gDeferredEmissiveProgram.unload(); - gDeferredAvatarEyesProgram.unload(); - gDeferredPostProgram.unload(); - gDeferredCoFProgram.unload(); - gDeferredDoFCombineProgram.unload(); - gDeferredPostGammaCorrectProgram.unload(); - gFXAAProgram.unload(); - gDeferredWaterProgram.unload(); - gDeferredUnderWaterProgram.unload(); - gDeferredWLSkyProgram.unload(); - gDeferredWLCloudProgram.unload(); - gDeferredWLCloudShadowProgram.unload(); + if (mShaderLevel[SHADER_DEFERRED] == 0) + { + gDeferredTreeProgram.unload(); + gDeferredTreeShadowProgram.unload(); + gDeferredDiffuseProgram.unload(); + gDeferredDiffuseAlphaMaskProgram.unload(); + gDeferredNonIndexedDiffuseAlphaMaskProgram.unload(); + gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload(); + gDeferredNonIndexedDiffuseProgram.unload(); + gDeferredSkinnedDiffuseProgram.unload(); + gDeferredSkinnedBumpProgram.unload(); + gDeferredSkinnedAlphaProgram.unload(); + gDeferredBumpProgram.unload(); + gDeferredImpostorProgram.unload(); + gDeferredTerrainProgram.unload(); + gDeferredTerrainWaterProgram.unload(); + gDeferredLightProgram.unload(); + for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; ++i) + { + gDeferredMultiLightProgram[i].unload(); + } + gDeferredSpotLightProgram.unload(); + gDeferredMultiSpotLightProgram.unload(); + gDeferredSunProgram.unload(); + gDeferredBlurLightProgram.unload(); + gDeferredSoftenProgram.unload(); + gDeferredSoftenWaterProgram.unload(); + gDeferredShadowProgram.unload(); + gDeferredShadowCubeProgram.unload(); + gDeferredShadowAlphaMaskProgram.unload(); + gDeferredAvatarShadowProgram.unload(); + gDeferredAttachmentShadowProgram.unload(); + gDeferredAvatarProgram.unload(); + gDeferredAvatarAlphaProgram.unload(); + gDeferredAlphaProgram.unload(); + gDeferredAlphaWaterProgram.unload(); + gDeferredFullbrightProgram.unload(); + gDeferredFullbrightAlphaMaskProgram.unload(); + gDeferredFullbrightWaterProgram.unload(); + gDeferredFullbrightAlphaMaskWaterProgram.unload(); + gDeferredEmissiveProgram.unload(); + gDeferredAvatarEyesProgram.unload(); + gDeferredPostProgram.unload(); + gDeferredCoFProgram.unload(); + gDeferredDoFCombineProgram.unload(); + gDeferredPostGammaCorrectProgram.unload(); + gFXAAProgram.unload(); + gDeferredWaterProgram.unload(); + gDeferredUnderWaterProgram.unload(); + gDeferredWLSkyProgram.unload(); + gDeferredWLCloudProgram.unload(); gDeferredWLSunProgram.unload(); gDeferredWLMoonProgram.unload(); - gDeferredStarProgram.unload(); - gDeferredFullbrightShinyProgram.unload(); - gDeferredSkinnedFullbrightShinyProgram.unload(); - gDeferredSkinnedFullbrightProgram.unload(); - - gNormalMapGenProgram.unload(); - for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i) - { - gDeferredMaterialProgram[i].unload(); - gDeferredMaterialWaterProgram[i].unload(); - } - return TRUE; - } - - BOOL success = TRUE; - - if (success) - { - gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader"; + gDeferredStarProgram.unload(); + gDeferredFullbrightShinyProgram.unload(); + gDeferredSkinnedFullbrightShinyProgram.unload(); + gDeferredSkinnedFullbrightProgram.unload(); + + gNormalMapGenProgram.unload(); + for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i) + { + gDeferredMaterialProgram[i].unload(); + gDeferredMaterialWaterProgram[i].unload(); + } + return TRUE; + } + + BOOL success = TRUE; + + if (success) + { + gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader"; gDeferredDiffuseProgram.mFeatures.encodesNormal = true; - gDeferredDiffuseProgram.mShaderFiles.clear(); - gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredDiffuseProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - gDeferredDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredDiffuseProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Alpha Mask Shader"; + gDeferredDiffuseProgram.mShaderFiles.clear(); + gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredDiffuseProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + gDeferredDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredDiffuseProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Alpha Mask Shader"; gDeferredDiffuseAlphaMaskProgram.mFeatures.encodesNormal = true; - gDeferredDiffuseAlphaMaskProgram.mShaderFiles.clear(); - gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredDiffuseAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredDiffuseAlphaMaskProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredNonIndexedDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader"; - gDeferredNonIndexedDiffuseAlphaMaskProgram.mFeatures.encodesNormal = true; - gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.clear(); - gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredNonIndexedDiffuseAlphaMaskProgram.createShader(NULL, NULL); + gDeferredDiffuseAlphaMaskProgram.mShaderFiles.clear(); + gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredDiffuseAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredDiffuseAlphaMaskProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredNonIndexedDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader"; + gDeferredNonIndexedDiffuseAlphaMaskProgram.mFeatures.encodesNormal = true; + gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.clear(); + gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredNonIndexedDiffuseAlphaMaskProgram.createShader(NULL, NULL); llassert(success); - } + } - if (success) - { - gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader"; - gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mFeatures.encodesNormal = true; - gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.clear(); - gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseNoColorV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskNoColorF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredNonIndexedDiffuseProgram.mName = "Non Indexed Deferred Diffuse Shader"; + if (success) + { + gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader"; + gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mFeatures.encodesNormal = true; + gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.clear(); + gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseNoColorV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskNoColorF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredNonIndexedDiffuseProgram.mName = "Non Indexed Deferred Diffuse Shader"; + gDeferredNonIndexedDiffuseProgram.mShaderFiles.clear(); gDeferredNonIndexedDiffuseProgram.mFeatures.encodesNormal = true; - gDeferredNonIndexedDiffuseProgram.mShaderFiles.clear(); - gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredNonIndexedDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredNonIndexedDiffuseProgram.createShader(NULL, NULL); + gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredNonIndexedDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredNonIndexedDiffuseProgram.createShader(NULL, NULL); llassert(success); - } - - if (success) - { - gDeferredSkinnedDiffuseProgram.mName = "Deferred Skinned Diffuse Shader"; - gDeferredSkinnedDiffuseProgram.mFeatures.hasObjectSkinning = true; - gDeferredSkinnedDiffuseProgram.mFeatures.encodesNormal = true; - gDeferredSkinnedDiffuseProgram.mShaderFiles.clear(); - gDeferredSkinnedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredSkinnedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredSkinnedDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredSkinnedDiffuseProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredSkinnedBumpProgram.mName = "Deferred Skinned Bump Shader"; - gDeferredSkinnedBumpProgram.mFeatures.hasObjectSkinning = true; + } + + if (success) + { + gDeferredSkinnedDiffuseProgram.mName = "Deferred Skinned Diffuse Shader"; + gDeferredSkinnedDiffuseProgram.mFeatures.hasObjectSkinning = true; + gDeferredSkinnedDiffuseProgram.mFeatures.encodesNormal = true; + gDeferredSkinnedDiffuseProgram.mShaderFiles.clear(); + gDeferredSkinnedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSkinnedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSkinnedDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredSkinnedDiffuseProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredSkinnedBumpProgram.mName = "Deferred Skinned Bump Shader"; + gDeferredSkinnedBumpProgram.mFeatures.hasObjectSkinning = true; gDeferredSkinnedBumpProgram.mFeatures.encodesNormal = true; - gDeferredSkinnedBumpProgram.mShaderFiles.clear(); - gDeferredSkinnedBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredSkinnedBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredSkinnedBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredSkinnedBumpProgram.createShader(NULL, NULL); + gDeferredSkinnedBumpProgram.mShaderFiles.clear(); + gDeferredSkinnedBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSkinnedBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSkinnedBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredSkinnedBumpProgram.createShader(NULL, NULL); llassert(success); - } - - if (success) - { - gDeferredSkinnedAlphaProgram.mName = "Deferred Skinned Alpha Shader"; - gDeferredSkinnedAlphaProgram.mFeatures.hasObjectSkinning = true; - gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = false; - gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = false; - gDeferredSkinnedAlphaProgram.mFeatures.isAlphaLighting = true; - gDeferredSkinnedAlphaProgram.mFeatures.disableTextureIndex = true; - gDeferredSkinnedAlphaProgram.mFeatures.hasSrgb = true; - gDeferredSkinnedAlphaProgram.mFeatures.encodesNormal = true; - gDeferredSkinnedAlphaProgram.mFeatures.calculatesAtmospherics = true; - gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true; - gDeferredSkinnedAlphaProgram.mFeatures.hasTransport = true; - gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = true; - gDeferredSkinnedAlphaProgram.mFeatures.hasShadows = true; + } + + if (success) + { + gDeferredSkinnedAlphaProgram.mName = "Deferred Skinned Alpha Shader"; + gDeferredSkinnedAlphaProgram.mFeatures.hasObjectSkinning = true; + gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = false; + gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = false; + gDeferredSkinnedAlphaProgram.mFeatures.isAlphaLighting = true; + gDeferredSkinnedAlphaProgram.mFeatures.disableTextureIndex = true; + gDeferredSkinnedAlphaProgram.mFeatures.hasSrgb = true; + gDeferredSkinnedAlphaProgram.mFeatures.encodesNormal = true; + gDeferredSkinnedAlphaProgram.mFeatures.calculatesAtmospherics = true; + gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true; + gDeferredSkinnedAlphaProgram.mFeatures.hasTransport = true; + gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = true; + gDeferredSkinnedAlphaProgram.mFeatures.hasShadows = true; - gDeferredSkinnedAlphaProgram.mShaderFiles.clear(); - gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredSkinnedAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - - gDeferredSkinnedAlphaProgram.clearPermutations(); - gDeferredSkinnedAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1"); - gDeferredSkinnedAlphaProgram.addPermutation("HAS_SKIN", "1"); - gDeferredSkinnedAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1"); - if (use_sun_shadow) - { - gDeferredSkinnedAlphaProgram.addPermutation("HAS_SHADOW", "1"); - } - success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL); - llassert(success); - - // Hack to include uniforms for lighting without linking in lighting file - gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = true; - gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = true; - } - - if (success) - { - gDeferredBumpProgram.mName = "Deferred Bump Shader"; - gDeferredBumpProgram.mFeatures.encodesNormal = true; - gDeferredBumpProgram.mShaderFiles.clear(); - gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredBumpProgram.createShader(NULL, NULL); - llassert(success); - } - - gDeferredMaterialProgram[1].mFeatures.hasLighting = false; - gDeferredMaterialProgram[5].mFeatures.hasLighting = false; - gDeferredMaterialProgram[9].mFeatures.hasLighting = false; - gDeferredMaterialProgram[13].mFeatures.hasLighting = false; - gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; - gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; - gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; - gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; - - gDeferredMaterialWaterProgram[1].mFeatures.hasLighting = false; - gDeferredMaterialWaterProgram[5].mFeatures.hasLighting = false; - gDeferredMaterialWaterProgram[9].mFeatures.hasLighting = false; - gDeferredMaterialWaterProgram[13].mFeatures.hasLighting = false; - gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; - gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; - gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; - gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; - - for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i) - { - if (success) - { + gDeferredSkinnedAlphaProgram.mShaderFiles.clear(); + gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSkinnedAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + + gDeferredSkinnedAlphaProgram.clearPermutations(); + gDeferredSkinnedAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1"); + gDeferredSkinnedAlphaProgram.addPermutation("HAS_SKIN", "1"); + gDeferredSkinnedAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1"); + if (use_sun_shadow) + { + gDeferredSkinnedAlphaProgram.addPermutation("HAS_SHADOW", "1"); + } + success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL); + llassert(success); + + // Hack to include uniforms for lighting without linking in lighting file + gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = true; + gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = true; + } + + if (success) + { + gDeferredBumpProgram.mName = "Deferred Bump Shader"; + gDeferredBumpProgram.mFeatures.encodesNormal = true; + gDeferredBumpProgram.mShaderFiles.clear(); + gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredBumpProgram.createShader(NULL, NULL); + llassert(success); + } + + gDeferredMaterialProgram[1].mFeatures.hasLighting = false; + gDeferredMaterialProgram[5].mFeatures.hasLighting = false; + gDeferredMaterialProgram[9].mFeatures.hasLighting = false; + gDeferredMaterialProgram[13].mFeatures.hasLighting = false; + gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; + gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; + gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; + gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; + + gDeferredMaterialWaterProgram[1].mFeatures.hasLighting = false; + gDeferredMaterialWaterProgram[5].mFeatures.hasLighting = false; + gDeferredMaterialWaterProgram[9].mFeatures.hasLighting = false; + gDeferredMaterialWaterProgram[13].mFeatures.hasLighting = false; + gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; + gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; + gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; + gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false; + + for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i) + { + if (success) + { mShaderList.push_back(&gDeferredMaterialProgram[i]); - gDeferredMaterialProgram[i].mName = llformat("Deferred Material Shader %d", i); - - U32 alpha_mode = i & 0x3; + gDeferredMaterialProgram[i].mName = llformat("Deferred Material Shader %d", i); + + U32 alpha_mode = i & 0x3; - gDeferredMaterialProgram[i].mShaderFiles.clear(); - gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredMaterialProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredMaterialProgram[i].mShaderFiles.clear(); + gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredMaterialProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - gDeferredMaterialProgram[i].clearPermutations(); + gDeferredMaterialProgram[i].clearPermutations(); - bool has_normal_map = (i & 0x8) > 0; - bool has_specular_map = (i & 0x4) > 0; + bool has_normal_map = (i & 0x8) > 0; + bool has_specular_map = (i & 0x4) > 0; - if (has_normal_map) - { - gDeferredMaterialProgram[i].addPermutation("HAS_NORMAL_MAP", "1"); - } + if (has_normal_map) + { + gDeferredMaterialProgram[i].addPermutation("HAS_NORMAL_MAP", "1"); + } - if (has_specular_map) - { - gDeferredMaterialProgram[i].addPermutation("HAS_SPECULAR_MAP", "1"); - } + if (has_specular_map) + { + gDeferredMaterialProgram[i].addPermutation("HAS_SPECULAR_MAP", "1"); + } gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); @@ -1501,10 +1489,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = gDeferredMaterialProgram[i].createShader(NULL, NULL); llassert(success); - } + } - if (success) - { + if (success) + { mShaderList.push_back(&gDeferredMaterialWaterProgram[i]); gDeferredMaterialWaterProgram[i].mName = llformat("Deferred Underwater Material Shader %d", i); @@ -1562,136 +1550,135 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = gDeferredMaterialWaterProgram[i].createShader(NULL, NULL);//&mWLUniforms); llassert(success); - } - } - - gDeferredMaterialProgram[1].mFeatures.hasLighting = true; - gDeferredMaterialProgram[5].mFeatures.hasLighting = true; - gDeferredMaterialProgram[9].mFeatures.hasLighting = true; - gDeferredMaterialProgram[13].mFeatures.hasLighting = true; - gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; - gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; - gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; - gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; - - gDeferredMaterialWaterProgram[1].mFeatures.hasLighting = true; - gDeferredMaterialWaterProgram[5].mFeatures.hasLighting = true; - gDeferredMaterialWaterProgram[9].mFeatures.hasLighting = true; - gDeferredMaterialWaterProgram[13].mFeatures.hasLighting = true; - gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; - gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; - gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; - gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; - - - if (success) - { - gDeferredTreeProgram.mName = "Deferred Tree Shader"; - gDeferredTreeProgram.mShaderFiles.clear(); + } + } + + gDeferredMaterialProgram[1].mFeatures.hasLighting = true; + gDeferredMaterialProgram[5].mFeatures.hasLighting = true; + gDeferredMaterialProgram[9].mFeatures.hasLighting = true; + gDeferredMaterialProgram[13].mFeatures.hasLighting = true; + gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; + gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; + gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; + gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; + + gDeferredMaterialWaterProgram[1].mFeatures.hasLighting = true; + gDeferredMaterialWaterProgram[5].mFeatures.hasLighting = true; + gDeferredMaterialWaterProgram[9].mFeatures.hasLighting = true; + gDeferredMaterialWaterProgram[13].mFeatures.hasLighting = true; + gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; + gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; + gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; + gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true; + + + if (success) + { + gDeferredTreeProgram.mName = "Deferred Tree Shader"; + gDeferredTreeProgram.mShaderFiles.clear(); gDeferredTreeProgram.mFeatures.encodesNormal = true; - gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredTreeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredTreeProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredTreeShadowProgram.mName = "Deferred Tree Shadow Shader"; - gDeferredTreeShadowProgram.mShaderFiles.clear(); - gDeferredTreeShadowProgram.mFeatures.isDeferred = true; - gDeferredTreeShadowProgram.mFeatures.hasShadows = true; - gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredTreeShadowProgram.createShader(NULL, NULL); + gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredTreeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredTreeProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredTreeShadowProgram.mName = "Deferred Tree Shadow Shader"; + gDeferredTreeShadowProgram.mShaderFiles.clear(); + gDeferredTreeShadowProgram.mFeatures.isDeferred = true; + gDeferredTreeShadowProgram.mFeatures.hasShadows = true; + gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredTreeShadowProgram.createShader(NULL, NULL); llassert(success); - } - - if (success) - { - gDeferredImpostorProgram.mName = "Deferred Impostor Shader"; - gDeferredImpostorProgram.mFeatures.hasSrgb = true; - gDeferredImpostorProgram.mFeatures.encodesNormal = true; - //gDeferredImpostorProgram.mFeatures.isDeferred = true; - gDeferredImpostorProgram.mShaderFiles.clear(); - gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorV.glsl", GL_VERTEX_SHADER_ARB)); + } + + if (success) + { + gDeferredImpostorProgram.mName = "Deferred Impostor Shader"; + gDeferredImpostorProgram.mFeatures.hasSrgb = true; + gDeferredImpostorProgram.mFeatures.encodesNormal = true; + //gDeferredImpostorProgram.mFeatures.isDeferred = true; + gDeferredImpostorProgram.mShaderFiles.clear(); + gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredImpostorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredImpostorProgram.createShader(NULL, NULL); llassert(success); - } + } - if (success) - { - gDeferredLightProgram.mName = "Deferred Light Shader"; - gDeferredLightProgram.mFeatures.isDeferred = true; - gDeferredLightProgram.mFeatures.hasShadows = true; + if (success) + { + gDeferredLightProgram.mName = "Deferred Light Shader"; + gDeferredLightProgram.mFeatures.isDeferred = true; + gDeferredLightProgram.mFeatures.hasShadows = true; - gDeferredLightProgram.mShaderFiles.clear(); - gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredLightProgram.mShaderFiles.clear(); + gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredLightProgram.createShader(NULL, NULL); + success = gDeferredLightProgram.createShader(NULL, NULL); llassert(success); - } - - for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; i++) - { - if (success) - { - gDeferredMultiLightProgram[i].mName = llformat("Deferred MultiLight Shader %d", i); - gDeferredMultiLightProgram[i].mFeatures.isDeferred = true; - gDeferredMultiLightProgram[i].mFeatures.hasShadows = true; - - gDeferredMultiLightProgram[i].mShaderFiles.clear(); - gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredMultiLightProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - gDeferredMultiLightProgram[i].addPermutation("LIGHT_COUNT", llformat("%d", i+1)); - success = gDeferredMultiLightProgram[i].createShader(NULL, NULL); + } + + for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; i++) + { + if (success) + { + gDeferredMultiLightProgram[i].mName = llformat("Deferred MultiLight Shader %d", i); + gDeferredMultiLightProgram[i].mFeatures.isDeferred = true; + gDeferredMultiLightProgram[i].mFeatures.hasShadows = true; + + gDeferredMultiLightProgram[i].mShaderFiles.clear(); + gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredMultiLightProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredMultiLightProgram[i].addPermutation("LIGHT_COUNT", llformat("%d", i+1)); + success = gDeferredMultiLightProgram[i].createShader(NULL, NULL); llassert(success); - } - } - - if (success) - { - gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader"; - gDeferredSpotLightProgram.mShaderFiles.clear(); - gDeferredSpotLightProgram.mFeatures.hasSrgb = true; - gDeferredSpotLightProgram.mFeatures.isDeferred = true; - gDeferredSpotLightProgram.mFeatures.hasShadows = true; - - gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - - success = gDeferredSpotLightProgram.createShader(NULL, NULL); + } + } + + if (success) + { + gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader"; + gDeferredSpotLightProgram.mShaderFiles.clear(); + gDeferredSpotLightProgram.mFeatures.hasSrgb = true; + gDeferredSpotLightProgram.mFeatures.isDeferred = true; + gDeferredSpotLightProgram.mFeatures.hasShadows = true; + + gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + + success = gDeferredSpotLightProgram.createShader(NULL, NULL); llassert(success); - } + } - if (success) - { - gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader"; - gDeferredMultiSpotLightProgram.mFeatures.hasSrgb = true; - gDeferredMultiSpotLightProgram.mFeatures.isDeferred = true; - gDeferredMultiSpotLightProgram.mFeatures.hasShadows = true; + if (success) + { + gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader"; + gDeferredMultiSpotLightProgram.mFeatures.hasSrgb = true; + gDeferredMultiSpotLightProgram.mFeatures.isDeferred = true; + gDeferredMultiSpotLightProgram.mFeatures.hasShadows = true; - gDeferredMultiSpotLightProgram.mShaderFiles.clear(); - gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredMultiSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredMultiSpotLightProgram.mShaderFiles.clear(); + gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredMultiSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL); + success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL); llassert(success); - } + } - if (success) - { - std::string fragment; - std::string vertex = "deferred/sunLightV.glsl"; + if (success) + { + std::string fragment; + std::string vertex = "deferred/sunLightV.glsl"; bool use_ao = gSavedSettings.getBOOL("RenderDeferredSSAO"); @@ -1713,40 +1700,41 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSunProgram.mFeatures.hasShadows = true; gDeferredSunProgram.mFeatures.hasAmbientOcclusion = use_ao; - gDeferredSunProgram.mShaderFiles.clear(); - gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER_ARB)); - gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB)); - gDeferredSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredSunProgram.mName = "Deferred Sun Shader"; + gDeferredSunProgram.mShaderFiles.clear(); + gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER_ARB)); + gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB)); + gDeferredSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredSunProgram.createShader(NULL, NULL); llassert(success); - } + } - if (success) - { - gDeferredBlurLightProgram.mName = "Deferred Blur Light Shader"; - gDeferredBlurLightProgram.mFeatures.isDeferred = true; + if (success) + { + gDeferredBlurLightProgram.mName = "Deferred Blur Light Shader"; + gDeferredBlurLightProgram.mFeatures.isDeferred = true; - gDeferredBlurLightProgram.mShaderFiles.clear(); - gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredBlurLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredBlurLightProgram.mShaderFiles.clear(); + gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredBlurLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredBlurLightProgram.createShader(NULL, NULL); + success = gDeferredBlurLightProgram.createShader(NULL, NULL); llassert(success); - } - - if (success) - { - gDeferredAlphaProgram.mName = "Deferred Alpha Shader"; - - gDeferredAlphaProgram.mFeatures.calculatesLighting = false; - gDeferredAlphaProgram.mFeatures.hasLighting = false; - gDeferredAlphaProgram.mFeatures.isAlphaLighting = true; - gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels - gDeferredAlphaProgram.mFeatures.hasSrgb = true; - gDeferredAlphaProgram.mFeatures.encodesNormal = true; - gDeferredAlphaProgram.mFeatures.calculatesAtmospherics = true; + } + + if (success) + { + gDeferredAlphaProgram.mName = "Deferred Alpha Shader"; + + gDeferredAlphaProgram.mFeatures.calculatesLighting = false; + gDeferredAlphaProgram.mFeatures.hasLighting = false; + gDeferredAlphaProgram.mFeatures.isAlphaLighting = true; + gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels + gDeferredAlphaProgram.mFeatures.hasSrgb = true; + gDeferredAlphaProgram.mFeatures.encodesNormal = true; + gDeferredAlphaProgram.mFeatures.calculatesAtmospherics = true; gDeferredAlphaProgram.mFeatures.hasAtmospherics = true; gDeferredAlphaProgram.mFeatures.hasGamma = true; gDeferredAlphaProgram.mFeatures.hasTransport = true; @@ -1787,14 +1775,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredAlphaImpostorProgram.mName = "Deferred Alpha Impostor Shader"; - gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = false; - gDeferredAlphaImpostorProgram.mFeatures.hasLighting = false; - gDeferredAlphaImpostorProgram.mFeatures.isAlphaLighting = true; - gDeferredAlphaImpostorProgram.mFeatures.hasSrgb = true; + gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = false; + gDeferredAlphaImpostorProgram.mFeatures.hasLighting = false; + gDeferredAlphaImpostorProgram.mFeatures.isAlphaLighting = true; + gDeferredAlphaImpostorProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of gDeferredAlphaImpostorProgram.mFeatures.hasSrgb = true; gDeferredAlphaImpostorProgram.mFeatures.encodesNormal = true; gDeferredAlphaImpostorProgram.mFeatures.hasShadows = use_sun_shadow; - gDeferredAlphaImpostorProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels if (mShaderLevel[SHADER_DEFERRED] < 1) { gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; @@ -1828,615 +1815,593 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAlphaImpostorProgram.mFeatures.hasLighting = true; } - if (success) - { - gDeferredAlphaWaterProgram.mName = "Deferred Alpha Underwater Shader"; - gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = false; - gDeferredAlphaWaterProgram.mFeatures.hasLighting = false; - gDeferredAlphaWaterProgram.mFeatures.isAlphaLighting = true; - gDeferredAlphaWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels - gDeferredAlphaWaterProgram.mFeatures.hasWaterFog = true; - gDeferredAlphaWaterProgram.mFeatures.hasSrgb = true; - gDeferredAlphaWaterProgram.mFeatures.encodesNormal = true; - gDeferredAlphaWaterProgram.mFeatures.calculatesAtmospherics = true; - gDeferredAlphaWaterProgram.mFeatures.hasAtmospherics = true; - gDeferredAlphaWaterProgram.mFeatures.hasGamma = true; - gDeferredAlphaWaterProgram.mFeatures.hasTransport = true; - gDeferredAlphaWaterProgram.mFeatures.hasShadows = use_sun_shadow; - - if (mShaderLevel[SHADER_DEFERRED] < 1) - { - gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - } - else - { //shave off some texture units for shadow maps - gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1); - } - gDeferredAlphaWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gDeferredAlphaWaterProgram.mShaderFiles.clear(); - gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); - - gDeferredAlphaWaterProgram.clearPermutations(); - gDeferredAlphaWaterProgram.addPermutation("USE_INDEXED_TEX", "1"); - gDeferredAlphaWaterProgram.addPermutation("WATER_FOG", "1"); - gDeferredAlphaWaterProgram.addPermutation("USE_VERTEX_COLOR", "1"); - if (use_sun_shadow) - { - gDeferredAlphaWaterProgram.addPermutation("HAS_SHADOW", "1"); - } + if (success) + { + gDeferredAlphaWaterProgram.mName = "Deferred Alpha Underwater Shader"; + gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = false; + gDeferredAlphaWaterProgram.mFeatures.hasLighting = false; + gDeferredAlphaWaterProgram.mFeatures.isAlphaLighting = true; + gDeferredAlphaWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels + gDeferredAlphaWaterProgram.mFeatures.hasWaterFog = true; + gDeferredAlphaWaterProgram.mFeatures.hasSrgb = true; + gDeferredAlphaWaterProgram.mFeatures.encodesNormal = true; + gDeferredAlphaWaterProgram.mFeatures.calculatesAtmospherics = true; + gDeferredAlphaWaterProgram.mFeatures.hasAtmospherics = true; + gDeferredAlphaWaterProgram.mFeatures.hasGamma = true; + gDeferredAlphaWaterProgram.mFeatures.hasTransport = true; + gDeferredAlphaWaterProgram.mFeatures.hasShadows = use_sun_shadow; + + if (mShaderLevel[SHADER_DEFERRED] < 1) + { + gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + } + else + { //shave off some texture units for shadow maps + gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1); + } + gDeferredAlphaWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gDeferredAlphaWaterProgram.mShaderFiles.clear(); + gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); + + gDeferredAlphaWaterProgram.clearPermutations(); + gDeferredAlphaWaterProgram.addPermutation("USE_INDEXED_TEX", "1"); + gDeferredAlphaWaterProgram.addPermutation("WATER_FOG", "1"); + gDeferredAlphaWaterProgram.addPermutation("USE_VERTEX_COLOR", "1"); + if (use_sun_shadow) + { + gDeferredAlphaWaterProgram.addPermutation("HAS_SHADOW", "1"); + } gDeferredAlphaWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredAlphaWaterProgram.createShader(NULL, NULL); - llassert(success); - - // Hack - gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = true; - gDeferredAlphaWaterProgram.mFeatures.hasLighting = true; - } - - if (success) - { - gDeferredAvatarEyesProgram.mName = "Deferred Avatar Eyes Shader"; - gDeferredAvatarEyesProgram.mFeatures.calculatesAtmospherics = true; - gDeferredAvatarEyesProgram.mFeatures.hasGamma = true; - gDeferredAvatarEyesProgram.mFeatures.hasTransport = true; - gDeferredAvatarEyesProgram.mFeatures.disableTextureIndex = true; - gDeferredAvatarEyesProgram.mFeatures.hasSrgb = true; - gDeferredAvatarEyesProgram.mFeatures.encodesNormal = true; - gDeferredAvatarEyesProgram.mFeatures.hasShadows = true; - - gDeferredAvatarEyesProgram.mShaderFiles.clear(); - gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredAvatarEyesProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredAvatarEyesProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredFullbrightProgram.mName = "Deferred Fullbright Shader"; - gDeferredFullbrightProgram.mFeatures.calculatesAtmospherics = true; - gDeferredFullbrightProgram.mFeatures.hasGamma = true; - gDeferredFullbrightProgram.mFeatures.hasTransport = true; - gDeferredFullbrightProgram.mFeatures.hasSrgb = true; - - gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - gDeferredFullbrightProgram.mShaderFiles.clear(); - gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredFullbrightProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredFullbrightAlphaMaskProgram.mName = "Deferred Fullbright Alpha Masking Shader"; - gDeferredFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true; - gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true; - gDeferredFullbrightAlphaMaskProgram.mFeatures.hasTransport = true; - gDeferredFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true; - - gDeferredFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - gDeferredFullbrightAlphaMaskProgram.mShaderFiles.clear(); - gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK","1"); - gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredFullbrightWaterProgram.mName = "Deferred Fullbright Underwater Shader"; - gDeferredFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true; - gDeferredFullbrightWaterProgram.mFeatures.hasGamma = true; - gDeferredFullbrightWaterProgram.mFeatures.hasTransport = true; - gDeferredFullbrightWaterProgram.mFeatures.hasWaterFog = true; - gDeferredFullbrightWaterProgram.mFeatures.hasSrgb = true; - gDeferredFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - gDeferredFullbrightWaterProgram.mShaderFiles.clear(); - gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - gDeferredFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gDeferredFullbrightWaterProgram.addPermutation("WATER_FOG","1"); - success = gDeferredFullbrightWaterProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredFullbrightAlphaMaskWaterProgram.mName = "Deferred Fullbright Underwater Alpha Masking Shader"; - gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.calculatesAtmospherics = true; - gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasGamma = true; - gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasTransport = true; - gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasWaterFog = true; - gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasSrgb = true; - gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.clear(); - gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredFullbrightAlphaMaskWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - gDeferredFullbrightAlphaMaskWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("HAS_ALPHA_MASK","1"); - gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("WATER_FOG","1"); - success = gDeferredFullbrightAlphaMaskWaterProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredFullbrightShinyProgram.mName = "Deferred FullbrightShiny Shader"; - gDeferredFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; - gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true; - gDeferredFullbrightShinyProgram.mFeatures.hasTransport = true; - gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels-1; - gDeferredFullbrightShinyProgram.mShaderFiles.clear(); - gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredFullbrightShinyProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredSkinnedFullbrightProgram.mName = "Skinned Fullbright Shader"; - gDeferredSkinnedFullbrightProgram.mFeatures.calculatesAtmospherics = true; - gDeferredSkinnedFullbrightProgram.mFeatures.hasGamma = true; - gDeferredSkinnedFullbrightProgram.mFeatures.hasTransport = true; - gDeferredSkinnedFullbrightProgram.mFeatures.hasObjectSkinning = true; - gDeferredSkinnedFullbrightProgram.mFeatures.disableTextureIndex = true; - gDeferredSkinnedFullbrightProgram.mFeatures.hasSrgb = true; - gDeferredSkinnedFullbrightProgram.mShaderFiles.clear(); - gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredSkinnedFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gDeferredSkinnedFullbrightProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredSkinnedFullbrightShinyProgram.mName = "Skinned Fullbright Shiny Shader"; - gDeferredSkinnedFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; - gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasGamma = true; - gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasTransport = true; - gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasObjectSkinning = true; - gDeferredSkinnedFullbrightShinyProgram.mFeatures.disableTextureIndex = true; - gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.clear(); - gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredSkinnedFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gDeferredSkinnedFullbrightShinyProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredEmissiveProgram.mName = "Deferred Emissive Shader"; - gDeferredEmissiveProgram.mFeatures.calculatesAtmospherics = true; - gDeferredEmissiveProgram.mFeatures.hasGamma = true; - gDeferredEmissiveProgram.mFeatures.hasTransport = true; - gDeferredEmissiveProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - gDeferredEmissiveProgram.mShaderFiles.clear(); - gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredEmissiveProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - // load water shader - gDeferredWaterProgram.mName = "Deferred Water Shader"; - gDeferredWaterProgram.mFeatures.calculatesAtmospherics = true; - gDeferredWaterProgram.mFeatures.hasGamma = true; - gDeferredWaterProgram.mFeatures.hasTransport = true; - gDeferredWaterProgram.mFeatures.encodesNormal = true; - //gDeferredWaterProgram.mFeatures.hasShadows = true; - - gDeferredWaterProgram.mShaderFiles.clear(); - gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - gDeferredWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gDeferredWaterProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - // load water shader - gDeferredUnderWaterProgram.mName = "Deferred Under Water Shader"; - gDeferredUnderWaterProgram.mFeatures.calculatesAtmospherics = true; - gDeferredUnderWaterProgram.mFeatures.hasWaterFog = true; - gDeferredUnderWaterProgram.mFeatures.hasGamma = true; - gDeferredUnderWaterProgram.mFeatures.hasTransport = true; - gDeferredUnderWaterProgram.mFeatures.hasSrgb = true; - gDeferredUnderWaterProgram.mFeatures.encodesNormal = true; - //gDeferredUnderWaterProgram.mFeatures.hasShadows = true; - - gDeferredUnderWaterProgram.mShaderFiles.clear(); - gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredUnderWaterProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredSoftenProgram.mName = "Deferred Soften Shader"; - gDeferredSoftenProgram.mShaderFiles.clear(); - gDeferredSoftenProgram.mFeatures.hasSrgb = true; - gDeferredSoftenProgram.mFeatures.calculatesAtmospherics = true; - gDeferredSoftenProgram.mFeatures.hasAtmospherics = true; - gDeferredSoftenProgram.mFeatures.hasTransport = true; - gDeferredSoftenProgram.mFeatures.hasGamma = true; - gDeferredSoftenProgram.mFeatures.isDeferred = true; - gDeferredSoftenProgram.mFeatures.hasShadows = true; - - gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB)); - - gDeferredSoftenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - - if (gSavedSettings.getBOOL("RenderDeferredSSAO")) - { //if using SSAO, take screen space light map into account as if shadows are enabled - gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2); - } - - success = gDeferredSoftenProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredSoftenWaterProgram.mName = "Deferred Soften Underwater Shader"; - gDeferredSoftenWaterProgram.mShaderFiles.clear(); - gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB)); - - gDeferredSoftenWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - - gDeferredSoftenWaterProgram.addPermutation("WATER_FOG", "1"); - gDeferredSoftenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gDeferredSoftenWaterProgram.mFeatures.hasWaterFog = true; - gDeferredSoftenWaterProgram.mFeatures.hasSrgb = true; - gDeferredSoftenWaterProgram.mFeatures.calculatesAtmospherics = true; - gDeferredSoftenWaterProgram.mFeatures.hasAtmospherics = true; - gDeferredSoftenWaterProgram.mFeatures.hasTransport = true; - gDeferredSoftenWaterProgram.mFeatures.hasGamma = true; + success = gDeferredAlphaWaterProgram.createShader(NULL, NULL); + llassert(success); + + // Hack + gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = true; + gDeferredAlphaWaterProgram.mFeatures.hasLighting = true; + } + + if (success) + { + gDeferredAvatarEyesProgram.mName = "Deferred Avatar Eyes Shader"; + gDeferredAvatarEyesProgram.mFeatures.calculatesAtmospherics = true; + gDeferredAvatarEyesProgram.mFeatures.hasGamma = true; + gDeferredAvatarEyesProgram.mFeatures.hasTransport = true; + gDeferredAvatarEyesProgram.mFeatures.disableTextureIndex = true; + gDeferredAvatarEyesProgram.mFeatures.hasSrgb = true; + gDeferredAvatarEyesProgram.mFeatures.encodesNormal = true; + gDeferredAvatarEyesProgram.mFeatures.hasShadows = true; + + gDeferredAvatarEyesProgram.mShaderFiles.clear(); + gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredAvatarEyesProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredAvatarEyesProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredFullbrightProgram.mName = "Deferred Fullbright Shader"; + gDeferredFullbrightProgram.mFeatures.calculatesAtmospherics = true; + gDeferredFullbrightProgram.mFeatures.hasGamma = true; + gDeferredFullbrightProgram.mFeatures.hasTransport = true; + gDeferredFullbrightProgram.mFeatures.hasSrgb = true; + gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + gDeferredFullbrightProgram.mShaderFiles.clear(); + gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredFullbrightProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredFullbrightAlphaMaskProgram.mName = "Deferred Fullbright Alpha Masking Shader"; + gDeferredFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true; + gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true; + gDeferredFullbrightAlphaMaskProgram.mFeatures.hasTransport = true; + gDeferredFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true; + gDeferredFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + gDeferredFullbrightAlphaMaskProgram.mShaderFiles.clear(); + gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK","1"); + gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredFullbrightWaterProgram.mName = "Deferred Fullbright Underwater Shader"; + gDeferredFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true; + gDeferredFullbrightWaterProgram.mFeatures.hasGamma = true; + gDeferredFullbrightWaterProgram.mFeatures.hasTransport = true; + gDeferredFullbrightWaterProgram.mFeatures.hasWaterFog = true; + gDeferredFullbrightWaterProgram.mFeatures.hasSrgb = true; + gDeferredFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + gDeferredFullbrightWaterProgram.mShaderFiles.clear(); + gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gDeferredFullbrightWaterProgram.addPermutation("WATER_FOG","1"); + success = gDeferredFullbrightWaterProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredFullbrightAlphaMaskWaterProgram.mName = "Deferred Fullbright Underwater Alpha Masking Shader"; + gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.calculatesAtmospherics = true; + gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasGamma = true; + gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasTransport = true; + gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasWaterFog = true; + gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasSrgb = true; + gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.clear(); + gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredFullbrightAlphaMaskWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredFullbrightAlphaMaskWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("HAS_ALPHA_MASK","1"); + gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("WATER_FOG","1"); + success = gDeferredFullbrightAlphaMaskWaterProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredFullbrightShinyProgram.mName = "Deferred FullbrightShiny Shader"; + gDeferredFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; + gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true; + gDeferredFullbrightShinyProgram.mFeatures.hasTransport = true; + gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels-1; + gDeferredFullbrightShinyProgram.mShaderFiles.clear(); + gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredFullbrightShinyProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredSkinnedFullbrightProgram.mName = "Skinned Fullbright Shader"; + gDeferredSkinnedFullbrightProgram.mFeatures.calculatesAtmospherics = true; + gDeferredSkinnedFullbrightProgram.mFeatures.hasGamma = true; + gDeferredSkinnedFullbrightProgram.mFeatures.hasTransport = true; + gDeferredSkinnedFullbrightProgram.mFeatures.hasObjectSkinning = true; + gDeferredSkinnedFullbrightProgram.mFeatures.disableTextureIndex = true; + gDeferredSkinnedFullbrightProgram.mFeatures.hasSrgb = true; + gDeferredSkinnedFullbrightProgram.mShaderFiles.clear(); + gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSkinnedFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gDeferredSkinnedFullbrightProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredSkinnedFullbrightShinyProgram.mName = "Skinned Fullbright Shiny Shader"; + gDeferredSkinnedFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; + gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasGamma = true; + gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasTransport = true; + gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasObjectSkinning = true; + gDeferredSkinnedFullbrightShinyProgram.mFeatures.disableTextureIndex = true; + gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.clear(); + gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSkinnedFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gDeferredSkinnedFullbrightShinyProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredEmissiveProgram.mName = "Deferred Emissive Shader"; + gDeferredEmissiveProgram.mFeatures.calculatesAtmospherics = true; + gDeferredEmissiveProgram.mFeatures.hasGamma = true; + gDeferredEmissiveProgram.mFeatures.hasTransport = true; + gDeferredEmissiveProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + gDeferredEmissiveProgram.mShaderFiles.clear(); + gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredEmissiveProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + // load water shader + gDeferredWaterProgram.mName = "Deferred Water Shader"; + gDeferredWaterProgram.mFeatures.calculatesAtmospherics = true; + gDeferredWaterProgram.mFeatures.hasGamma = true; + gDeferredWaterProgram.mFeatures.hasTransport = true; + gDeferredWaterProgram.mFeatures.encodesNormal = true; + //gDeferredWaterProgram.mFeatures.hasShadows = true; + + gDeferredWaterProgram.mShaderFiles.clear(); + gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gDeferredWaterProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + // load water shader + gDeferredUnderWaterProgram.mName = "Deferred Under Water Shader"; + gDeferredUnderWaterProgram.mFeatures.calculatesAtmospherics = true; + gDeferredUnderWaterProgram.mFeatures.hasWaterFog = true; + gDeferredUnderWaterProgram.mFeatures.hasGamma = true; + gDeferredUnderWaterProgram.mFeatures.hasTransport = true; + gDeferredUnderWaterProgram.mFeatures.hasSrgb = true; + gDeferredUnderWaterProgram.mFeatures.encodesNormal = true; + //gDeferredUnderWaterProgram.mFeatures.hasShadows = true; + + gDeferredUnderWaterProgram.mShaderFiles.clear(); + gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredUnderWaterProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredSoftenProgram.mName = "Deferred Soften Shader"; + gDeferredSoftenProgram.mShaderFiles.clear(); + gDeferredSoftenProgram.mFeatures.hasSrgb = true; + gDeferredSoftenProgram.mFeatures.calculatesAtmospherics = true; + gDeferredSoftenProgram.mFeatures.hasAtmospherics = true; + gDeferredSoftenProgram.mFeatures.hasTransport = true; + gDeferredSoftenProgram.mFeatures.hasGamma = true; + gDeferredSoftenProgram.mFeatures.isDeferred = true; + gDeferredSoftenProgram.mFeatures.hasShadows = true; + + gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + + gDeferredSoftenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + + if (gSavedSettings.getBOOL("RenderDeferredSSAO")) + { //if using SSAO, take screen space light map into account as if shadows are enabled + gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2); + } + + success = gDeferredSoftenProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredSoftenWaterProgram.mName = "Deferred Soften Underwater Shader"; + gDeferredSoftenWaterProgram.mShaderFiles.clear(); + gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + + gDeferredSoftenWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredSoftenWaterProgram.addPermutation("WATER_FOG", "1"); + gDeferredSoftenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gDeferredSoftenWaterProgram.mFeatures.hasWaterFog = true; + gDeferredSoftenWaterProgram.mFeatures.hasSrgb = true; + gDeferredSoftenWaterProgram.mFeatures.calculatesAtmospherics = true; + gDeferredSoftenWaterProgram.mFeatures.hasAtmospherics = true; + gDeferredSoftenWaterProgram.mFeatures.hasTransport = true; + gDeferredSoftenWaterProgram.mFeatures.hasGamma = true; gDeferredSoftenWaterProgram.mFeatures.isDeferred = true; gDeferredSoftenWaterProgram.mFeatures.hasShadows = true; - if (gSavedSettings.getBOOL("RenderDeferredSSAO")) - { //if using SSAO, take screen space light map into account as if shadows are enabled - gDeferredSoftenWaterProgram.mShaderLevel = llmax(gDeferredSoftenWaterProgram.mShaderLevel, 2); - } - - success = gDeferredSoftenWaterProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredShadowProgram.mName = "Deferred Shadow Shader"; - gDeferredShadowProgram.mFeatures.isDeferred = true; - gDeferredShadowProgram.mFeatures.hasShadows = true; - gDeferredShadowProgram.mShaderFiles.clear(); - gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - if (gGLManager.mHasDepthClamp) - { - gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", "1"); - } - success = gDeferredShadowProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredShadowCubeProgram.mName = "Deferred Shadow Cube Shader"; - gDeferredShadowCubeProgram.mFeatures.isDeferred = true; - gDeferredShadowCubeProgram.mFeatures.hasShadows = true; - gDeferredShadowCubeProgram.mShaderFiles.clear(); - gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB)); - if (gGLManager.mHasDepthClamp) - { - gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1"); - } - gDeferredShadowCubeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredShadowCubeProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader"; - gDeferredShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; - - gDeferredShadowAlphaMaskProgram.mShaderFiles.clear(); - gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB)); - if (gGLManager.mHasDepthClamp) - { - gDeferredShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); - } - gDeferredShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredAvatarShadowProgram.mName = "Deferred Avatar Shadow Shader"; - gDeferredAvatarShadowProgram.mFeatures.hasSkinning = true; - - gDeferredAvatarShadowProgram.mShaderFiles.clear(); - gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); - if (gGLManager.mHasDepthClamp) - { - gDeferredAvatarShadowProgram.addPermutation("DEPTH_CLAMP", "1"); - } - gDeferredAvatarShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredAvatarShadowProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredAttachmentShadowProgram.mName = "Deferred Attachment Shadow Shader"; - gDeferredAttachmentShadowProgram.mFeatures.hasObjectSkinning = true; - - gDeferredAttachmentShadowProgram.mShaderFiles.clear(); - gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); - if (gGLManager.mHasDepthClamp) - { - gDeferredAttachmentShadowProgram.addPermutation("DEPTH_CLAMP", "1"); - } - gDeferredAttachmentShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredAttachmentShadowProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredTerrainProgram.mName = "Deferred Terrain Shader"; - gDeferredTerrainProgram.mFeatures.encodesNormal = true; - gDeferredTerrainProgram.mFeatures.hasSrgb = true; - gDeferredTerrainProgram.mFeatures.calculatesLighting = false; - gDeferredTerrainProgram.mFeatures.hasLighting = false; - gDeferredTerrainProgram.mFeatures.isAlphaLighting = true; - gDeferredTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels - gDeferredTerrainProgram.mFeatures.hasWaterFog = true; - gDeferredTerrainProgram.mFeatures.calculatesAtmospherics = true; - gDeferredTerrainProgram.mFeatures.hasAtmospherics = true; - gDeferredTerrainProgram.mFeatures.hasGamma = true; - gDeferredTerrainProgram.mFeatures.hasTransport = true; - - gDeferredTerrainProgram.mShaderFiles.clear(); - gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + if (gSavedSettings.getBOOL("RenderDeferredSSAO")) + { //if using SSAO, take screen space light map into account as if shadows are enabled + gDeferredSoftenWaterProgram.mShaderLevel = llmax(gDeferredSoftenWaterProgram.mShaderLevel, 2); + } + + success = gDeferredSoftenWaterProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredShadowProgram.mName = "Deferred Shadow Shader"; + gDeferredShadowProgram.mFeatures.isDeferred = true; + gDeferredShadowProgram.mFeatures.hasShadows = true; + gDeferredShadowProgram.mShaderFiles.clear(); + gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + if (gGLManager.mHasDepthClamp) + { + gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", "1"); + } + success = gDeferredShadowProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredShadowCubeProgram.mName = "Deferred Shadow Cube Shader"; + gDeferredShadowCubeProgram.mFeatures.isDeferred = true; + gDeferredShadowCubeProgram.mFeatures.hasShadows = true; + gDeferredShadowCubeProgram.mShaderFiles.clear(); + gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB)); + if (gGLManager.mHasDepthClamp) + { + gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1"); + } + gDeferredShadowCubeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredShadowCubeProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader"; + gDeferredShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + + gDeferredShadowAlphaMaskProgram.mShaderFiles.clear(); + gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB)); + if (gGLManager.mHasDepthClamp) + { + gDeferredShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); + } + gDeferredShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredAvatarShadowProgram.mName = "Deferred Avatar Shadow Shader"; + gDeferredAvatarShadowProgram.mFeatures.hasSkinning = true; + + gDeferredAvatarShadowProgram.mShaderFiles.clear(); + gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); + if (gGLManager.mHasDepthClamp) + { + gDeferredAvatarShadowProgram.addPermutation("DEPTH_CLAMP", "1"); + } + gDeferredAvatarShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredAvatarShadowProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredAttachmentShadowProgram.mName = "Deferred Attachment Shadow Shader"; + gDeferredAttachmentShadowProgram.mFeatures.hasObjectSkinning = true; + + gDeferredAttachmentShadowProgram.mShaderFiles.clear(); + gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); + if (gGLManager.mHasDepthClamp) + { + gDeferredAttachmentShadowProgram.addPermutation("DEPTH_CLAMP", "1"); + } + gDeferredAttachmentShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredAttachmentShadowProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredTerrainProgram.mName = "Deferred Terrain Shader"; + gDeferredTerrainProgram.mFeatures.encodesNormal = true; + gDeferredTerrainProgram.mFeatures.hasSrgb = true; + gDeferredTerrainProgram.mFeatures.calculatesLighting = false; + gDeferredTerrainProgram.mFeatures.hasLighting = false; + gDeferredTerrainProgram.mFeatures.isAlphaLighting = true; + gDeferredTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels + gDeferredTerrainProgram.mFeatures.hasWaterFog = true; + gDeferredTerrainProgram.mFeatures.calculatesAtmospherics = true; + gDeferredTerrainProgram.mFeatures.hasAtmospherics = true; + gDeferredTerrainProgram.mFeatures.hasGamma = true; + gDeferredTerrainProgram.mFeatures.hasTransport = true; + + gDeferredTerrainProgram.mShaderFiles.clear(); + gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredTerrainProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredTerrainWaterProgram.mName = "Deferred Terrain Underwater Shader"; - gDeferredTerrainWaterProgram.mFeatures.encodesNormal = true; - gDeferredTerrainWaterProgram.mFeatures.hasSrgb = true; - gDeferredTerrainWaterProgram.mFeatures.calculatesLighting = false; - gDeferredTerrainWaterProgram.mFeatures.hasLighting = false; - gDeferredTerrainWaterProgram.mFeatures.isAlphaLighting = true; - gDeferredTerrainWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels - gDeferredTerrainWaterProgram.mFeatures.hasWaterFog = true; - gDeferredTerrainWaterProgram.mFeatures.calculatesAtmospherics = true; - gDeferredTerrainWaterProgram.mFeatures.hasAtmospherics = true; - gDeferredTerrainWaterProgram.mFeatures.hasGamma = true; - gDeferredTerrainWaterProgram.mFeatures.hasTransport = true; - - gDeferredTerrainWaterProgram.mShaderFiles.clear(); - gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredTerrainWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - gDeferredTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gDeferredTerrainWaterProgram.addPermutation("WATER_FOG", "1"); - success = gDeferredTerrainWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gDeferredAvatarProgram.mName = "Avatar Shader"; - gDeferredAvatarProgram.mFeatures.hasSkinning = true; - gDeferredAvatarProgram.mFeatures.encodesNormal = true; - gDeferredAvatarProgram.mShaderFiles.clear(); - gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredAvatarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredAvatarProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredAvatarAlphaProgram.mName = "Avatar Alpha Shader"; - gDeferredAvatarAlphaProgram.mFeatures.hasSkinning = true; - gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = false; - gDeferredAvatarAlphaProgram.mFeatures.hasLighting = false; - gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true; - gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true; - gDeferredAvatarAlphaProgram.mFeatures.hasSrgb = true; - gDeferredAvatarAlphaProgram.mFeatures.encodesNormal = true; - gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true; - gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true; - gDeferredAvatarAlphaProgram.mFeatures.hasTransport = true; + llassert(success); + } + + if (success) + { + gDeferredTerrainWaterProgram.mName = "Deferred Terrain Underwater Shader"; + gDeferredTerrainWaterProgram.mFeatures.encodesNormal = true; + gDeferredTerrainWaterProgram.mFeatures.hasSrgb = true; + gDeferredTerrainWaterProgram.mFeatures.calculatesLighting = false; + gDeferredTerrainWaterProgram.mFeatures.hasLighting = false; + gDeferredTerrainWaterProgram.mFeatures.isAlphaLighting = true; + gDeferredTerrainWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels + gDeferredTerrainWaterProgram.mFeatures.hasWaterFog = true; + gDeferredTerrainWaterProgram.mFeatures.calculatesAtmospherics = true; + gDeferredTerrainWaterProgram.mFeatures.hasAtmospherics = true; + gDeferredTerrainWaterProgram.mFeatures.hasGamma = true; + gDeferredTerrainWaterProgram.mFeatures.hasTransport = true; + + gDeferredTerrainWaterProgram.mShaderFiles.clear(); + gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredTerrainWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gDeferredTerrainWaterProgram.addPermutation("WATER_FOG", "1"); + success = gDeferredTerrainWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredAvatarProgram.mName = "Avatar Shader"; + gDeferredAvatarProgram.mFeatures.hasSkinning = true; + gDeferredAvatarProgram.mFeatures.encodesNormal = true; + gDeferredAvatarProgram.mShaderFiles.clear(); + gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredAvatarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredAvatarProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredAvatarAlphaProgram.mName = "Avatar Alpha Shader"; + gDeferredAvatarAlphaProgram.mFeatures.hasSkinning = true; + gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = false; + gDeferredAvatarAlphaProgram.mFeatures.hasLighting = false; + gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true; + gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true; + gDeferredAvatarAlphaProgram.mFeatures.hasSrgb = true; + gDeferredAvatarAlphaProgram.mFeatures.encodesNormal = true; + gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true; + gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true; + gDeferredAvatarAlphaProgram.mFeatures.hasTransport = true; gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true; gDeferredAvatarAlphaProgram.mFeatures.isDeferred = true; - gDeferredAvatarAlphaProgram.mFeatures.hasShadows = true; + gDeferredAvatarAlphaProgram.mFeatures.hasShadows = true; - gDeferredAvatarAlphaProgram.mShaderFiles.clear(); + gDeferredAvatarAlphaProgram.mShaderFiles.clear(); gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredAvatarAlphaProgram.clearPermutations(); - gDeferredAvatarAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1"); - gDeferredAvatarAlphaProgram.addPermutation("IS_AVATAR_SKIN", "1"); - if (use_sun_shadow) - { - gDeferredAvatarAlphaProgram.addPermutation("HAS_SHADOW", "1"); - } - gDeferredAvatarAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - - success = gDeferredAvatarAlphaProgram.createShader(NULL, NULL); - llassert(success); - - gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true; - gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true; - } - - if (success) - { - gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process"; - gDeferredPostGammaCorrectProgram.mFeatures.hasSrgb = true; - gDeferredPostGammaCorrectProgram.mFeatures.isDeferred = true; - gDeferredPostGammaCorrectProgram.mShaderFiles.clear(); - gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredAvatarAlphaProgram.clearPermutations(); + gDeferredAvatarAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1"); + gDeferredAvatarAlphaProgram.addPermutation("IS_AVATAR_SKIN", "1"); + if (use_sun_shadow) + { + gDeferredAvatarAlphaProgram.addPermutation("HAS_SHADOW", "1"); + } + gDeferredAvatarAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + + success = gDeferredAvatarAlphaProgram.createShader(NULL, NULL); + llassert(success); + + gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true; + gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true; + } + + if (success) + { + gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process"; + gDeferredPostGammaCorrectProgram.mFeatures.hasSrgb = true; + gDeferredPostGammaCorrectProgram.mFeatures.isDeferred = true; + gDeferredPostGammaCorrectProgram.mShaderFiles.clear(); + gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredPostGammaCorrectProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gFXAAProgram.mName = "FXAA Shader"; - gFXAAProgram.mFeatures.isDeferred = true; - gFXAAProgram.mShaderFiles.clear(); - gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); - gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/fxaaF.glsl", GL_FRAGMENT_SHADER_ARB)); - gFXAAProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gFXAAProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredPostProgram.mName = "Deferred Post Shader"; - gFXAAProgram.mFeatures.isDeferred = true; - gDeferredPostProgram.mShaderFiles.clear(); - gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredPostProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredPostProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredCoFProgram.mName = "Deferred CoF Shader"; - gDeferredCoFProgram.mShaderFiles.clear(); - gDeferredCoFProgram.mFeatures.isDeferred = true; - gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/cofF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredCoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredCoFProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredDoFCombineProgram.mName = "Deferred DoFCombine Shader"; - gDeferredDoFCombineProgram.mFeatures.isDeferred = true; - gDeferredDoFCombineProgram.mShaderFiles.clear(); - gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/dofCombineF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredDoFCombineProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredDoFCombineProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredPostNoDoFProgram.mName = "Deferred Post Shader"; - gDeferredPostNoDoFProgram.mFeatures.isDeferred = true; - gDeferredPostNoDoFProgram.mShaderFiles.clear(); - gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredPostNoDoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredPostNoDoFProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredWLSkyProgram.mName = "Deferred Windlight Sky Shader"; - gDeferredWLSkyProgram.mShaderFiles.clear(); - gDeferredWLSkyProgram.mFeatures.calculatesAtmospherics = true; - gDeferredWLSkyProgram.mFeatures.hasTransport = true; - gDeferredWLSkyProgram.mFeatures.hasGamma = true; - gDeferredWLSkyProgram.mFeatures.hasSrgb = true; - - gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredWLSkyProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT]; - gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY; - - success = gDeferredWLSkyProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredWLCloudProgram.mName = "Deferred Windlight Cloud Program"; - gDeferredWLCloudProgram.mShaderFiles.clear(); - gDeferredWLCloudProgram.mFeatures.calculatesAtmospherics = true; - gDeferredWLCloudProgram.mFeatures.hasTransport = true; + success = gDeferredPostGammaCorrectProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gFXAAProgram.mName = "FXAA Shader"; + gFXAAProgram.mFeatures.isDeferred = true; + gFXAAProgram.mShaderFiles.clear(); + gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); + gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/fxaaF.glsl", GL_FRAGMENT_SHADER_ARB)); + gFXAAProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gFXAAProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredPostProgram.mName = "Deferred Post Shader"; + gFXAAProgram.mFeatures.isDeferred = true; + gDeferredPostProgram.mShaderFiles.clear(); + gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredPostProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredPostProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredCoFProgram.mName = "Deferred CoF Shader"; + gDeferredCoFProgram.mShaderFiles.clear(); + gDeferredCoFProgram.mFeatures.isDeferred = true; + gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/cofF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredCoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredCoFProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredDoFCombineProgram.mName = "Deferred DoFCombine Shader"; + gDeferredDoFCombineProgram.mFeatures.isDeferred = true; + gDeferredDoFCombineProgram.mShaderFiles.clear(); + gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/dofCombineF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredDoFCombineProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredDoFCombineProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredPostNoDoFProgram.mName = "Deferred Post Shader"; + gDeferredPostNoDoFProgram.mFeatures.isDeferred = true; + gDeferredPostNoDoFProgram.mShaderFiles.clear(); + gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredPostNoDoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredPostNoDoFProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredWLSkyProgram.mName = "Deferred Windlight Sky Shader"; + gDeferredWLSkyProgram.mShaderFiles.clear(); + gDeferredWLSkyProgram.mFeatures.calculatesAtmospherics = true; + gDeferredWLSkyProgram.mFeatures.hasTransport = true; + gDeferredWLSkyProgram.mFeatures.hasGamma = true; + gDeferredWLSkyProgram.mFeatures.hasSrgb = true; + + gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredWLSkyProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT]; + gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY; + + success = gDeferredWLSkyProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredWLCloudProgram.mName = "Deferred Windlight Cloud Program"; + gDeferredWLCloudProgram.mShaderFiles.clear(); + gDeferredWLCloudProgram.mFeatures.calculatesAtmospherics = true; + gDeferredWLCloudProgram.mFeatures.hasTransport = true; gDeferredWLCloudProgram.mFeatures.hasGamma = true; gDeferredWLCloudProgram.mFeatures.hasSrgb = true; - gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT]; - gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY; - - success = gDeferredWLCloudProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success && (mShaderLevel[SHADER_DEFERRED] > 2)) - { - gDeferredWLCloudShadowProgram.mName = "Deferred Cloud Shadow Program"; - gDeferredWLCloudShadowProgram.mShaderFiles.clear(); - gDeferredWLCloudShadowProgram.mFeatures.calculatesAtmospherics = true; - gDeferredWLCloudShadowProgram.mFeatures.hasTransport = true; - gDeferredWLCloudShadowProgram.mFeatures.hasGamma = true; - gDeferredWLCloudShadowProgram.mFeatures.hasSrgb = true; - gDeferredWLCloudShadowProgram.mFeatures.isDeferred = true; - gDeferredWLCloudShadowProgram.mFeatures.hasShadows = true; - gDeferredWLCloudShadowProgram.mShaderFiles.push_back(make_pair("deferred/cloudShadowV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredWLCloudShadowProgram.mShaderFiles.push_back(make_pair("deferred/cloudShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredWLCloudShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - gDeferredWLCloudShadowProgram.mShaderGroup = LLGLSLShader::SG_SKY; - success = gDeferredWLCloudShadowProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredWLSunProgram.mName = "Deferred Windlight Sun Program"; + gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT]; + gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY; + success = gDeferredWLCloudProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) + { + gDeferredWLSunProgram.mName = "Deferred Windlight Sun Program"; gDeferredWLSunProgram.mFeatures.calculatesAtmospherics = true; gDeferredWLSunProgram.mFeatures.hasTransport = true; gDeferredWLSunProgram.mFeatures.hasGamma = true; @@ -2467,1350 +2432,1345 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredWLMoonProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; gDeferredWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY; - success = gDeferredWLMoonProgram.createShader(NULL, NULL); + success = gDeferredWLMoonProgram.createShader(NULL, NULL); llassert(success); - } - - if (success) - { - gDeferredStarProgram.mName = "Deferred Star Program"; - gDeferredStarProgram.mShaderFiles.clear(); - gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredStarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY; - success = gDeferredStarProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredStarProgram.mName = "Deferred Star Program"; + gDeferredStarProgram.mShaderFiles.clear(); + gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredStarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY; + success = gDeferredStarProgram.createShader(NULL, NULL); llassert(success); - } - - if (success) - { - gNormalMapGenProgram.mName = "Normal Map Generation Program"; - gNormalMapGenProgram.mFeatures.isDeferred = true; - gNormalMapGenProgram.mShaderFiles.clear(); - gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenV.glsl", GL_VERTEX_SHADER_ARB)); - gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenF.glsl", GL_FRAGMENT_SHADER_ARB)); - gNormalMapGenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - gNormalMapGenProgram.mShaderGroup = LLGLSLShader::SG_SKY; - success = gNormalMapGenProgram.createShader(NULL, NULL); - } - - return success; + } + + if (success) + { + gNormalMapGenProgram.mName = "Normal Map Generation Program"; + gNormalMapGenProgram.mShaderFiles.clear(); + gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenV.glsl", GL_VERTEX_SHADER_ARB)); + gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenF.glsl", GL_FRAGMENT_SHADER_ARB)); + gNormalMapGenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gNormalMapGenProgram.mShaderGroup = LLGLSLShader::SG_SKY; + success = gNormalMapGenProgram.createShader(NULL, NULL); + } + + return success; } BOOL LLViewerShaderMgr::loadShadersObject() { - BOOL success = TRUE; - - if (mShaderLevel[SHADER_OBJECT] == 0) - { - gObjectShinyProgram.unload(); - gObjectFullbrightShinyProgram.unload(); - gObjectFullbrightShinyWaterProgram.unload(); - gObjectShinyWaterProgram.unload(); - gObjectFullbrightNoColorProgram.unload(); - gObjectFullbrightNoColorWaterProgram.unload(); - gObjectSimpleProgram.unload(); - gObjectSimpleImpostorProgram.unload(); - gObjectPreviewProgram.unload(); - gImpostorProgram.unload(); - gObjectSimpleAlphaMaskProgram.unload(); - gObjectBumpProgram.unload(); - gObjectSimpleWaterProgram.unload(); - gObjectSimpleWaterAlphaMaskProgram.unload(); - gObjectEmissiveProgram.unload(); - gObjectEmissiveWaterProgram.unload(); - gObjectFullbrightProgram.unload(); - gObjectFullbrightAlphaMaskProgram.unload(); - gObjectFullbrightWaterProgram.unload(); - gObjectFullbrightWaterAlphaMaskProgram.unload(); - gObjectShinyNonIndexedProgram.unload(); - gObjectFullbrightShinyNonIndexedProgram.unload(); - gObjectFullbrightShinyNonIndexedWaterProgram.unload(); - gObjectShinyNonIndexedWaterProgram.unload(); - gObjectSimpleNonIndexedTexGenProgram.unload(); - gObjectSimpleNonIndexedTexGenWaterProgram.unload(); - gObjectSimpleNonIndexedWaterProgram.unload(); - gObjectAlphaMaskNonIndexedProgram.unload(); - gObjectAlphaMaskNonIndexedWaterProgram.unload(); - gObjectAlphaMaskNoColorProgram.unload(); - gObjectAlphaMaskNoColorWaterProgram.unload(); - gObjectFullbrightNonIndexedProgram.unload(); - gObjectFullbrightNonIndexedWaterProgram.unload(); - gObjectEmissiveNonIndexedProgram.unload(); - gObjectEmissiveNonIndexedWaterProgram.unload(); - gSkinnedObjectSimpleProgram.unload(); - gSkinnedObjectFullbrightProgram.unload(); - gSkinnedObjectEmissiveProgram.unload(); - gSkinnedObjectFullbrightShinyProgram.unload(); - gSkinnedObjectShinySimpleProgram.unload(); - gSkinnedObjectSimpleWaterProgram.unload(); - gSkinnedObjectFullbrightWaterProgram.unload(); - gSkinnedObjectEmissiveWaterProgram.unload(); - gSkinnedObjectFullbrightShinyWaterProgram.unload(); - gSkinnedObjectShinySimpleWaterProgram.unload(); - gTreeProgram.unload(); - gTreeWaterProgram.unload(); - - return TRUE; - } - - if (success) - { - gObjectSimpleNonIndexedProgram.mName = "Non indexed Shader"; - gObjectSimpleNonIndexedProgram.mFeatures.calculatesLighting = true; - gObjectSimpleNonIndexedProgram.mFeatures.calculatesAtmospherics = true; - gObjectSimpleNonIndexedProgram.mFeatures.hasGamma = true; - gObjectSimpleNonIndexedProgram.mFeatures.hasAtmospherics = true; - gObjectSimpleNonIndexedProgram.mFeatures.hasLighting = true; - gObjectSimpleNonIndexedProgram.mFeatures.disableTextureIndex = true; - gObjectSimpleNonIndexedProgram.mShaderFiles.clear(); - gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectSimpleNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectSimpleNonIndexedProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectSimpleNonIndexedTexGenProgram.mName = "Non indexed tex-gen Shader"; - gObjectSimpleNonIndexedTexGenProgram.mFeatures.calculatesLighting = true; - gObjectSimpleNonIndexedTexGenProgram.mFeatures.calculatesAtmospherics = true; - gObjectSimpleNonIndexedTexGenProgram.mFeatures.hasGamma = true; - gObjectSimpleNonIndexedTexGenProgram.mFeatures.hasAtmospherics = true; - gObjectSimpleNonIndexedTexGenProgram.mFeatures.hasLighting = true; - gObjectSimpleNonIndexedTexGenProgram.mFeatures.disableTextureIndex = true; - gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.clear(); - gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.push_back(make_pair("objects/simpleTexGenV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectSimpleNonIndexedTexGenProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectSimpleNonIndexedTexGenProgram.createShader(NULL, NULL); - } - - - if (success) - { - gObjectSimpleNonIndexedWaterProgram.mName = "Non indexed Water Shader"; - gObjectSimpleNonIndexedWaterProgram.mFeatures.calculatesLighting = true; - gObjectSimpleNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectSimpleNonIndexedWaterProgram.mFeatures.hasWaterFog = true; - gObjectSimpleNonIndexedWaterProgram.mFeatures.hasAtmospherics = true; - gObjectSimpleNonIndexedWaterProgram.mFeatures.hasLighting = true; - gObjectSimpleNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; - gObjectSimpleNonIndexedWaterProgram.mShaderFiles.clear(); - gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectSimpleNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectSimpleNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectSimpleNonIndexedWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectSimpleNonIndexedTexGenWaterProgram.mName = "Non indexed tex-gen Water Shader"; - gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.calculatesLighting = true; - gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.hasWaterFog = true; - gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.hasAtmospherics = true; - gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.hasLighting = true; - gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.disableTextureIndex = true; - gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.clear(); - gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleTexGenV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectSimpleNonIndexedTexGenWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectSimpleNonIndexedTexGenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectSimpleNonIndexedTexGenWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectAlphaMaskNonIndexedProgram.mName = "Non indexed alpha mask Shader"; - gObjectAlphaMaskNonIndexedProgram.mFeatures.calculatesLighting = true; - gObjectAlphaMaskNonIndexedProgram.mFeatures.calculatesAtmospherics = true; - gObjectAlphaMaskNonIndexedProgram.mFeatures.hasGamma = true; - gObjectAlphaMaskNonIndexedProgram.mFeatures.hasAtmospherics = true; - gObjectAlphaMaskNonIndexedProgram.mFeatures.hasLighting = true; - gObjectAlphaMaskNonIndexedProgram.mFeatures.disableTextureIndex = true; - gObjectAlphaMaskNonIndexedProgram.mFeatures.hasAlphaMask = true; - gObjectAlphaMaskNonIndexedProgram.mShaderFiles.clear(); - gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleNonIndexedV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectAlphaMaskNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectAlphaMaskNonIndexedProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectAlphaMaskNonIndexedWaterProgram.mName = "Non indexed alpha mask Water Shader"; - gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.calculatesLighting = true; - gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.hasWaterFog = true; - gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.hasAtmospherics = true; - gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.hasLighting = true; - gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; - gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.hasAlphaMask = true; - gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.clear(); - gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNonIndexedV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectAlphaMaskNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectAlphaMaskNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectAlphaMaskNonIndexedWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectAlphaMaskNoColorProgram.mName = "No color alpha mask Shader"; - gObjectAlphaMaskNoColorProgram.mFeatures.calculatesLighting = true; - gObjectAlphaMaskNoColorProgram.mFeatures.calculatesAtmospherics = true; - gObjectAlphaMaskNoColorProgram.mFeatures.hasGamma = true; - gObjectAlphaMaskNoColorProgram.mFeatures.hasAtmospherics = true; - gObjectAlphaMaskNoColorProgram.mFeatures.hasLighting = true; - gObjectAlphaMaskNoColorProgram.mFeatures.disableTextureIndex = true; - gObjectAlphaMaskNoColorProgram.mFeatures.hasAlphaMask = true; - gObjectAlphaMaskNoColorProgram.mShaderFiles.clear(); - gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectAlphaMaskNoColorProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectAlphaMaskNoColorWaterProgram.mName = "No color alpha mask Water Shader"; - gObjectAlphaMaskNoColorWaterProgram.mFeatures.calculatesLighting = true; - gObjectAlphaMaskNoColorWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasWaterFog = true; - gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasAtmospherics = true; - gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasLighting = true; - gObjectAlphaMaskNoColorWaterProgram.mFeatures.disableTextureIndex = true; - gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasAlphaMask = true; - gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.clear(); - gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectAlphaMaskNoColorWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectAlphaMaskNoColorWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectAlphaMaskNoColorWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gTreeProgram.mName = "Tree Shader"; - gTreeProgram.mFeatures.calculatesLighting = true; - gTreeProgram.mFeatures.calculatesAtmospherics = true; - gTreeProgram.mFeatures.hasGamma = true; - gTreeProgram.mFeatures.hasAtmospherics = true; - gTreeProgram.mFeatures.hasLighting = true; - gTreeProgram.mFeatures.disableTextureIndex = true; - gTreeProgram.mFeatures.hasAlphaMask = true; - gTreeProgram.mShaderFiles.clear(); - gTreeProgram.mShaderFiles.push_back(make_pair("objects/treeV.glsl", GL_VERTEX_SHADER_ARB)); - gTreeProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); - gTreeProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gTreeProgram.createShader(NULL, NULL); - } - - if (success) - { - gTreeWaterProgram.mName = "Tree Water Shader"; - gTreeWaterProgram.mFeatures.calculatesLighting = true; - gTreeWaterProgram.mFeatures.calculatesAtmospherics = true; - gTreeWaterProgram.mFeatures.hasWaterFog = true; - gTreeWaterProgram.mFeatures.hasAtmospherics = true; - gTreeWaterProgram.mFeatures.hasLighting = true; - gTreeWaterProgram.mFeatures.disableTextureIndex = true; - gTreeWaterProgram.mFeatures.hasAlphaMask = true; - gTreeWaterProgram.mShaderFiles.clear(); - gTreeWaterProgram.mShaderFiles.push_back(make_pair("objects/treeV.glsl", GL_VERTEX_SHADER_ARB)); - gTreeWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gTreeWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gTreeWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gTreeWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectFullbrightNonIndexedProgram.mName = "Non Indexed Fullbright Shader"; - gObjectFullbrightNonIndexedProgram.mFeatures.calculatesAtmospherics = true; - gObjectFullbrightNonIndexedProgram.mFeatures.hasGamma = true; - gObjectFullbrightNonIndexedProgram.mFeatures.hasTransport = true; - gObjectFullbrightNonIndexedProgram.mFeatures.isFullbright = true; - gObjectFullbrightNonIndexedProgram.mFeatures.disableTextureIndex = true; - gObjectFullbrightNonIndexedProgram.mFeatures.hasSrgb = true; - gObjectFullbrightNonIndexedProgram.mShaderFiles.clear(); - gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectFullbrightNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectFullbrightNonIndexedProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectFullbrightNonIndexedWaterProgram.mName = "Non Indexed Fullbright Water Shader"; - gObjectFullbrightNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectFullbrightNonIndexedWaterProgram.mFeatures.isFullbright = true; - gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasWaterFog = true; - gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasTransport = true; - gObjectFullbrightNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; - gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasSrgb = true; - gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.clear(); - gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectFullbrightNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectFullbrightNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectFullbrightNonIndexedWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectEmissiveNonIndexedProgram.mName = "Non Indexed Emissive Shader"; - gObjectEmissiveNonIndexedProgram.mFeatures.calculatesAtmospherics = true; - gObjectEmissiveNonIndexedProgram.mFeatures.hasGamma = true; - gObjectEmissiveNonIndexedProgram.mFeatures.hasTransport = true; - gObjectEmissiveNonIndexedProgram.mFeatures.isFullbright = true; - gObjectEmissiveNonIndexedProgram.mFeatures.disableTextureIndex = true; - gObjectEmissiveNonIndexedProgram.mFeatures.hasSrgb = true; - gObjectEmissiveNonIndexedProgram.mShaderFiles.clear(); - gObjectEmissiveNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectEmissiveNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectEmissiveNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectEmissiveNonIndexedProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectEmissiveNonIndexedWaterProgram.mName = "Non Indexed Emissive Water Shader"; - gObjectEmissiveNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectEmissiveNonIndexedWaterProgram.mFeatures.isFullbright = true; - gObjectEmissiveNonIndexedWaterProgram.mFeatures.hasWaterFog = true; - gObjectEmissiveNonIndexedWaterProgram.mFeatures.hasTransport = true; - gObjectEmissiveNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; - gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.clear(); - gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectEmissiveNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectEmissiveNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectEmissiveNonIndexedWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectFullbrightNoColorProgram.mName = "Non Indexed no color Fullbright Shader"; - gObjectFullbrightNoColorProgram.mFeatures.calculatesAtmospherics = true; - gObjectFullbrightNoColorProgram.mFeatures.hasGamma = true; - gObjectFullbrightNoColorProgram.mFeatures.hasTransport = true; - gObjectFullbrightNoColorProgram.mFeatures.isFullbright = true; - gObjectFullbrightNoColorProgram.mFeatures.hasSrgb = true; - gObjectFullbrightNoColorProgram.mFeatures.disableTextureIndex = true; - gObjectFullbrightNoColorProgram.mShaderFiles.clear(); - gObjectFullbrightNoColorProgram.mShaderFiles.push_back(make_pair("objects/fullbrightNoColorV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectFullbrightNoColorProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectFullbrightNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectFullbrightNoColorProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectFullbrightNoColorWaterProgram.mName = "Non Indexed no color Fullbright Water Shader"; - gObjectFullbrightNoColorWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectFullbrightNoColorWaterProgram.mFeatures.isFullbright = true; - gObjectFullbrightNoColorWaterProgram.mFeatures.hasWaterFog = true; - gObjectFullbrightNoColorWaterProgram.mFeatures.hasTransport = true; - gObjectFullbrightNoColorWaterProgram.mFeatures.disableTextureIndex = true; - gObjectFullbrightNoColorWaterProgram.mShaderFiles.clear(); - gObjectFullbrightNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightNoColorV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectFullbrightNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectFullbrightNoColorWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectFullbrightNoColorWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectFullbrightNoColorWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectShinyNonIndexedProgram.mName = "Non Indexed Shiny Shader"; - gObjectShinyNonIndexedProgram.mFeatures.calculatesAtmospherics = true; - gObjectShinyNonIndexedProgram.mFeatures.calculatesLighting = true; - gObjectShinyNonIndexedProgram.mFeatures.hasGamma = true; - gObjectShinyNonIndexedProgram.mFeatures.hasAtmospherics = true; - gObjectShinyNonIndexedProgram.mFeatures.isShiny = true; - gObjectShinyNonIndexedProgram.mFeatures.disableTextureIndex = true; - gObjectShinyNonIndexedProgram.mShaderFiles.clear(); - gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectShinyNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectShinyNonIndexedProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectShinyNonIndexedWaterProgram.mName = "Non Indexed Shiny Water Shader"; - gObjectShinyNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectShinyNonIndexedWaterProgram.mFeatures.calculatesLighting = true; - gObjectShinyNonIndexedWaterProgram.mFeatures.isShiny = true; - gObjectShinyNonIndexedWaterProgram.mFeatures.hasWaterFog = true; - gObjectShinyNonIndexedWaterProgram.mFeatures.hasAtmospherics = true; - gObjectShinyNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; - gObjectShinyNonIndexedWaterProgram.mShaderFiles.clear(); - gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectShinyNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectShinyNonIndexedWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectFullbrightShinyNonIndexedProgram.mName = "Non Indexed Fullbright Shiny Shader"; - gObjectFullbrightShinyNonIndexedProgram.mFeatures.calculatesAtmospherics = true; - gObjectFullbrightShinyNonIndexedProgram.mFeatures.isFullbright = true; - gObjectFullbrightShinyNonIndexedProgram.mFeatures.isShiny = true; - gObjectFullbrightShinyNonIndexedProgram.mFeatures.hasGamma = true; - gObjectFullbrightShinyNonIndexedProgram.mFeatures.hasTransport = true; - gObjectFullbrightShinyNonIndexedProgram.mFeatures.disableTextureIndex = true; - gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.clear(); - gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectFullbrightShinyNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectFullbrightShinyNonIndexedProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectFullbrightShinyNonIndexedWaterProgram.mName = "Non Indexed Fullbright Shiny Water Shader"; - gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.isFullbright = true; - gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.isShiny = true; - gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasGamma = true; - gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasTransport = true; - gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasWaterFog = true; - gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; - gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.clear(); - gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectFullbrightShinyNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectFullbrightShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectFullbrightShinyNonIndexedWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gImpostorProgram.mName = "Impostor Shader"; - gImpostorProgram.mFeatures.disableTextureIndex = true; - gImpostorProgram.mFeatures.hasSrgb = true; - gImpostorProgram.mShaderFiles.clear(); - gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorV.glsl", GL_VERTEX_SHADER_ARB)); - gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorF.glsl", GL_FRAGMENT_SHADER_ARB)); - gImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gImpostorProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectPreviewProgram.mName = "Simple Shader"; - gObjectPreviewProgram.mFeatures.calculatesLighting = false; - gObjectPreviewProgram.mFeatures.calculatesAtmospherics = false; - gObjectPreviewProgram.mFeatures.hasGamma = false; - gObjectPreviewProgram.mFeatures.hasAtmospherics = false; - gObjectPreviewProgram.mFeatures.hasLighting = false; - gObjectPreviewProgram.mFeatures.mIndexedTextureChannels = 0; - gObjectPreviewProgram.mFeatures.disableTextureIndex = true; - gObjectPreviewProgram.mShaderFiles.clear(); - gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectPreviewProgram.createShader(NULL, NULL); - gObjectPreviewProgram.mFeatures.hasLighting = true; - } - - if (success) - { - gObjectSimpleProgram.mName = "Simple Shader"; - gObjectSimpleProgram.mFeatures.calculatesLighting = true; - gObjectSimpleProgram.mFeatures.calculatesAtmospherics = true; - gObjectSimpleProgram.mFeatures.hasGamma = true; - gObjectSimpleProgram.mFeatures.hasAtmospherics = true; - gObjectSimpleProgram.mFeatures.hasLighting = true; - gObjectSimpleProgram.mFeatures.mIndexedTextureChannels = 0; - gObjectSimpleProgram.mShaderFiles.clear(); - gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectSimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectSimpleProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectSimpleImpostorProgram.mName = "Simple Impostor Shader"; - gObjectSimpleImpostorProgram.mFeatures.calculatesLighting = true; - gObjectSimpleImpostorProgram.mFeatures.calculatesAtmospherics = true; - gObjectSimpleImpostorProgram.mFeatures.hasGamma = true; - gObjectSimpleImpostorProgram.mFeatures.hasAtmospherics = true; - gObjectSimpleImpostorProgram.mFeatures.hasLighting = true; - gObjectSimpleImpostorProgram.mFeatures.mIndexedTextureChannels = 0; - // force alpha mask version of lighting so we can weed out - // transparent pixels from impostor temp buffer - // - gObjectSimpleImpostorProgram.mFeatures.hasAlphaMask = true; - gObjectSimpleImpostorProgram.mShaderFiles.clear(); - gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectSimpleImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - - success = gObjectSimpleImpostorProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectSimpleWaterProgram.mName = "Simple Water Shader"; - gObjectSimpleWaterProgram.mFeatures.calculatesLighting = true; - gObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectSimpleWaterProgram.mFeatures.hasWaterFog = true; - gObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true; - gObjectSimpleWaterProgram.mFeatures.hasLighting = true; - gObjectSimpleWaterProgram.mFeatures.mIndexedTextureChannels = 0; - gObjectSimpleWaterProgram.mShaderFiles.clear(); - gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectSimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectSimpleWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectBumpProgram.mName = "Bump Shader"; - /*gObjectBumpProgram.mFeatures.calculatesLighting = true; - gObjectBumpProgram.mFeatures.calculatesAtmospherics = true; - gObjectBumpProgram.mFeatures.hasGamma = true; - gObjectBumpProgram.mFeatures.hasAtmospherics = true; - gObjectBumpProgram.mFeatures.hasLighting = true; - gObjectBumpProgram.mFeatures.mIndexedTextureChannels = 0;*/ - gObjectBumpProgram.mFeatures.encodesNormal = true; - gObjectBumpProgram.mShaderFiles.clear(); - gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectBumpProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectBumpProgram.createShader(NULL, NULL); - if (success) - { //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1 - gObjectBumpProgram.bind(); - gObjectBumpProgram.uniform1i(sTexture0, 0); - gObjectBumpProgram.uniform1i(sTexture1, 1); - gObjectBumpProgram.unbind(); - } - } - - - if (success) - { - gObjectSimpleAlphaMaskProgram.mName = "Simple Alpha Mask Shader"; - gObjectSimpleAlphaMaskProgram.mFeatures.calculatesLighting = true; - gObjectSimpleAlphaMaskProgram.mFeatures.calculatesAtmospherics = true; - gObjectSimpleAlphaMaskProgram.mFeatures.hasGamma = true; - gObjectSimpleAlphaMaskProgram.mFeatures.hasAtmospherics = true; - gObjectSimpleAlphaMaskProgram.mFeatures.hasLighting = true; - gObjectSimpleAlphaMaskProgram.mFeatures.hasAlphaMask = true; - gObjectSimpleAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0; - gObjectSimpleAlphaMaskProgram.mShaderFiles.clear(); - gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectSimpleAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectSimpleAlphaMaskProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectSimpleWaterAlphaMaskProgram.mName = "Simple Water Alpha Mask Shader"; - gObjectSimpleWaterAlphaMaskProgram.mFeatures.calculatesLighting = true; - gObjectSimpleWaterAlphaMaskProgram.mFeatures.calculatesAtmospherics = true; - gObjectSimpleWaterAlphaMaskProgram.mFeatures.hasWaterFog = true; - gObjectSimpleWaterAlphaMaskProgram.mFeatures.hasAtmospherics = true; - gObjectSimpleWaterAlphaMaskProgram.mFeatures.hasLighting = true; - gObjectSimpleWaterAlphaMaskProgram.mFeatures.hasAlphaMask = true; - gObjectSimpleWaterAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0; - gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.clear(); - gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectSimpleWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectSimpleWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectSimpleWaterAlphaMaskProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectFullbrightProgram.mName = "Fullbright Shader"; - gObjectFullbrightProgram.mFeatures.calculatesAtmospherics = true; - gObjectFullbrightProgram.mFeatures.hasGamma = true; - gObjectFullbrightProgram.mFeatures.hasTransport = true; - gObjectFullbrightProgram.mFeatures.isFullbright = true; - gObjectFullbrightProgram.mFeatures.hasSrgb = true; - gObjectFullbrightProgram.mFeatures.mIndexedTextureChannels = 0; - gObjectFullbrightProgram.mShaderFiles.clear(); - gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectFullbrightProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectFullbrightWaterProgram.mName = "Fullbright Water Shader"; - gObjectFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectFullbrightWaterProgram.mFeatures.isFullbright = true; - gObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true; - gObjectFullbrightWaterProgram.mFeatures.hasTransport = true; - gObjectFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = 0; - gObjectFullbrightWaterProgram.mShaderFiles.clear(); - gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectFullbrightWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectEmissiveProgram.mName = "Emissive Shader"; - gObjectEmissiveProgram.mFeatures.calculatesAtmospherics = true; - gObjectEmissiveProgram.mFeatures.hasGamma = true; - gObjectEmissiveProgram.mFeatures.hasTransport = true; - gObjectEmissiveProgram.mFeatures.isFullbright = true; - gObjectEmissiveProgram.mFeatures.hasSrgb = true; - gObjectEmissiveProgram.mFeatures.mIndexedTextureChannels = 0; - gObjectEmissiveProgram.mShaderFiles.clear(); - gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectEmissiveProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectEmissiveWaterProgram.mName = "Emissive Water Shader"; - gObjectEmissiveWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectEmissiveWaterProgram.mFeatures.isFullbright = true; - gObjectEmissiveWaterProgram.mFeatures.hasWaterFog = true; - gObjectEmissiveWaterProgram.mFeatures.hasTransport = true; - gObjectEmissiveWaterProgram.mFeatures.mIndexedTextureChannels = 0; - gObjectEmissiveWaterProgram.mShaderFiles.clear(); - gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectEmissiveWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectEmissiveWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectEmissiveWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectFullbrightAlphaMaskProgram.mName = "Fullbright Alpha Mask Shader"; - gObjectFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true; - gObjectFullbrightAlphaMaskProgram.mFeatures.hasGamma = true; - gObjectFullbrightAlphaMaskProgram.mFeatures.hasTransport = true; - gObjectFullbrightAlphaMaskProgram.mFeatures.isFullbright = true; - gObjectFullbrightAlphaMaskProgram.mFeatures.hasAlphaMask = true; - gObjectFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true; - gObjectFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0; - gObjectFullbrightAlphaMaskProgram.mShaderFiles.clear(); - gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectFullbrightAlphaMaskProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectFullbrightWaterAlphaMaskProgram.mName = "Fullbright Water Shader"; - gObjectFullbrightWaterAlphaMaskProgram.mFeatures.calculatesAtmospherics = true; - gObjectFullbrightWaterAlphaMaskProgram.mFeatures.isFullbright = true; - gObjectFullbrightWaterAlphaMaskProgram.mFeatures.hasWaterFog = true; - gObjectFullbrightWaterAlphaMaskProgram.mFeatures.hasTransport = true; - gObjectFullbrightWaterAlphaMaskProgram.mFeatures.hasAlphaMask = true; - gObjectFullbrightWaterAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0; - gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.clear(); - gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectFullbrightWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectFullbrightWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectFullbrightWaterAlphaMaskProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectShinyProgram.mName = "Shiny Shader"; - gObjectShinyProgram.mFeatures.calculatesAtmospherics = true; - gObjectShinyProgram.mFeatures.calculatesLighting = true; - gObjectShinyProgram.mFeatures.hasGamma = true; - gObjectShinyProgram.mFeatures.hasAtmospherics = true; - gObjectShinyProgram.mFeatures.isShiny = true; - gObjectShinyProgram.mFeatures.mIndexedTextureChannels = 0; - gObjectShinyProgram.mShaderFiles.clear(); - gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectShinyProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectShinyWaterProgram.mName = "Shiny Water Shader"; - gObjectShinyWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectShinyWaterProgram.mFeatures.calculatesLighting = true; - gObjectShinyWaterProgram.mFeatures.isShiny = true; - gObjectShinyWaterProgram.mFeatures.hasWaterFog = true; - gObjectShinyWaterProgram.mFeatures.hasAtmospherics = true; - gObjectShinyWaterProgram.mFeatures.mIndexedTextureChannels = 0; - gObjectShinyWaterProgram.mShaderFiles.clear(); - gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectShinyWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectFullbrightShinyProgram.mName = "Fullbright Shiny Shader"; - gObjectFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; - gObjectFullbrightShinyProgram.mFeatures.isFullbright = true; - gObjectFullbrightShinyProgram.mFeatures.isShiny = true; - gObjectFullbrightShinyProgram.mFeatures.hasGamma = true; - gObjectFullbrightShinyProgram.mFeatures.hasTransport = true; - gObjectFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = 0; - gObjectFullbrightShinyProgram.mShaderFiles.clear(); - gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gObjectFullbrightShinyProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectFullbrightShinyWaterProgram.mName = "Fullbright Shiny Water Shader"; - gObjectFullbrightShinyWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true; - gObjectFullbrightShinyWaterProgram.mFeatures.isShiny = true; - gObjectFullbrightShinyWaterProgram.mFeatures.hasGamma = true; - gObjectFullbrightShinyWaterProgram.mFeatures.hasTransport = true; - gObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true; - gObjectFullbrightShinyWaterProgram.mFeatures.mIndexedTextureChannels = 0; - gObjectFullbrightShinyWaterProgram.mShaderFiles.clear(); - gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectFullbrightShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - gObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectFullbrightShinyWaterProgram.createShader(NULL, NULL); - } - - if (mShaderLevel[SHADER_AVATAR] > 0) - { //load hardware skinned attachment shaders - if (success) - { - gSkinnedObjectSimpleProgram.mName = "Skinned Simple Shader"; - gSkinnedObjectSimpleProgram.mFeatures.calculatesLighting = true; - gSkinnedObjectSimpleProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectSimpleProgram.mFeatures.hasGamma = true; - gSkinnedObjectSimpleProgram.mFeatures.hasAtmospherics = true; - gSkinnedObjectSimpleProgram.mFeatures.hasLighting = true; - gSkinnedObjectSimpleProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectSimpleProgram.mFeatures.hasAlphaMask = true; - gSkinnedObjectSimpleProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectSimpleProgram.mShaderFiles.clear(); - gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); - gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); - gSkinnedObjectSimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectSimpleProgram.createShader(NULL, NULL); - } - - if (success) - { - gSkinnedObjectFullbrightProgram.mName = "Skinned Fullbright Shader"; - gSkinnedObjectFullbrightProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectFullbrightProgram.mFeatures.hasGamma = true; - gSkinnedObjectFullbrightProgram.mFeatures.hasTransport = true; - gSkinnedObjectFullbrightProgram.mFeatures.isFullbright = true; - gSkinnedObjectFullbrightProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectFullbrightProgram.mFeatures.hasAlphaMask = true; - gSkinnedObjectFullbrightProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectFullbrightProgram.mFeatures.hasSrgb = true; - gSkinnedObjectFullbrightProgram.mShaderFiles.clear(); - gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); - gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gSkinnedObjectFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectFullbrightProgram.createShader(NULL, NULL); - } - - if (success) - { - gSkinnedObjectEmissiveProgram.mName = "Skinned Emissive Shader"; - gSkinnedObjectEmissiveProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectEmissiveProgram.mFeatures.hasGamma = true; - gSkinnedObjectEmissiveProgram.mFeatures.hasTransport = true; - gSkinnedObjectEmissiveProgram.mFeatures.isFullbright = true; - gSkinnedObjectEmissiveProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectEmissiveProgram.mFeatures.disableTextureIndex = true; + BOOL success = TRUE; + + if (mShaderLevel[SHADER_OBJECT] == 0) + { + gObjectShinyProgram.unload(); + gObjectFullbrightShinyProgram.unload(); + gObjectFullbrightShinyWaterProgram.unload(); + gObjectShinyWaterProgram.unload(); + gObjectFullbrightNoColorProgram.unload(); + gObjectFullbrightNoColorWaterProgram.unload(); + gObjectSimpleProgram.unload(); + gObjectSimpleImpostorProgram.unload(); + gObjectPreviewProgram.unload(); + gImpostorProgram.unload(); + gObjectSimpleAlphaMaskProgram.unload(); + gObjectBumpProgram.unload(); + gObjectSimpleWaterProgram.unload(); + gObjectSimpleWaterAlphaMaskProgram.unload(); + gObjectEmissiveProgram.unload(); + gObjectEmissiveWaterProgram.unload(); + gObjectFullbrightProgram.unload(); + gObjectFullbrightAlphaMaskProgram.unload(); + gObjectFullbrightWaterProgram.unload(); + gObjectFullbrightWaterAlphaMaskProgram.unload(); + gObjectShinyNonIndexedProgram.unload(); + gObjectFullbrightShinyNonIndexedProgram.unload(); + gObjectFullbrightShinyNonIndexedWaterProgram.unload(); + gObjectShinyNonIndexedWaterProgram.unload(); + gObjectSimpleNonIndexedTexGenProgram.unload(); + gObjectSimpleNonIndexedTexGenWaterProgram.unload(); + gObjectSimpleNonIndexedWaterProgram.unload(); + gObjectAlphaMaskNonIndexedProgram.unload(); + gObjectAlphaMaskNonIndexedWaterProgram.unload(); + gObjectAlphaMaskNoColorProgram.unload(); + gObjectAlphaMaskNoColorWaterProgram.unload(); + gObjectFullbrightNonIndexedProgram.unload(); + gObjectFullbrightNonIndexedWaterProgram.unload(); + gObjectEmissiveNonIndexedProgram.unload(); + gObjectEmissiveNonIndexedWaterProgram.unload(); + gSkinnedObjectSimpleProgram.unload(); + gSkinnedObjectFullbrightProgram.unload(); + gSkinnedObjectEmissiveProgram.unload(); + gSkinnedObjectFullbrightShinyProgram.unload(); + gSkinnedObjectShinySimpleProgram.unload(); + gSkinnedObjectSimpleWaterProgram.unload(); + gSkinnedObjectFullbrightWaterProgram.unload(); + gSkinnedObjectEmissiveWaterProgram.unload(); + gSkinnedObjectFullbrightShinyWaterProgram.unload(); + gSkinnedObjectShinySimpleWaterProgram.unload(); + gTreeProgram.unload(); + gTreeWaterProgram.unload(); + + return TRUE; + } + + if (success) + { + gObjectSimpleNonIndexedProgram.mName = "Non indexed Shader"; + gObjectSimpleNonIndexedProgram.mFeatures.calculatesLighting = true; + gObjectSimpleNonIndexedProgram.mFeatures.calculatesAtmospherics = true; + gObjectSimpleNonIndexedProgram.mFeatures.hasGamma = true; + gObjectSimpleNonIndexedProgram.mFeatures.hasAtmospherics = true; + gObjectSimpleNonIndexedProgram.mFeatures.hasLighting = true; + gObjectSimpleNonIndexedProgram.mFeatures.disableTextureIndex = true; + gObjectSimpleNonIndexedProgram.mShaderFiles.clear(); + gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectSimpleNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gObjectSimpleNonIndexedProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectSimpleNonIndexedTexGenProgram.mName = "Non indexed tex-gen Shader"; + gObjectSimpleNonIndexedTexGenProgram.mFeatures.calculatesLighting = true; + gObjectSimpleNonIndexedTexGenProgram.mFeatures.calculatesAtmospherics = true; + gObjectSimpleNonIndexedTexGenProgram.mFeatures.hasGamma = true; + gObjectSimpleNonIndexedTexGenProgram.mFeatures.hasAtmospherics = true; + gObjectSimpleNonIndexedTexGenProgram.mFeatures.hasLighting = true; + gObjectSimpleNonIndexedTexGenProgram.mFeatures.disableTextureIndex = true; + gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.clear(); + gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.push_back(make_pair("objects/simpleTexGenV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectSimpleNonIndexedTexGenProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gObjectSimpleNonIndexedTexGenProgram.createShader(NULL, NULL); + } + + + if (success) + { + gObjectSimpleNonIndexedWaterProgram.mName = "Non indexed Water Shader"; + gObjectSimpleNonIndexedWaterProgram.mFeatures.calculatesLighting = true; + gObjectSimpleNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectSimpleNonIndexedWaterProgram.mFeatures.hasWaterFog = true; + gObjectSimpleNonIndexedWaterProgram.mFeatures.hasAtmospherics = true; + gObjectSimpleNonIndexedWaterProgram.mFeatures.hasLighting = true; + gObjectSimpleNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; + gObjectSimpleNonIndexedWaterProgram.mShaderFiles.clear(); + gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectSimpleNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + gObjectSimpleNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectSimpleNonIndexedWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectSimpleNonIndexedTexGenWaterProgram.mName = "Non indexed tex-gen Water Shader"; + gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.calculatesLighting = true; + gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.hasWaterFog = true; + gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.hasAtmospherics = true; + gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.hasLighting = true; + gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.disableTextureIndex = true; + gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.clear(); + gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleTexGenV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectSimpleNonIndexedTexGenWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + gObjectSimpleNonIndexedTexGenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectSimpleNonIndexedTexGenWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectAlphaMaskNonIndexedProgram.mName = "Non indexed alpha mask Shader"; + gObjectAlphaMaskNonIndexedProgram.mFeatures.calculatesLighting = true; + gObjectAlphaMaskNonIndexedProgram.mFeatures.calculatesAtmospherics = true; + gObjectAlphaMaskNonIndexedProgram.mFeatures.hasGamma = true; + gObjectAlphaMaskNonIndexedProgram.mFeatures.hasAtmospherics = true; + gObjectAlphaMaskNonIndexedProgram.mFeatures.hasLighting = true; + gObjectAlphaMaskNonIndexedProgram.mFeatures.disableTextureIndex = true; + gObjectAlphaMaskNonIndexedProgram.mFeatures.hasAlphaMask = true; + gObjectAlphaMaskNonIndexedProgram.mShaderFiles.clear(); + gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleNonIndexedV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectAlphaMaskNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gObjectAlphaMaskNonIndexedProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectAlphaMaskNonIndexedWaterProgram.mName = "Non indexed alpha mask Water Shader"; + gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.calculatesLighting = true; + gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.hasWaterFog = true; + gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.hasAtmospherics = true; + gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.hasLighting = true; + gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; + gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.hasAlphaMask = true; + gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.clear(); + gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNonIndexedV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectAlphaMaskNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + gObjectAlphaMaskNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectAlphaMaskNonIndexedWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectAlphaMaskNoColorProgram.mName = "No color alpha mask Shader"; + gObjectAlphaMaskNoColorProgram.mFeatures.calculatesLighting = true; + gObjectAlphaMaskNoColorProgram.mFeatures.calculatesAtmospherics = true; + gObjectAlphaMaskNoColorProgram.mFeatures.hasGamma = true; + gObjectAlphaMaskNoColorProgram.mFeatures.hasAtmospherics = true; + gObjectAlphaMaskNoColorProgram.mFeatures.hasLighting = true; + gObjectAlphaMaskNoColorProgram.mFeatures.disableTextureIndex = true; + gObjectAlphaMaskNoColorProgram.mFeatures.hasAlphaMask = true; + gObjectAlphaMaskNoColorProgram.mShaderFiles.clear(); + gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gObjectAlphaMaskNoColorProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectAlphaMaskNoColorWaterProgram.mName = "No color alpha mask Water Shader"; + gObjectAlphaMaskNoColorWaterProgram.mFeatures.calculatesLighting = true; + gObjectAlphaMaskNoColorWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasWaterFog = true; + gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasAtmospherics = true; + gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasLighting = true; + gObjectAlphaMaskNoColorWaterProgram.mFeatures.disableTextureIndex = true; + gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasAlphaMask = true; + gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.clear(); + gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectAlphaMaskNoColorWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + gObjectAlphaMaskNoColorWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectAlphaMaskNoColorWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gTreeProgram.mName = "Tree Shader"; + gTreeProgram.mFeatures.calculatesLighting = true; + gTreeProgram.mFeatures.calculatesAtmospherics = true; + gTreeProgram.mFeatures.hasGamma = true; + gTreeProgram.mFeatures.hasAtmospherics = true; + gTreeProgram.mFeatures.hasLighting = true; + gTreeProgram.mFeatures.disableTextureIndex = true; + gTreeProgram.mFeatures.hasAlphaMask = true; + gTreeProgram.mShaderFiles.clear(); + gTreeProgram.mShaderFiles.push_back(make_pair("objects/treeV.glsl", GL_VERTEX_SHADER_ARB)); + gTreeProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); + gTreeProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gTreeProgram.createShader(NULL, NULL); + } + + if (success) + { + gTreeWaterProgram.mName = "Tree Water Shader"; + gTreeWaterProgram.mFeatures.calculatesLighting = true; + gTreeWaterProgram.mFeatures.calculatesAtmospherics = true; + gTreeWaterProgram.mFeatures.hasWaterFog = true; + gTreeWaterProgram.mFeatures.hasAtmospherics = true; + gTreeWaterProgram.mFeatures.hasLighting = true; + gTreeWaterProgram.mFeatures.disableTextureIndex = true; + gTreeWaterProgram.mFeatures.hasAlphaMask = true; + gTreeWaterProgram.mShaderFiles.clear(); + gTreeWaterProgram.mShaderFiles.push_back(make_pair("objects/treeV.glsl", GL_VERTEX_SHADER_ARB)); + gTreeWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gTreeWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + gTreeWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gTreeWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectFullbrightNonIndexedProgram.mName = "Non Indexed Fullbright Shader"; + gObjectFullbrightNonIndexedProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightNonIndexedProgram.mFeatures.hasGamma = true; + gObjectFullbrightNonIndexedProgram.mFeatures.hasTransport = true; + gObjectFullbrightNonIndexedProgram.mFeatures.isFullbright = true; + gObjectFullbrightNonIndexedProgram.mFeatures.disableTextureIndex = true; + gObjectFullbrightNonIndexedProgram.mShaderFiles.clear(); + gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gObjectFullbrightNonIndexedProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectFullbrightNonIndexedWaterProgram.mName = "Non Indexed Fullbright Water Shader"; + gObjectFullbrightNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightNonIndexedWaterProgram.mFeatures.isFullbright = true; + gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasWaterFog = true; + gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasTransport = true; + gObjectFullbrightNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; + gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasSrgb = true; + gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.clear(); + gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + gObjectFullbrightNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectFullbrightNonIndexedWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectEmissiveNonIndexedProgram.mName = "Non Indexed Emissive Shader"; + gObjectEmissiveNonIndexedProgram.mFeatures.calculatesAtmospherics = true; + gObjectEmissiveNonIndexedProgram.mFeatures.hasGamma = true; + gObjectEmissiveNonIndexedProgram.mFeatures.hasTransport = true; + gObjectEmissiveNonIndexedProgram.mFeatures.isFullbright = true; + gObjectEmissiveNonIndexedProgram.mFeatures.disableTextureIndex = true; + gObjectEmissiveNonIndexedProgram.mFeatures.hasSrgb = true; + gObjectEmissiveNonIndexedProgram.mShaderFiles.clear(); + gObjectEmissiveNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectEmissiveNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectEmissiveNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gObjectEmissiveNonIndexedProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectEmissiveNonIndexedWaterProgram.mName = "Non Indexed Emissive Water Shader"; + gObjectEmissiveNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectEmissiveNonIndexedWaterProgram.mFeatures.isFullbright = true; + gObjectEmissiveNonIndexedWaterProgram.mFeatures.hasWaterFog = true; + gObjectEmissiveNonIndexedWaterProgram.mFeatures.hasTransport = true; + gObjectEmissiveNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; + gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.clear(); + gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectEmissiveNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + gObjectEmissiveNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectEmissiveNonIndexedWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectFullbrightNoColorProgram.mName = "Non Indexed no color Fullbright Shader"; + gObjectFullbrightNoColorProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightNoColorProgram.mFeatures.hasGamma = true; + gObjectFullbrightNoColorProgram.mFeatures.hasTransport = true; + gObjectFullbrightNoColorProgram.mFeatures.isFullbright = true; + gObjectFullbrightNoColorProgram.mFeatures.hasSrgb = true; + gObjectFullbrightNoColorProgram.mFeatures.disableTextureIndex = true; + gObjectFullbrightNoColorProgram.mShaderFiles.clear(); + gObjectFullbrightNoColorProgram.mShaderFiles.push_back(make_pair("objects/fullbrightNoColorV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightNoColorProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gObjectFullbrightNoColorProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectFullbrightNoColorWaterProgram.mName = "Non Indexed no color Fullbright Water Shader"; + gObjectFullbrightNoColorWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightNoColorWaterProgram.mFeatures.isFullbright = true; + gObjectFullbrightNoColorWaterProgram.mFeatures.hasWaterFog = true; + gObjectFullbrightNoColorWaterProgram.mFeatures.hasTransport = true; + gObjectFullbrightNoColorWaterProgram.mFeatures.disableTextureIndex = true; + gObjectFullbrightNoColorWaterProgram.mShaderFiles.clear(); + gObjectFullbrightNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightNoColorV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightNoColorWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + gObjectFullbrightNoColorWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectFullbrightNoColorWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectShinyNonIndexedProgram.mName = "Non Indexed Shiny Shader"; + gObjectShinyNonIndexedProgram.mFeatures.calculatesAtmospherics = true; + gObjectShinyNonIndexedProgram.mFeatures.calculatesLighting = true; + gObjectShinyNonIndexedProgram.mFeatures.hasGamma = true; + gObjectShinyNonIndexedProgram.mFeatures.hasAtmospherics = true; + gObjectShinyNonIndexedProgram.mFeatures.isShiny = true; + gObjectShinyNonIndexedProgram.mFeatures.disableTextureIndex = true; + gObjectShinyNonIndexedProgram.mShaderFiles.clear(); + gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectShinyNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gObjectShinyNonIndexedProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectShinyNonIndexedWaterProgram.mName = "Non Indexed Shiny Water Shader"; + gObjectShinyNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectShinyNonIndexedWaterProgram.mFeatures.calculatesLighting = true; + gObjectShinyNonIndexedWaterProgram.mFeatures.isShiny = true; + gObjectShinyNonIndexedWaterProgram.mFeatures.hasWaterFog = true; + gObjectShinyNonIndexedWaterProgram.mFeatures.hasAtmospherics = true; + gObjectShinyNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; + gObjectShinyNonIndexedWaterProgram.mShaderFiles.clear(); + gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectShinyNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + gObjectShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectShinyNonIndexedWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectFullbrightShinyNonIndexedProgram.mName = "Non Indexed Fullbright Shiny Shader"; + gObjectFullbrightShinyNonIndexedProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightShinyNonIndexedProgram.mFeatures.isFullbright = true; + gObjectFullbrightShinyNonIndexedProgram.mFeatures.isShiny = true; + gObjectFullbrightShinyNonIndexedProgram.mFeatures.hasGamma = true; + gObjectFullbrightShinyNonIndexedProgram.mFeatures.hasTransport = true; + gObjectFullbrightShinyNonIndexedProgram.mFeatures.disableTextureIndex = true; + gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.clear(); + gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightShinyNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gObjectFullbrightShinyNonIndexedProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectFullbrightShinyNonIndexedWaterProgram.mName = "Non Indexed Fullbright Shiny Water Shader"; + gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.isFullbright = true; + gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.isShiny = true; + gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasGamma = true; + gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasTransport = true; + gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasWaterFog = true; + gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.disableTextureIndex = true; + gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.clear(); + gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightShinyNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + gObjectFullbrightShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectFullbrightShinyNonIndexedWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gImpostorProgram.mName = "Impostor Shader"; + gImpostorProgram.mFeatures.disableTextureIndex = true; + gImpostorProgram.mFeatures.hasSrgb = true; + gImpostorProgram.mShaderFiles.clear(); + gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorV.glsl", GL_VERTEX_SHADER_ARB)); + gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorF.glsl", GL_FRAGMENT_SHADER_ARB)); + gImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gImpostorProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectPreviewProgram.mName = "Simple Shader"; + gObjectPreviewProgram.mFeatures.calculatesLighting = false; + gObjectPreviewProgram.mFeatures.calculatesAtmospherics = false; + gObjectPreviewProgram.mFeatures.hasGamma = false; + gObjectPreviewProgram.mFeatures.hasAtmospherics = false; + gObjectPreviewProgram.mFeatures.hasLighting = false; + gObjectPreviewProgram.mFeatures.mIndexedTextureChannels = 0; + gObjectPreviewProgram.mFeatures.disableTextureIndex = true; + gObjectPreviewProgram.mShaderFiles.clear(); + gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gObjectPreviewProgram.createShader(NULL, NULL); + gObjectPreviewProgram.mFeatures.hasLighting = true; + } + + if (success) + { + gObjectSimpleProgram.mName = "Simple Shader"; + gObjectSimpleProgram.mFeatures.calculatesLighting = true; + gObjectSimpleProgram.mFeatures.calculatesAtmospherics = true; + gObjectSimpleProgram.mFeatures.hasGamma = true; + gObjectSimpleProgram.mFeatures.hasAtmospherics = true; + gObjectSimpleProgram.mFeatures.hasLighting = true; + gObjectSimpleProgram.mFeatures.mIndexedTextureChannels = 0; + gObjectSimpleProgram.mShaderFiles.clear(); + gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectSimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gObjectSimpleProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectSimpleImpostorProgram.mName = "Simple Impostor Shader"; + gObjectSimpleImpostorProgram.mFeatures.calculatesLighting = true; + gObjectSimpleImpostorProgram.mFeatures.calculatesAtmospherics = true; + gObjectSimpleImpostorProgram.mFeatures.hasGamma = true; + gObjectSimpleImpostorProgram.mFeatures.hasAtmospherics = true; + gObjectSimpleImpostorProgram.mFeatures.hasLighting = true; + gObjectSimpleImpostorProgram.mFeatures.mIndexedTextureChannels = 0; + // force alpha mask version of lighting so we can weed out + // transparent pixels from impostor temp buffer + // + gObjectSimpleImpostorProgram.mFeatures.hasAlphaMask = true; + gObjectSimpleImpostorProgram.mShaderFiles.clear(); + gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectSimpleImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + + success = gObjectSimpleImpostorProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectSimpleWaterProgram.mName = "Simple Water Shader"; + gObjectSimpleWaterProgram.mFeatures.calculatesLighting = true; + gObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectSimpleWaterProgram.mFeatures.hasWaterFog = true; + gObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true; + gObjectSimpleWaterProgram.mFeatures.hasLighting = true; + gObjectSimpleWaterProgram.mFeatures.mIndexedTextureChannels = 0; + gObjectSimpleWaterProgram.mShaderFiles.clear(); + gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectSimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + gObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectSimpleWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectBumpProgram.mName = "Bump Shader"; + /*gObjectBumpProgram.mFeatures.calculatesLighting = true; + gObjectBumpProgram.mFeatures.calculatesAtmospherics = true; + gObjectBumpProgram.mFeatures.hasGamma = true; + gObjectBumpProgram.mFeatures.hasAtmospherics = true; + gObjectBumpProgram.mFeatures.hasLighting = true; + gObjectBumpProgram.mFeatures.mIndexedTextureChannels = 0;*/ + gObjectBumpProgram.mFeatures.encodesNormal = true; + gObjectBumpProgram.mShaderFiles.clear(); + gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectBumpProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gObjectBumpProgram.createShader(NULL, NULL); + if (success) + { //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1 + gObjectBumpProgram.bind(); + gObjectBumpProgram.uniform1i(sTexture0, 0); + gObjectBumpProgram.uniform1i(sTexture1, 1); + gObjectBumpProgram.unbind(); + } + } + + + if (success) + { + gObjectSimpleAlphaMaskProgram.mName = "Simple Alpha Mask Shader"; + gObjectSimpleAlphaMaskProgram.mFeatures.calculatesLighting = true; + gObjectSimpleAlphaMaskProgram.mFeatures.calculatesAtmospherics = true; + gObjectSimpleAlphaMaskProgram.mFeatures.hasGamma = true; + gObjectSimpleAlphaMaskProgram.mFeatures.hasAtmospherics = true; + gObjectSimpleAlphaMaskProgram.mFeatures.hasLighting = true; + gObjectSimpleAlphaMaskProgram.mFeatures.hasAlphaMask = true; + gObjectSimpleAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0; + gObjectSimpleAlphaMaskProgram.mShaderFiles.clear(); + gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectSimpleAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gObjectSimpleAlphaMaskProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectSimpleWaterAlphaMaskProgram.mName = "Simple Water Alpha Mask Shader"; + gObjectSimpleWaterAlphaMaskProgram.mFeatures.calculatesLighting = true; + gObjectSimpleWaterAlphaMaskProgram.mFeatures.calculatesAtmospherics = true; + gObjectSimpleWaterAlphaMaskProgram.mFeatures.hasWaterFog = true; + gObjectSimpleWaterAlphaMaskProgram.mFeatures.hasAtmospherics = true; + gObjectSimpleWaterAlphaMaskProgram.mFeatures.hasLighting = true; + gObjectSimpleWaterAlphaMaskProgram.mFeatures.hasAlphaMask = true; + gObjectSimpleWaterAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0; + gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.clear(); + gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectSimpleWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + gObjectSimpleWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectSimpleWaterAlphaMaskProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectFullbrightProgram.mName = "Fullbright Shader"; + gObjectFullbrightProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightProgram.mFeatures.hasGamma = true; + gObjectFullbrightProgram.mFeatures.hasTransport = true; + gObjectFullbrightProgram.mFeatures.isFullbright = true; + gObjectFullbrightProgram.mFeatures.hasSrgb = true; + gObjectFullbrightProgram.mFeatures.mIndexedTextureChannels = 0; + gObjectFullbrightProgram.mShaderFiles.clear(); + gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gObjectFullbrightProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectFullbrightWaterProgram.mName = "Fullbright Water Shader"; + gObjectFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightWaterProgram.mFeatures.isFullbright = true; + gObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true; + gObjectFullbrightWaterProgram.mFeatures.hasTransport = true; + gObjectFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = 0; + gObjectFullbrightWaterProgram.mShaderFiles.clear(); + gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + gObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectFullbrightWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectEmissiveProgram.mName = "Emissive Shader"; + gObjectEmissiveProgram.mFeatures.calculatesAtmospherics = true; + gObjectEmissiveProgram.mFeatures.hasGamma = true; + gObjectEmissiveProgram.mFeatures.hasTransport = true; + gObjectEmissiveProgram.mFeatures.isFullbright = true; + gObjectEmissiveProgram.mFeatures.hasSrgb = true; + gObjectEmissiveProgram.mFeatures.mIndexedTextureChannels = 0; + gObjectEmissiveProgram.mShaderFiles.clear(); + gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gObjectEmissiveProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectEmissiveWaterProgram.mName = "Emissive Water Shader"; + gObjectEmissiveWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectEmissiveWaterProgram.mFeatures.isFullbright = true; + gObjectEmissiveWaterProgram.mFeatures.hasWaterFog = true; + gObjectEmissiveWaterProgram.mFeatures.hasTransport = true; + gObjectEmissiveWaterProgram.mFeatures.mIndexedTextureChannels = 0; + gObjectEmissiveWaterProgram.mShaderFiles.clear(); + gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectEmissiveWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + gObjectEmissiveWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectEmissiveWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectFullbrightAlphaMaskProgram.mName = "Fullbright Alpha Mask Shader"; + gObjectFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightAlphaMaskProgram.mFeatures.hasGamma = true; + gObjectFullbrightAlphaMaskProgram.mFeatures.hasTransport = true; + gObjectFullbrightAlphaMaskProgram.mFeatures.isFullbright = true; + gObjectFullbrightAlphaMaskProgram.mFeatures.hasAlphaMask = true; + gObjectFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true; + gObjectFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0; + gObjectFullbrightAlphaMaskProgram.mShaderFiles.clear(); + gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gObjectFullbrightAlphaMaskProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectFullbrightWaterAlphaMaskProgram.mName = "Fullbright Water Shader"; + gObjectFullbrightWaterAlphaMaskProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightWaterAlphaMaskProgram.mFeatures.isFullbright = true; + gObjectFullbrightWaterAlphaMaskProgram.mFeatures.hasWaterFog = true; + gObjectFullbrightWaterAlphaMaskProgram.mFeatures.hasTransport = true; + gObjectFullbrightWaterAlphaMaskProgram.mFeatures.hasAlphaMask = true; + gObjectFullbrightWaterAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0; + gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.clear(); + gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + gObjectFullbrightWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectFullbrightWaterAlphaMaskProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectShinyProgram.mName = "Shiny Shader"; + gObjectShinyProgram.mFeatures.calculatesAtmospherics = true; + gObjectShinyProgram.mFeatures.calculatesLighting = true; + gObjectShinyProgram.mFeatures.hasGamma = true; + gObjectShinyProgram.mFeatures.hasAtmospherics = true; + gObjectShinyProgram.mFeatures.isShiny = true; + gObjectShinyProgram.mFeatures.mIndexedTextureChannels = 0; + gObjectShinyProgram.mShaderFiles.clear(); + gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gObjectShinyProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectShinyWaterProgram.mName = "Shiny Water Shader"; + gObjectShinyWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectShinyWaterProgram.mFeatures.calculatesLighting = true; + gObjectShinyWaterProgram.mFeatures.isShiny = true; + gObjectShinyWaterProgram.mFeatures.hasWaterFog = true; + gObjectShinyWaterProgram.mFeatures.hasAtmospherics = true; + gObjectShinyWaterProgram.mFeatures.mIndexedTextureChannels = 0; + gObjectShinyWaterProgram.mShaderFiles.clear(); + gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + gObjectShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectShinyWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectFullbrightShinyProgram.mName = "Fullbright Shiny Shader"; + gObjectFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightShinyProgram.mFeatures.isFullbright = true; + gObjectFullbrightShinyProgram.mFeatures.isShiny = true; + gObjectFullbrightShinyProgram.mFeatures.hasGamma = true; + gObjectFullbrightShinyProgram.mFeatures.hasTransport = true; + gObjectFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = 0; + gObjectFullbrightShinyProgram.mShaderFiles.clear(); + gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gObjectFullbrightShinyProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectFullbrightShinyWaterProgram.mName = "Fullbright Shiny Water Shader"; + gObjectFullbrightShinyWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true; + gObjectFullbrightShinyWaterProgram.mFeatures.isShiny = true; + gObjectFullbrightShinyWaterProgram.mFeatures.hasGamma = true; + gObjectFullbrightShinyWaterProgram.mFeatures.hasTransport = true; + gObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true; + gObjectFullbrightShinyWaterProgram.mFeatures.mIndexedTextureChannels = 0; + gObjectFullbrightShinyWaterProgram.mShaderFiles.clear(); + gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + gObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectFullbrightShinyWaterProgram.createShader(NULL, NULL); + } + + if (mShaderLevel[SHADER_AVATAR] > 0) + { //load hardware skinned attachment shaders + if (success) + { + gSkinnedObjectSimpleProgram.mName = "Skinned Simple Shader"; + gSkinnedObjectSimpleProgram.mFeatures.calculatesLighting = true; + gSkinnedObjectSimpleProgram.mFeatures.calculatesAtmospherics = true; + gSkinnedObjectSimpleProgram.mFeatures.hasGamma = true; + gSkinnedObjectSimpleProgram.mFeatures.hasAtmospherics = true; + gSkinnedObjectSimpleProgram.mFeatures.hasLighting = true; + gSkinnedObjectSimpleProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectSimpleProgram.mFeatures.hasAlphaMask = true; + gSkinnedObjectSimpleProgram.mFeatures.disableTextureIndex = true; + gSkinnedObjectSimpleProgram.mShaderFiles.clear(); + gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSkinnedObjectSimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gSkinnedObjectSimpleProgram.createShader(NULL, NULL); + } + + if (success) + { + gSkinnedObjectFullbrightProgram.mName = "Skinned Fullbright Shader"; + gSkinnedObjectFullbrightProgram.mFeatures.calculatesAtmospherics = true; + gSkinnedObjectFullbrightProgram.mFeatures.hasGamma = true; + gSkinnedObjectFullbrightProgram.mFeatures.hasTransport = true; + gSkinnedObjectFullbrightProgram.mFeatures.isFullbright = true; + gSkinnedObjectFullbrightProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectFullbrightProgram.mFeatures.hasAlphaMask = true; + gSkinnedObjectFullbrightProgram.mFeatures.disableTextureIndex = true; + gSkinnedObjectFullbrightProgram.mFeatures.hasSrgb = true; + gSkinnedObjectFullbrightProgram.mShaderFiles.clear(); + gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSkinnedObjectFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gSkinnedObjectFullbrightProgram.createShader(NULL, NULL); + } + + if (success) + { + gSkinnedObjectEmissiveProgram.mName = "Skinned Emissive Shader"; + gSkinnedObjectEmissiveProgram.mFeatures.calculatesAtmospherics = true; + gSkinnedObjectEmissiveProgram.mFeatures.hasGamma = true; + gSkinnedObjectEmissiveProgram.mFeatures.hasTransport = true; + gSkinnedObjectEmissiveProgram.mFeatures.isFullbright = true; + gSkinnedObjectEmissiveProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectEmissiveProgram.mFeatures.disableTextureIndex = true; gSkinnedObjectEmissiveProgram.mFeatures.hasSrgb = true; - gSkinnedObjectEmissiveProgram.mShaderFiles.clear(); - gSkinnedObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); - gSkinnedObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gSkinnedObjectEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectEmissiveProgram.createShader(NULL, NULL); - } - - if (success) - { - gSkinnedObjectEmissiveWaterProgram.mName = "Skinned Emissive Water Shader"; - gSkinnedObjectEmissiveWaterProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectEmissiveWaterProgram.mFeatures.hasGamma = true; - gSkinnedObjectEmissiveWaterProgram.mFeatures.hasTransport = true; - gSkinnedObjectEmissiveWaterProgram.mFeatures.isFullbright = true; - gSkinnedObjectEmissiveWaterProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectEmissiveWaterProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectEmissiveWaterProgram.mFeatures.hasWaterFog = true; - gSkinnedObjectEmissiveWaterProgram.mShaderFiles.clear(); - gSkinnedObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); - gSkinnedObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gSkinnedObjectEmissiveWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectEmissiveWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gSkinnedObjectFullbrightShinyProgram.mName = "Skinned Fullbright Shiny Shader"; - gSkinnedObjectFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectFullbrightShinyProgram.mFeatures.hasGamma = true; - gSkinnedObjectFullbrightShinyProgram.mFeatures.hasTransport = true; - gSkinnedObjectFullbrightShinyProgram.mFeatures.isShiny = true; - gSkinnedObjectFullbrightShinyProgram.mFeatures.isFullbright = true; - gSkinnedObjectFullbrightShinyProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectFullbrightShinyProgram.mFeatures.hasAlphaMask = true; - gSkinnedObjectFullbrightShinyProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectFullbrightShinyProgram.mShaderFiles.clear(); - gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); - gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); - gSkinnedObjectFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectFullbrightShinyProgram.createShader(NULL, NULL); - } - - if (success) - { - gSkinnedObjectShinySimpleProgram.mName = "Skinned Shiny Simple Shader"; - gSkinnedObjectShinySimpleProgram.mFeatures.calculatesLighting = true; - gSkinnedObjectShinySimpleProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectShinySimpleProgram.mFeatures.hasGamma = true; - gSkinnedObjectShinySimpleProgram.mFeatures.hasAtmospherics = true; - gSkinnedObjectShinySimpleProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectShinySimpleProgram.mFeatures.hasAlphaMask = true; - gSkinnedObjectShinySimpleProgram.mFeatures.isShiny = true; - gSkinnedObjectShinySimpleProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectShinySimpleProgram.mShaderFiles.clear(); - gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); - gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB)); - gSkinnedObjectShinySimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectShinySimpleProgram.createShader(NULL, NULL); - } - - if (success) - { - gSkinnedObjectSimpleWaterProgram.mName = "Skinned Simple Water Shader"; - gSkinnedObjectSimpleWaterProgram.mFeatures.calculatesLighting = true; - gSkinnedObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectSimpleWaterProgram.mFeatures.hasGamma = true; - gSkinnedObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true; - gSkinnedObjectSimpleWaterProgram.mFeatures.hasLighting = true; - gSkinnedObjectSimpleWaterProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectSimpleWaterProgram.mFeatures.hasWaterFog = true; - gSkinnedObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gSkinnedObjectSimpleWaterProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectSimpleWaterProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectSimpleWaterProgram.mFeatures.hasAlphaMask = true; - gSkinnedObjectSimpleWaterProgram.mShaderFiles.clear(); - gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); - gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gSkinnedObjectSimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectSimpleWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gSkinnedObjectFullbrightWaterProgram.mName = "Skinned Fullbright Water Shader"; - gSkinnedObjectFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectFullbrightWaterProgram.mFeatures.hasGamma = true; - gSkinnedObjectFullbrightWaterProgram.mFeatures.hasTransport = true; - gSkinnedObjectFullbrightWaterProgram.mFeatures.isFullbright = true; - gSkinnedObjectFullbrightWaterProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectFullbrightWaterProgram.mFeatures.hasAlphaMask = true; - gSkinnedObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true; - gSkinnedObjectFullbrightWaterProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gSkinnedObjectFullbrightWaterProgram.mShaderFiles.clear(); - gSkinnedObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); - gSkinnedObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gSkinnedObjectFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectFullbrightWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gSkinnedObjectFullbrightShinyWaterProgram.mName = "Skinned Fullbright Shiny Water Shader"; - gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasGamma = true; - gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasTransport = true; - gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isShiny = true; - gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true; - gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasAlphaMask = true; - gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true; - gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.clear(); - gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); - gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gSkinnedObjectFullbrightShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectFullbrightShinyWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gSkinnedObjectShinySimpleWaterProgram.mName = "Skinned Shiny Simple Water Shader"; - gSkinnedObjectShinySimpleWaterProgram.mFeatures.calculatesLighting = true; - gSkinnedObjectShinySimpleWaterProgram.mFeatures.calculatesAtmospherics = true; - gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasGamma = true; - gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasAtmospherics = true; - gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasObjectSkinning = true; - gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasAlphaMask = true; - gSkinnedObjectShinySimpleWaterProgram.mFeatures.isShiny = true; - gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasWaterFog = true; - gSkinnedObjectShinySimpleWaterProgram.mFeatures.disableTextureIndex = true; - gSkinnedObjectShinySimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.clear(); - gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); - gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gSkinnedObjectShinySimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; - success = gSkinnedObjectShinySimpleWaterProgram.createShader(NULL, NULL); - } - } - - if( !success ) - { - mShaderLevel[SHADER_OBJECT] = 0; - return FALSE; - } - - return TRUE; + gSkinnedObjectEmissiveProgram.mShaderFiles.clear(); + gSkinnedObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gSkinnedObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSkinnedObjectEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gSkinnedObjectEmissiveProgram.createShader(NULL, NULL); + } + + if (success) + { + gSkinnedObjectEmissiveWaterProgram.mName = "Skinned Emissive Water Shader"; + gSkinnedObjectEmissiveWaterProgram.mFeatures.calculatesAtmospherics = true; + gSkinnedObjectEmissiveWaterProgram.mFeatures.hasGamma = true; + gSkinnedObjectEmissiveWaterProgram.mFeatures.hasTransport = true; + gSkinnedObjectEmissiveWaterProgram.mFeatures.isFullbright = true; + gSkinnedObjectEmissiveWaterProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectEmissiveWaterProgram.mFeatures.disableTextureIndex = true; + gSkinnedObjectEmissiveWaterProgram.mFeatures.hasWaterFog = true; + gSkinnedObjectEmissiveWaterProgram.mShaderFiles.clear(); + gSkinnedObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gSkinnedObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSkinnedObjectEmissiveWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gSkinnedObjectEmissiveWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gSkinnedObjectFullbrightShinyProgram.mName = "Skinned Fullbright Shiny Shader"; + gSkinnedObjectFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; + gSkinnedObjectFullbrightShinyProgram.mFeatures.hasGamma = true; + gSkinnedObjectFullbrightShinyProgram.mFeatures.hasTransport = true; + gSkinnedObjectFullbrightShinyProgram.mFeatures.isShiny = true; + gSkinnedObjectFullbrightShinyProgram.mFeatures.isFullbright = true; + gSkinnedObjectFullbrightShinyProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectFullbrightShinyProgram.mFeatures.hasAlphaMask = true; + gSkinnedObjectFullbrightShinyProgram.mFeatures.disableTextureIndex = true; + gSkinnedObjectFullbrightShinyProgram.mShaderFiles.clear(); + gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSkinnedObjectFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gSkinnedObjectFullbrightShinyProgram.createShader(NULL, NULL); + } + + if (success) + { + gSkinnedObjectShinySimpleProgram.mName = "Skinned Shiny Simple Shader"; + gSkinnedObjectShinySimpleProgram.mFeatures.calculatesLighting = true; + gSkinnedObjectShinySimpleProgram.mFeatures.calculatesAtmospherics = true; + gSkinnedObjectShinySimpleProgram.mFeatures.hasGamma = true; + gSkinnedObjectShinySimpleProgram.mFeatures.hasAtmospherics = true; + gSkinnedObjectShinySimpleProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectShinySimpleProgram.mFeatures.hasAlphaMask = true; + gSkinnedObjectShinySimpleProgram.mFeatures.isShiny = true; + gSkinnedObjectShinySimpleProgram.mFeatures.disableTextureIndex = true; + gSkinnedObjectShinySimpleProgram.mShaderFiles.clear(); + gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSkinnedObjectShinySimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gSkinnedObjectShinySimpleProgram.createShader(NULL, NULL); + } + + if (success) + { + gSkinnedObjectSimpleWaterProgram.mName = "Skinned Simple Water Shader"; + gSkinnedObjectSimpleWaterProgram.mFeatures.calculatesLighting = true; + gSkinnedObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true; + gSkinnedObjectSimpleWaterProgram.mFeatures.hasGamma = true; + gSkinnedObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true; + gSkinnedObjectSimpleWaterProgram.mFeatures.hasLighting = true; + gSkinnedObjectSimpleWaterProgram.mFeatures.disableTextureIndex = true; + gSkinnedObjectSimpleWaterProgram.mFeatures.hasWaterFog = true; + gSkinnedObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gSkinnedObjectSimpleWaterProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectSimpleWaterProgram.mFeatures.disableTextureIndex = true; + gSkinnedObjectSimpleWaterProgram.mFeatures.hasAlphaMask = true; + gSkinnedObjectSimpleWaterProgram.mShaderFiles.clear(); + gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSkinnedObjectSimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gSkinnedObjectSimpleWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gSkinnedObjectFullbrightWaterProgram.mName = "Skinned Fullbright Water Shader"; + gSkinnedObjectFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true; + gSkinnedObjectFullbrightWaterProgram.mFeatures.hasGamma = true; + gSkinnedObjectFullbrightWaterProgram.mFeatures.hasTransport = true; + gSkinnedObjectFullbrightWaterProgram.mFeatures.isFullbright = true; + gSkinnedObjectFullbrightWaterProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectFullbrightWaterProgram.mFeatures.hasAlphaMask = true; + gSkinnedObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true; + gSkinnedObjectFullbrightWaterProgram.mFeatures.disableTextureIndex = true; + gSkinnedObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gSkinnedObjectFullbrightWaterProgram.mShaderFiles.clear(); + gSkinnedObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gSkinnedObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSkinnedObjectFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gSkinnedObjectFullbrightWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gSkinnedObjectFullbrightShinyWaterProgram.mName = "Skinned Fullbright Shiny Water Shader"; + gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.calculatesAtmospherics = true; + gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasGamma = true; + gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasTransport = true; + gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isShiny = true; + gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true; + gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasAlphaMask = true; + gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true; + gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.disableTextureIndex = true; + gSkinnedObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.clear(); + gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSkinnedObjectFullbrightShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gSkinnedObjectFullbrightShinyWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gSkinnedObjectShinySimpleWaterProgram.mName = "Skinned Shiny Simple Water Shader"; + gSkinnedObjectShinySimpleWaterProgram.mFeatures.calculatesLighting = true; + gSkinnedObjectShinySimpleWaterProgram.mFeatures.calculatesAtmospherics = true; + gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasGamma = true; + gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasAtmospherics = true; + gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasAlphaMask = true; + gSkinnedObjectShinySimpleWaterProgram.mFeatures.isShiny = true; + gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasWaterFog = true; + gSkinnedObjectShinySimpleWaterProgram.mFeatures.disableTextureIndex = true; + gSkinnedObjectShinySimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.clear(); + gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSkinnedObjectShinySimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gSkinnedObjectShinySimpleWaterProgram.createShader(NULL, NULL); + } + } + + if( !success ) + { + mShaderLevel[SHADER_OBJECT] = 0; + return FALSE; + } + + return TRUE; } BOOL LLViewerShaderMgr::loadShadersAvatar() { - BOOL success = TRUE; - - if (mShaderLevel[SHADER_AVATAR] == 0) - { - gAvatarProgram.unload(); - gAvatarWaterProgram.unload(); - gAvatarEyeballProgram.unload(); - gAvatarPickProgram.unload(); - return TRUE; - } - - if (success) - { - gAvatarProgram.mName = "Avatar Shader"; - gAvatarProgram.mFeatures.hasSkinning = true; - gAvatarProgram.mFeatures.calculatesAtmospherics = true; - gAvatarProgram.mFeatures.calculatesLighting = true; - gAvatarProgram.mFeatures.hasGamma = true; - gAvatarProgram.mFeatures.hasAtmospherics = true; - gAvatarProgram.mFeatures.hasLighting = true; - gAvatarProgram.mFeatures.hasAlphaMask = true; - gAvatarProgram.mFeatures.disableTextureIndex = true; - gAvatarProgram.mShaderFiles.clear(); - gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB)); - gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER_ARB)); - gAvatarProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR]; - success = gAvatarProgram.createShader(NULL, NULL); - - if (success) - { - gAvatarWaterProgram.mName = "Avatar Water Shader"; - gAvatarWaterProgram.mFeatures.hasSkinning = true; - gAvatarWaterProgram.mFeatures.calculatesAtmospherics = true; - gAvatarWaterProgram.mFeatures.calculatesLighting = true; - gAvatarWaterProgram.mFeatures.hasWaterFog = true; - gAvatarWaterProgram.mFeatures.hasAtmospherics = true; - gAvatarWaterProgram.mFeatures.hasLighting = true; - gAvatarWaterProgram.mFeatures.hasAlphaMask = true; - gAvatarWaterProgram.mFeatures.disableTextureIndex = true; - gAvatarWaterProgram.mShaderFiles.clear(); - gAvatarWaterProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB)); - gAvatarWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - // Note: no cloth under water: - gAvatarWaterProgram.mShaderLevel = llmin(mShaderLevel[SHADER_AVATAR], 1); - gAvatarWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gAvatarWaterProgram.createShader(NULL, NULL); - } - - /// Keep track of avatar levels - if (gAvatarProgram.mShaderLevel != mShaderLevel[SHADER_AVATAR]) - { - mMaxAvatarShaderLevel = mShaderLevel[SHADER_AVATAR] = gAvatarProgram.mShaderLevel; - } - } - - if (success) - { - gAvatarPickProgram.mName = "Avatar Pick Shader"; - gAvatarPickProgram.mFeatures.hasSkinning = true; - gAvatarPickProgram.mFeatures.disableTextureIndex = true; - gAvatarPickProgram.mShaderFiles.clear(); - gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER_ARB)); - gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER_ARB)); - gAvatarPickProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR]; - success = gAvatarPickProgram.createShader(NULL, NULL); - } - - if (success) - { - gAvatarEyeballProgram.mName = "Avatar Eyeball Program"; - gAvatarEyeballProgram.mFeatures.calculatesLighting = true; - gAvatarEyeballProgram.mFeatures.isSpecular = true; - gAvatarEyeballProgram.mFeatures.calculatesAtmospherics = true; - gAvatarEyeballProgram.mFeatures.hasGamma = true; - gAvatarEyeballProgram.mFeatures.hasAtmospherics = true; - gAvatarEyeballProgram.mFeatures.hasLighting = true; - gAvatarEyeballProgram.mFeatures.hasAlphaMask = true; - gAvatarEyeballProgram.mFeatures.disableTextureIndex = true; - gAvatarEyeballProgram.mShaderFiles.clear(); - gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER_ARB)); - gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER_ARB)); - gAvatarEyeballProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR]; - success = gAvatarEyeballProgram.createShader(NULL, NULL); - } - - if( !success ) - { - mShaderLevel[SHADER_AVATAR] = 0; - mMaxAvatarShaderLevel = 0; - return FALSE; - } - - return TRUE; + BOOL success = TRUE; + + if (mShaderLevel[SHADER_AVATAR] == 0) + { + gAvatarProgram.unload(); + gAvatarWaterProgram.unload(); + gAvatarEyeballProgram.unload(); + gAvatarPickProgram.unload(); + return TRUE; + } + + if (success) + { + gAvatarProgram.mName = "Avatar Shader"; + gAvatarProgram.mFeatures.hasSkinning = true; + gAvatarProgram.mFeatures.calculatesAtmospherics = true; + gAvatarProgram.mFeatures.calculatesLighting = true; + gAvatarProgram.mFeatures.hasGamma = true; + gAvatarProgram.mFeatures.hasAtmospherics = true; + gAvatarProgram.mFeatures.hasLighting = true; + gAvatarProgram.mFeatures.hasAlphaMask = true; + gAvatarProgram.mFeatures.disableTextureIndex = true; + gAvatarProgram.mShaderFiles.clear(); + gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB)); + gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER_ARB)); + gAvatarProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR]; + success = gAvatarProgram.createShader(NULL, NULL); + + if (success) + { + gAvatarWaterProgram.mName = "Avatar Water Shader"; + gAvatarWaterProgram.mFeatures.hasSkinning = true; + gAvatarWaterProgram.mFeatures.calculatesAtmospherics = true; + gAvatarWaterProgram.mFeatures.calculatesLighting = true; + gAvatarWaterProgram.mFeatures.hasWaterFog = true; + gAvatarWaterProgram.mFeatures.hasAtmospherics = true; + gAvatarWaterProgram.mFeatures.hasLighting = true; + gAvatarWaterProgram.mFeatures.hasAlphaMask = true; + gAvatarWaterProgram.mFeatures.disableTextureIndex = true; + gAvatarWaterProgram.mShaderFiles.clear(); + gAvatarWaterProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB)); + gAvatarWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + // Note: no cloth under water: + gAvatarWaterProgram.mShaderLevel = llmin(mShaderLevel[SHADER_AVATAR], 1); + gAvatarWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gAvatarWaterProgram.createShader(NULL, NULL); + } + + /// Keep track of avatar levels + if (gAvatarProgram.mShaderLevel != mShaderLevel[SHADER_AVATAR]) + { + mMaxAvatarShaderLevel = mShaderLevel[SHADER_AVATAR] = gAvatarProgram.mShaderLevel; + } + } + + if (success) + { + gAvatarPickProgram.mName = "Avatar Pick Shader"; + gAvatarPickProgram.mFeatures.hasSkinning = true; + gAvatarPickProgram.mFeatures.disableTextureIndex = true; + gAvatarPickProgram.mShaderFiles.clear(); + gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER_ARB)); + gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER_ARB)); + gAvatarPickProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR]; + success = gAvatarPickProgram.createShader(NULL, NULL); + } + + if (success) + { + gAvatarEyeballProgram.mName = "Avatar Eyeball Program"; + gAvatarEyeballProgram.mFeatures.calculatesLighting = true; + gAvatarEyeballProgram.mFeatures.isSpecular = true; + gAvatarEyeballProgram.mFeatures.calculatesAtmospherics = true; + gAvatarEyeballProgram.mFeatures.hasGamma = true; + gAvatarEyeballProgram.mFeatures.hasAtmospherics = true; + gAvatarEyeballProgram.mFeatures.hasLighting = true; + gAvatarEyeballProgram.mFeatures.hasAlphaMask = true; + gAvatarEyeballProgram.mFeatures.disableTextureIndex = true; + gAvatarEyeballProgram.mShaderFiles.clear(); + gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER_ARB)); + gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER_ARB)); + gAvatarEyeballProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR]; + success = gAvatarEyeballProgram.createShader(NULL, NULL); + } + + if( !success ) + { + mShaderLevel[SHADER_AVATAR] = 0; + mMaxAvatarShaderLevel = 0; + return FALSE; + } + + return TRUE; } BOOL LLViewerShaderMgr::loadShadersInterface() { - BOOL success = TRUE; - - if (mShaderLevel[SHADER_INTERFACE] == 0) - { - gHighlightProgram.unload(); - return TRUE; - } - - if (success) - { - gHighlightProgram.mName = "Highlight Shader"; - gHighlightProgram.mShaderFiles.clear(); - gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER_ARB)); - gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gHighlightProgram.createShader(NULL, NULL); - } - - if (success) - { - gHighlightNormalProgram.mName = "Highlight Normals Shader"; - gHighlightNormalProgram.mShaderFiles.clear(); - gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER_ARB)); - gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gHighlightNormalProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gHighlightNormalProgram.createShader(NULL, NULL); - } - - if (success) - { - gHighlightSpecularProgram.mName = "Highlight Spec Shader"; - gHighlightSpecularProgram.mShaderFiles.clear(); - gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER_ARB)); - gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gHighlightSpecularProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gHighlightSpecularProgram.createShader(NULL, NULL); - } - - if (success) - { - gUIProgram.mName = "UI Shader"; - gUIProgram.mShaderFiles.clear(); - gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER_ARB)); - gUIProgram.mShaderFiles.push_back(make_pair("interface/uiF.glsl", GL_FRAGMENT_SHADER_ARB)); - gUIProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gUIProgram.createShader(NULL, NULL); - } - - if (success) - { - gPathfindingProgram.mName = "Pathfinding Shader"; - gPathfindingProgram.mShaderFiles.clear(); - gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingV.glsl", GL_VERTEX_SHADER_ARB)); - gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER_ARB)); - gPathfindingProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gPathfindingProgram.createShader(NULL, NULL); - } - - if (success) - { - gPathfindingNoNormalsProgram.mName = "PathfindingNoNormals Shader"; - gPathfindingNoNormalsProgram.mShaderFiles.clear(); - gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingNoNormalV.glsl", GL_VERTEX_SHADER_ARB)); - gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER_ARB)); - gPathfindingNoNormalsProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gPathfindingNoNormalsProgram.createShader(NULL, NULL); - } - - if (success) - { - gCustomAlphaProgram.mName = "Custom Alpha Shader"; - gCustomAlphaProgram.mShaderFiles.clear(); - gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaV.glsl", GL_VERTEX_SHADER_ARB)); - gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaF.glsl", GL_FRAGMENT_SHADER_ARB)); - gCustomAlphaProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gCustomAlphaProgram.createShader(NULL, NULL); - } - - if (success) - { - gSplatTextureRectProgram.mName = "Splat Texture Rect Shader"; - gSplatTextureRectProgram.mShaderFiles.clear(); - gSplatTextureRectProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER_ARB)); - gSplatTextureRectProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectF.glsl", GL_FRAGMENT_SHADER_ARB)); - gSplatTextureRectProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gSplatTextureRectProgram.createShader(NULL, NULL); - if (success) - { - gSplatTextureRectProgram.bind(); - gSplatTextureRectProgram.uniform1i(sScreenMap, 0); - gSplatTextureRectProgram.unbind(); - } - } - - if (success) - { - gGlowCombineProgram.mName = "Glow Combine Shader"; - gGlowCombineProgram.mShaderFiles.clear(); - gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineV.glsl", GL_VERTEX_SHADER_ARB)); - gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineF.glsl", GL_FRAGMENT_SHADER_ARB)); - gGlowCombineProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gGlowCombineProgram.createShader(NULL, NULL); - if (success) - { - gGlowCombineProgram.bind(); - gGlowCombineProgram.uniform1i(sGlowMap, 0); - gGlowCombineProgram.uniform1i(sScreenMap, 1); - gGlowCombineProgram.unbind(); - } - } - - if (success) - { - gGlowCombineFXAAProgram.mName = "Glow CombineFXAA Shader"; - gGlowCombineFXAAProgram.mShaderFiles.clear(); - gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER_ARB)); - gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER_ARB)); - gGlowCombineFXAAProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gGlowCombineFXAAProgram.createShader(NULL, NULL); - if (success) - { - gGlowCombineFXAAProgram.bind(); - gGlowCombineFXAAProgram.uniform1i(sGlowMap, 0); - gGlowCombineFXAAProgram.uniform1i(sScreenMap, 1); - gGlowCombineFXAAProgram.unbind(); - } - } - - - if (success) - { - gTwoTextureAddProgram.mName = "Two Texture Add Shader"; - gTwoTextureAddProgram.mShaderFiles.clear(); - gTwoTextureAddProgram.mShaderFiles.push_back(make_pair("interface/twotextureaddV.glsl", GL_VERTEX_SHADER_ARB)); - gTwoTextureAddProgram.mShaderFiles.push_back(make_pair("interface/twotextureaddF.glsl", GL_FRAGMENT_SHADER_ARB)); - gTwoTextureAddProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gTwoTextureAddProgram.createShader(NULL, NULL); - if (success) - { - gTwoTextureAddProgram.bind(); - gTwoTextureAddProgram.uniform1i(sTex0, 0); - gTwoTextureAddProgram.uniform1i(sTex1, 1); - } - } + BOOL success = TRUE; + + if (mShaderLevel[SHADER_INTERFACE] == 0) + { + gHighlightProgram.unload(); + return TRUE; + } + + if (success) + { + gHighlightProgram.mName = "Highlight Shader"; + gHighlightProgram.mShaderFiles.clear(); + gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER_ARB)); + gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gHighlightProgram.createShader(NULL, NULL); + } + + if (success) + { + gHighlightNormalProgram.mName = "Highlight Normals Shader"; + gHighlightNormalProgram.mShaderFiles.clear(); + gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER_ARB)); + gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gHighlightNormalProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gHighlightNormalProgram.createShader(NULL, NULL); + } + + if (success) + { + gHighlightSpecularProgram.mName = "Highlight Spec Shader"; + gHighlightSpecularProgram.mShaderFiles.clear(); + gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER_ARB)); + gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gHighlightSpecularProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gHighlightSpecularProgram.createShader(NULL, NULL); + } + + if (success) + { + gUIProgram.mName = "UI Shader"; + gUIProgram.mShaderFiles.clear(); + gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER_ARB)); + gUIProgram.mShaderFiles.push_back(make_pair("interface/uiF.glsl", GL_FRAGMENT_SHADER_ARB)); + gUIProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gUIProgram.createShader(NULL, NULL); + } + + if (success) + { + gPathfindingProgram.mName = "Pathfinding Shader"; + gPathfindingProgram.mShaderFiles.clear(); + gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingV.glsl", GL_VERTEX_SHADER_ARB)); + gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER_ARB)); + gPathfindingProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gPathfindingProgram.createShader(NULL, NULL); + } + + if (success) + { + gPathfindingNoNormalsProgram.mName = "PathfindingNoNormals Shader"; + gPathfindingNoNormalsProgram.mShaderFiles.clear(); + gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingNoNormalV.glsl", GL_VERTEX_SHADER_ARB)); + gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER_ARB)); + gPathfindingNoNormalsProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gPathfindingNoNormalsProgram.createShader(NULL, NULL); + } + + if (success) + { + gCustomAlphaProgram.mName = "Custom Alpha Shader"; + gCustomAlphaProgram.mShaderFiles.clear(); + gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaV.glsl", GL_VERTEX_SHADER_ARB)); + gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaF.glsl", GL_FRAGMENT_SHADER_ARB)); + gCustomAlphaProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gCustomAlphaProgram.createShader(NULL, NULL); + } + + if (success) + { + gSplatTextureRectProgram.mName = "Splat Texture Rect Shader"; + gSplatTextureRectProgram.mShaderFiles.clear(); + gSplatTextureRectProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER_ARB)); + gSplatTextureRectProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSplatTextureRectProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gSplatTextureRectProgram.createShader(NULL, NULL); + if (success) + { + gSplatTextureRectProgram.bind(); + gSplatTextureRectProgram.uniform1i(sScreenMap, 0); + gSplatTextureRectProgram.unbind(); + } + } + + if (success) + { + gGlowCombineProgram.mName = "Glow Combine Shader"; + gGlowCombineProgram.mShaderFiles.clear(); + gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineV.glsl", GL_VERTEX_SHADER_ARB)); + gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineF.glsl", GL_FRAGMENT_SHADER_ARB)); + gGlowCombineProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gGlowCombineProgram.createShader(NULL, NULL); + if (success) + { + gGlowCombineProgram.bind(); + gGlowCombineProgram.uniform1i(sGlowMap, 0); + gGlowCombineProgram.uniform1i(sScreenMap, 1); + gGlowCombineProgram.unbind(); + } + } + + if (success) + { + gGlowCombineFXAAProgram.mName = "Glow CombineFXAA Shader"; + gGlowCombineFXAAProgram.mShaderFiles.clear(); + gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER_ARB)); + gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER_ARB)); + gGlowCombineFXAAProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gGlowCombineFXAAProgram.createShader(NULL, NULL); + if (success) + { + gGlowCombineFXAAProgram.bind(); + gGlowCombineFXAAProgram.uniform1i(sGlowMap, 0); + gGlowCombineFXAAProgram.uniform1i(sScreenMap, 1); + gGlowCombineFXAAProgram.unbind(); + } + } + + + if (success) + { + gTwoTextureAddProgram.mName = "Two Texture Add Shader"; + gTwoTextureAddProgram.mShaderFiles.clear(); + gTwoTextureAddProgram.mShaderFiles.push_back(make_pair("interface/twotextureaddV.glsl", GL_VERTEX_SHADER_ARB)); + gTwoTextureAddProgram.mShaderFiles.push_back(make_pair("interface/twotextureaddF.glsl", GL_FRAGMENT_SHADER_ARB)); + gTwoTextureAddProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gTwoTextureAddProgram.createShader(NULL, NULL); + if (success) + { + gTwoTextureAddProgram.bind(); + gTwoTextureAddProgram.uniform1i(sTex0, 0); + gTwoTextureAddProgram.uniform1i(sTex1, 1); + } + } #ifdef LL_WINDOWS - if (success) - { - gTwoTextureCompareProgram.mName = "Two Texture Compare Shader"; - gTwoTextureCompareProgram.mShaderFiles.clear(); - gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareV.glsl", GL_VERTEX_SHADER_ARB)); - gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareF.glsl", GL_FRAGMENT_SHADER_ARB)); - gTwoTextureCompareProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gTwoTextureCompareProgram.createShader(NULL, NULL); - if (success) - { - gTwoTextureCompareProgram.bind(); - gTwoTextureCompareProgram.uniform1i(sTex0, 0); - gTwoTextureCompareProgram.uniform1i(sTex1, 1); - gTwoTextureCompareProgram.uniform1i(sDitherTex, 2); - } - } - - if (success) - { - gOneTextureFilterProgram.mName = "One Texture Filter Shader"; - gOneTextureFilterProgram.mShaderFiles.clear(); - gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER_ARB)); - gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gOneTextureFilterProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gOneTextureFilterProgram.createShader(NULL, NULL); - if (success) - { - gOneTextureFilterProgram.bind(); - gOneTextureFilterProgram.uniform1i(sTex0, 0); - } - } + if (success) + { + gTwoTextureCompareProgram.mName = "Two Texture Compare Shader"; + gTwoTextureCompareProgram.mShaderFiles.clear(); + gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareV.glsl", GL_VERTEX_SHADER_ARB)); + gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareF.glsl", GL_FRAGMENT_SHADER_ARB)); + gTwoTextureCompareProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gTwoTextureCompareProgram.createShader(NULL, NULL); + if (success) + { + gTwoTextureCompareProgram.bind(); + gTwoTextureCompareProgram.uniform1i(sTex0, 0); + gTwoTextureCompareProgram.uniform1i(sTex1, 1); + gTwoTextureCompareProgram.uniform1i(sDitherTex, 2); + } + } + + if (success) + { + gOneTextureFilterProgram.mName = "One Texture Filter Shader"; + gOneTextureFilterProgram.mShaderFiles.clear(); + gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER_ARB)); + gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gOneTextureFilterProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gOneTextureFilterProgram.createShader(NULL, NULL); + if (success) + { + gOneTextureFilterProgram.bind(); + gOneTextureFilterProgram.uniform1i(sTex0, 0); + } + } #endif - if (success) - { - gOneTextureNoColorProgram.mName = "One Texture No Color Shader"; - gOneTextureNoColorProgram.mShaderFiles.clear(); - gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorV.glsl", GL_VERTEX_SHADER_ARB)); - gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorF.glsl", GL_FRAGMENT_SHADER_ARB)); - gOneTextureNoColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gOneTextureNoColorProgram.createShader(NULL, NULL); - if (success) - { - gOneTextureNoColorProgram.bind(); - gOneTextureNoColorProgram.uniform1i(sTex0, 0); - } - } - - if (success) - { - gSolidColorProgram.mName = "Solid Color Shader"; - gSolidColorProgram.mShaderFiles.clear(); - gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorV.glsl", GL_VERTEX_SHADER_ARB)); - gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorF.glsl", GL_FRAGMENT_SHADER_ARB)); - gSolidColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gSolidColorProgram.createShader(NULL, NULL); - if (success) - { - gSolidColorProgram.bind(); - gSolidColorProgram.uniform1i(sTex0, 0); - gSolidColorProgram.unbind(); - } - } - - if (success) - { - gOcclusionProgram.mName = "Occlusion Shader"; - gOcclusionProgram.mShaderFiles.clear(); - gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionV.glsl", GL_VERTEX_SHADER_ARB)); - gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB)); - gOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gOcclusionProgram.createShader(NULL, NULL); - } - - if (success) - { - gOcclusionCubeProgram.mName = "Occlusion Cube Shader"; - gOcclusionCubeProgram.mShaderFiles.clear(); - gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER_ARB)); - gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB)); - gOcclusionCubeProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gOcclusionCubeProgram.createShader(NULL, NULL); - } - - if (success) - { - gDebugProgram.mName = "Debug Shader"; - gDebugProgram.mShaderFiles.clear(); - gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER_ARB)); - gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDebugProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gDebugProgram.createShader(NULL, NULL); - } - - if (success) - { - gClipProgram.mName = "Clip Shader"; - gClipProgram.mShaderFiles.clear(); - gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER_ARB)); - gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER_ARB)); - gClipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gClipProgram.createShader(NULL, NULL); - } - - if (success) - { - gDownsampleDepthProgram.mName = "DownsampleDepth Shader"; - gDownsampleDepthProgram.mShaderFiles.clear(); - gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER_ARB)); - gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDownsampleDepthProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gDownsampleDepthProgram.createShader(NULL, NULL); - } - - if (success) - { - gBenchmarkProgram.mName = "Benchmark Shader"; - gBenchmarkProgram.mShaderFiles.clear(); - gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER_ARB)); - gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER_ARB)); - gBenchmarkProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gBenchmarkProgram.createShader(NULL, NULL); - } - - if (success) - { - gDownsampleDepthRectProgram.mName = "DownsampleDepthRect Shader"; - gDownsampleDepthRectProgram.mShaderFiles.clear(); - gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER_ARB)); - gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthRectF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDownsampleDepthRectProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gDownsampleDepthRectProgram.createShader(NULL, NULL); - } - - if (success) - { - gAlphaMaskProgram.mName = "Alpha Mask Shader"; - gAlphaMaskProgram.mShaderFiles.clear(); - gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER_ARB)); - gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskF.glsl", GL_FRAGMENT_SHADER_ARB)); - gAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; - success = gAlphaMaskProgram.createShader(NULL, NULL); - } - - if( !success ) - { - mShaderLevel[SHADER_INTERFACE] = 0; - return FALSE; - } - - return TRUE; + if (success) + { + gOneTextureNoColorProgram.mName = "One Texture No Color Shader"; + gOneTextureNoColorProgram.mShaderFiles.clear(); + gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorV.glsl", GL_VERTEX_SHADER_ARB)); + gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorF.glsl", GL_FRAGMENT_SHADER_ARB)); + gOneTextureNoColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gOneTextureNoColorProgram.createShader(NULL, NULL); + if (success) + { + gOneTextureNoColorProgram.bind(); + gOneTextureNoColorProgram.uniform1i(sTex0, 0); + } + } + + if (success) + { + gSolidColorProgram.mName = "Solid Color Shader"; + gSolidColorProgram.mShaderFiles.clear(); + gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorV.glsl", GL_VERTEX_SHADER_ARB)); + gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSolidColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gSolidColorProgram.createShader(NULL, NULL); + if (success) + { + gSolidColorProgram.bind(); + gSolidColorProgram.uniform1i(sTex0, 0); + gSolidColorProgram.unbind(); + } + } + + if (success) + { + gOcclusionProgram.mName = "Occlusion Shader"; + gOcclusionProgram.mShaderFiles.clear(); + gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionV.glsl", GL_VERTEX_SHADER_ARB)); + gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB)); + gOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gOcclusionProgram.createShader(NULL, NULL); + } + + if (success) + { + gOcclusionCubeProgram.mName = "Occlusion Cube Shader"; + gOcclusionCubeProgram.mShaderFiles.clear(); + gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER_ARB)); + gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB)); + gOcclusionCubeProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gOcclusionCubeProgram.createShader(NULL, NULL); + } + + if (success) + { + gDebugProgram.mName = "Debug Shader"; + gDebugProgram.mShaderFiles.clear(); + gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER_ARB)); + gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDebugProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gDebugProgram.createShader(NULL, NULL); + } + + if (success) + { + gClipProgram.mName = "Clip Shader"; + gClipProgram.mShaderFiles.clear(); + gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER_ARB)); + gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER_ARB)); + gClipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gClipProgram.createShader(NULL, NULL); + } + + if (success) + { + gDownsampleDepthProgram.mName = "DownsampleDepth Shader"; + gDownsampleDepthProgram.mShaderFiles.clear(); + gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER_ARB)); + gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDownsampleDepthProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gDownsampleDepthProgram.createShader(NULL, NULL); + } + + if (success) + { + gBenchmarkProgram.mName = "Benchmark Shader"; + gBenchmarkProgram.mShaderFiles.clear(); + gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER_ARB)); + gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER_ARB)); + gBenchmarkProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gBenchmarkProgram.createShader(NULL, NULL); + } + + if (success) + { + gDownsampleDepthRectProgram.mName = "DownsampleDepthRect Shader"; + gDownsampleDepthRectProgram.mShaderFiles.clear(); + gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER_ARB)); + gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthRectF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDownsampleDepthRectProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gDownsampleDepthRectProgram.createShader(NULL, NULL); + } + + if (success) + { + gAlphaMaskProgram.mName = "Alpha Mask Shader"; + gAlphaMaskProgram.mShaderFiles.clear(); + gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER_ARB)); + gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskF.glsl", GL_FRAGMENT_SHADER_ARB)); + gAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gAlphaMaskProgram.createShader(NULL, NULL); + } + + if( !success ) + { + mShaderLevel[SHADER_INTERFACE] = 0; + return FALSE; + } + + return TRUE; } BOOL LLViewerShaderMgr::loadShadersWindLight() -{ - BOOL success = TRUE; +{ + BOOL success = TRUE; - if (mShaderLevel[SHADER_WINDLIGHT] < 2) - { - gWLSkyProgram.unload(); - gWLCloudProgram.unload(); - gWLCloudShadowProgram.unload(); - gWLSunProgram.unload(); - gWLMoonProgram.unload(); - gDownsampleMinMaxDepthRectProgram.unload(); - gInscatterRectProgram.unload(); - return TRUE; - } + if (mShaderLevel[SHADER_WINDLIGHT] < 2) + { + gWLSkyProgram.unload(); + gWLCloudProgram.unload(); + gWLSunProgram.unload(); + gWLMoonProgram.unload(); + return TRUE; + } if (success) { @@ -3830,7 +3790,6 @@ BOOL LLViewerShaderMgr::loadShadersWindLight() if (success) { gWLCloudProgram.mName = "Windlight Cloud Program"; - //gWLCloudProgram.mFeatures.hasGamma = true; gWLCloudProgram.mShaderFiles.clear(); gWLCloudProgram.mFeatures.calculatesAtmospherics = true; gWLCloudProgram.mFeatures.hasTransport = true; @@ -3842,21 +3801,6 @@ BOOL LLViewerShaderMgr::loadShadersWindLight() success = gWLCloudProgram.createShader(NULL, NULL); } - /* unused outside of ALM at the moment and failing to link on OSX for reasons only Timmy knows. - if (success) - { - gWLCloudShadowProgram.mName = "Windlight Cloud Shadow Program"; - gWLCloudShadowProgram.mShaderFiles.clear(); - gWLCloudShadowProgram.mFeatures.hasGamma = true; - gWLCloudShadowProgram.mFeatures.hasShadows = true; - gWLCloudShadowProgram.mFeatures.isDeferred = true; - gWLCloudShadowProgram.mShaderFiles.push_back(make_pair("windlight/cloudShadowV.glsl", GL_VERTEX_SHADER_ARB)); - gWLCloudShadowProgram.mShaderFiles.push_back(make_pair("windlight/cloudShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); - gWLCloudShadowProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT]; - gWLCloudShadowProgram.mShaderGroup = LLGLSLShader::SG_SKY; - success = gWLCloudShadowProgram.createShader(NULL, NULL); - }*/ - if (success) { gWLSunProgram.mName = "Windlight Sun Program"; @@ -3893,101 +3837,101 @@ BOOL LLViewerShaderMgr::loadShadersWindLight() success = gWLMoonProgram.createShader(NULL, NULL); } - return success; + return success; } BOOL LLViewerShaderMgr::loadTransformShaders() { - BOOL success = TRUE; - - if (mShaderLevel[SHADER_TRANSFORM] < 1) - { - gTransformPositionProgram.unload(); - gTransformTexCoordProgram.unload(); - gTransformNormalProgram.unload(); - gTransformColorProgram.unload(); - gTransformTangentProgram.unload(); - return TRUE; - } - - if (success) - { + BOOL success = TRUE; + + if (mShaderLevel[SHADER_TRANSFORM] < 1) + { + gTransformPositionProgram.unload(); + gTransformTexCoordProgram.unload(); + gTransformNormalProgram.unload(); + gTransformColorProgram.unload(); + gTransformTangentProgram.unload(); + return TRUE; + } + + if (success) + { gTransformPositionProgram.mName = "Position Transform Shader"; - gTransformPositionProgram.mShaderFiles.clear(); - gTransformPositionProgram.mShaderFiles.push_back(make_pair("transform/positionV.glsl", GL_VERTEX_SHADER_ARB)); - gTransformPositionProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - - const char* varyings[] = { - "position_out", - "texture_index_out", - }; - - success = gTransformPositionProgram.createShader(NULL, NULL, 2, varyings); - } - - if (success) - { - gTransformTexCoordProgram.mName = "TexCoord Transform Shader"; - gTransformTexCoordProgram.mShaderFiles.clear(); - gTransformTexCoordProgram.mShaderFiles.push_back(make_pair("transform/texcoordV.glsl", GL_VERTEX_SHADER_ARB)); - gTransformTexCoordProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - - const char* varyings[] = { - "texcoord_out", - }; - - success = gTransformTexCoordProgram.createShader(NULL, NULL, 1, varyings); - } - - if (success) - { - gTransformNormalProgram.mName = "Normal Transform Shader"; - gTransformNormalProgram.mShaderFiles.clear(); - gTransformNormalProgram.mShaderFiles.push_back(make_pair("transform/normalV.glsl", GL_VERTEX_SHADER_ARB)); - gTransformNormalProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - - const char* varyings[] = { - "normal_out", - }; - - success = gTransformNormalProgram.createShader(NULL, NULL, 1, varyings); - } - - if (success) - { - gTransformColorProgram.mName = "Color Transform Shader"; - gTransformColorProgram.mShaderFiles.clear(); - gTransformColorProgram.mShaderFiles.push_back(make_pair("transform/colorV.glsl", GL_VERTEX_SHADER_ARB)); - gTransformColorProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - - const char* varyings[] = { - "color_out", - }; - - success = gTransformColorProgram.createShader(NULL, NULL, 1, varyings); - } - - if (success) - { - gTransformTangentProgram.mName = "Binormal Transform Shader"; - gTransformTangentProgram.mShaderFiles.clear(); - gTransformTangentProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB)); + gTransformPositionProgram.mShaderFiles.clear(); + gTransformPositionProgram.mShaderFiles.push_back(make_pair("transform/positionV.glsl", GL_VERTEX_SHADER_ARB)); + gTransformPositionProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; + + const char* varyings[] = { + "position_out", + "texture_index_out", + }; + + success = gTransformPositionProgram.createShader(NULL, NULL, 2, varyings); + } + + if (success) + { + gTransformTexCoordProgram.mName = "TexCoord Transform Shader"; + gTransformTexCoordProgram.mShaderFiles.clear(); + gTransformTexCoordProgram.mShaderFiles.push_back(make_pair("transform/texcoordV.glsl", GL_VERTEX_SHADER_ARB)); + gTransformTexCoordProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; + + const char* varyings[] = { + "texcoord_out", + }; + + success = gTransformTexCoordProgram.createShader(NULL, NULL, 1, varyings); + } + + if (success) + { + gTransformNormalProgram.mName = "Normal Transform Shader"; + gTransformNormalProgram.mShaderFiles.clear(); + gTransformNormalProgram.mShaderFiles.push_back(make_pair("transform/normalV.glsl", GL_VERTEX_SHADER_ARB)); + gTransformNormalProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; + + const char* varyings[] = { + "normal_out", + }; + + success = gTransformNormalProgram.createShader(NULL, NULL, 1, varyings); + } + + if (success) + { + gTransformColorProgram.mName = "Color Transform Shader"; + gTransformColorProgram.mShaderFiles.clear(); + gTransformColorProgram.mShaderFiles.push_back(make_pair("transform/colorV.glsl", GL_VERTEX_SHADER_ARB)); + gTransformColorProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; + + const char* varyings[] = { + "color_out", + }; + + success = gTransformColorProgram.createShader(NULL, NULL, 1, varyings); + } + + if (success) + { + gTransformTangentProgram.mName = "Binormal Transform Shader"; + gTransformTangentProgram.mShaderFiles.clear(); + gTransformTangentProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB)); gTransformTangentProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - const char* varyings[] = { - "tangent_out", - }; - - success = gTransformTangentProgram.createShader(NULL, NULL, 1, varyings); - } + const char* varyings[] = { + "tangent_out", + }; + + success = gTransformTangentProgram.createShader(NULL, NULL, 1, varyings); + } - - return success; + + return success; } std::string LLViewerShaderMgr::getShaderDirPrefix(void) { - return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class"); + return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class"); } void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader * shader) @@ -3997,11 +3941,11 @@ void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader * shader) LLViewerShaderMgr::shader_iter LLViewerShaderMgr::beginShaders() const { - return mShaderList.begin(); + return mShaderList.begin(); } LLViewerShaderMgr::shader_iter LLViewerShaderMgr::endShaders() const { - return mShaderList.end(); + return mShaderList.end(); } diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 8e1801612e..66cb80657f 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -166,8 +166,6 @@ extern LLGLSLShader gDebugProgram; extern LLGLSLShader gClipProgram; extern LLGLSLShader gDownsampleDepthProgram; extern LLGLSLShader gDownsampleDepthRectProgram; -extern LLGLSLShader gDownsampleMinMaxDepthRectProgram; -extern LLGLSLShader gInscatterRectProgram; extern LLGLSLShader gBenchmarkProgram; //output tex0[tc0] + tex1[tc1] @@ -262,7 +260,6 @@ extern LLGLSLShader gImpostorProgram; // WindLight shader handles extern LLGLSLShader gWLSkyProgram; extern LLGLSLShader gWLCloudProgram; -extern LLGLSLShader gWLCloudShadowProgram; extern LLGLSLShader gWLSunProgram; extern LLGLSLShader gWLMoonProgram; @@ -320,7 +317,6 @@ extern LLGLSLShader gDeferredAvatarEyesProgram; extern LLGLSLShader gDeferredAvatarAlphaProgram; extern LLGLSLShader gDeferredWLSkyProgram; extern LLGLSLShader gDeferredWLCloudProgram; -extern LLGLSLShader gDeferredWLCloudShadowProgram; extern LLGLSLShader gDeferredWLSunProgram; extern LLGLSLShader gDeferredWLMoonProgram; extern LLGLSLShader gDeferredStarProgram; @@ -329,7 +325,6 @@ extern LLGLSLShader gDeferredSkinnedFullbrightShinyProgram; extern LLGLSLShader gDeferredSkinnedFullbrightProgram; extern LLGLSLShader gNormalMapGenProgram; - // Deferred materials shaders extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; extern LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2]; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 507936190a..1ba7a7b2b9 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1193,12 +1193,12 @@ void LLViewerFetchedTexture::loadFromFastCache() { return; //no need to access the fast cache. } - mInFastCacheList = FALSE; + mInFastCacheList = FALSE; mRawImage = LLAppViewer::getTextureCache()->readFromFastCache(getID(), mRawDiscardLevel); if(mRawImage.notNull()) { - mFullWidth = mRawImage->getWidth() << mRawDiscardLevel; + mFullWidth = mRawImage->getWidth() << mRawDiscardLevel; mFullHeight = mRawImage->getHeight() << mRawDiscardLevel; setTexelsPerImage(); @@ -1213,20 +1213,20 @@ void LLViewerFetchedTexture::loadFromFastCache() else { if (mBoostLevel == LLGLTexture::BOOST_ICON) - { - S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS; - S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS; - if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)) { - // scale oversized icon, no need to give more work to gl - mRawImage->scale(expected_width, expected_height); - } + S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS; + S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS; + if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)) + { + // scale oversized icon, no need to give more work to gl + mRawImage->scale(expected_width, expected_height); + } } - mRequestedDiscardLevel = mDesiredDiscardLevel + 1; - mIsRawImageValid = TRUE; - addToCreateTexture(); - } + mRequestedDiscardLevel = mDesiredDiscardLevel + 1; + mIsRawImageValid = TRUE; + addToCreateTexture(); + } } } @@ -1989,7 +1989,7 @@ bool LLViewerFetchedTexture::updateFetch() mIsFetched = TRUE; tester->updateTextureLoadingStats(this, mRawImage, LLAppViewer::getTextureFetch()->isFromLocalCache(mID)); } - mRawDiscardLevel = fetch_discard; + mRawDiscardLevel = fetch_discard; if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) && (current_discard < 0 || mRawDiscardLevel < current_discard)) { diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 11cf303753..3421b99ba4 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4608,7 +4608,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei // PRE SNAPSHOT gDisplaySwapBuffers = FALSE; - + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); setCursor(UI_CURSOR_WAIT); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 9c761cc4a6..671f4d49a7 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2345,7 +2345,7 @@ bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture) switch(range_it->second.map) { - case LLRender::DIFFUSE_MAP: + case LLRender::DIFFUSE_MAP: { if(LLMaterial::DIFFUSE_ALPHA_MODE_NONE != cur_material->getDiffuseAlphaMode()) { //missing texture + !LLMaterial::DIFFUSE_ALPHA_MODE_NONE => LLMaterial::DIFFUSE_ALPHA_MODE_NONE diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index 08bb2d2b2b..37689e0683 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -99,7 +99,7 @@ LLDrawable * LLVOWLSky::createDrawable(LLPipeline * pipeline) inline F32 LLVOWLSky::calcPhi(U32 i) { - // i should range from [0..SKY_STACKS] so t will range from [0.f .. 1.f] + // i should range from [0..SKY_STACKS] so t will range from [0.f .. 1.f] F32 t = float(i) / float(getNumStacks()); // ^4 the parameter of the tesselation to bias things toward 0 (the dome's apex) diff --git a/indra/newview/llvowlsky.h b/indra/newview/llvowlsky.h index c52acba98b..73ecf1a717 100644 --- a/indra/newview/llvowlsky.h +++ b/indra/newview/llvowlsky.h @@ -81,9 +81,9 @@ private: std::vector< LLPointer<LLVertexBuffer> > mStripsVerts; LLPointer<LLVertexBuffer> mStarsVerts; - std::vector<LLVector3> mStarVertices; // Star verticies - std::vector<LLColor4> mStarColors; // Star colors - std::vector<F32> mStarIntensities; // Star intensities + std::vector<LLVector3> mStarVertices; // Star verticies + std::vector<LLColor4> mStarColors; // Star colors + std::vector<F32> mStarIntensities; // Star intensities }; #endif // LL_VOWLSKY_H diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp index 2760ebd1df..768db047a4 100644 --- a/indra/newview/llweb.cpp +++ b/indra/newview/llweb.cpp @@ -268,9 +268,12 @@ bool LLWeb::useExternalBrowser(const std::string &url) boost::match_results<std::string::const_iterator> matches; return !(boost::regex_search(uri_string, matches, pattern)); } - - boost::regex pattern = boost::regex("^mailto:", boost::regex::perl | boost::regex::icase); - boost::match_results<std::string::const_iterator> matches; - return boost::regex_search(url, matches, pattern); + else + { + boost::regex pattern = boost::regex("^mailto:", boost::regex::perl | boost::regex::icase); + boost::match_results<std::string::const_iterator> matches; + return boost::regex_search(url, matches, pattern); + } + return false; #endif } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 6e7e8eef21..c3bccfd19b 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -43,7 +43,7 @@ #include "llui.h" #include "llglheaders.h" #include "llrender.h" -#include "llwindow.h" // swapBuffers() +#include "llwindow.h" // swapBuffers() // newview includes #include "llagent.h" @@ -217,9 +217,9 @@ extern S32 gBoxFrame; extern BOOL gDisplaySwapBuffers; extern BOOL gDebugGL; -bool gAvatarBacklight = false; +bool gAvatarBacklight = false; -bool gDebugPipeline = false; +bool gDebugPipeline = false; LLPipeline gPipeline; const LLMatrix4* gGLLastMatrix = NULL; @@ -277,26 +277,26 @@ static LLStaticHashedString sKernScale("kern_scale"); //---------------------------------------- std::string gPoolNames[] = { - // Correspond to LLDrawpool enum render type - "NONE", - "POOL_SIMPLE", - "POOL_GROUND", - "POOL_FULLBRIGHT", - "POOL_BUMP", - "POOL_MATERIALS", - "POOL_TERRAIN," - "POOL_SKY", - "POOL_WL_SKY", - "POOL_TREE", - "POOL_ALPHA_MASK", - "POOL_FULLBRIGHT_ALPHA_MASK", - "POOL_GRASS", - "POOL_INVISIBLE", - "POOL_AVATAR", - "POOL_VOIDWATER", - "POOL_WATER", - "POOL_GLOW", - "POOL_ALPHA" + // Correspond to LLDrawpool enum render type + "NONE", + "POOL_SIMPLE", + "POOL_GROUND", + "POOL_FULLBRIGHT", + "POOL_BUMP", + "POOL_MATERIALS", + "POOL_TERRAIN," + "POOL_SKY", + "POOL_WL_SKY", + "POOL_TREE", + "POOL_ALPHA_MASK", + "POOL_FULLBRIGHT_ALPHA_MASK", + "POOL_GRASS", + "POOL_INVISIBLE", + "POOL_AVATAR", + "POOL_VOIDWATER", + "POOL_WATER", + "POOL_GLOW", + "POOL_ALPHA" }; void drawBox(const LLVector4a& c, const LLVector4a& r); @@ -307,48 +307,48 @@ LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage); void display_update_camera(); //---------------------------------------- -S32 LLPipeline::sCompiles = 0; - -bool LLPipeline::sPickAvatar = true; -bool LLPipeline::sDynamicLOD = true; -bool LLPipeline::sShowHUDAttachments = true; -bool LLPipeline::sRenderMOAPBeacons = false; -bool LLPipeline::sRenderPhysicalBeacons = true; -bool LLPipeline::sRenderScriptedBeacons = false; -bool LLPipeline::sRenderScriptedTouchBeacons = true; -bool LLPipeline::sRenderParticleBeacons = false; -bool LLPipeline::sRenderSoundBeacons = false; -bool LLPipeline::sRenderBeacons = false; -bool LLPipeline::sRenderHighlight = true; +S32 LLPipeline::sCompiles = 0; + +bool LLPipeline::sPickAvatar = true; +bool LLPipeline::sDynamicLOD = true; +bool LLPipeline::sShowHUDAttachments = true; +bool LLPipeline::sRenderMOAPBeacons = false; +bool LLPipeline::sRenderPhysicalBeacons = true; +bool LLPipeline::sRenderScriptedBeacons = false; +bool LLPipeline::sRenderScriptedTouchBeacons = true; +bool LLPipeline::sRenderParticleBeacons = false; +bool LLPipeline::sRenderSoundBeacons = false; +bool LLPipeline::sRenderBeacons = false; +bool LLPipeline::sRenderHighlight = true; LLRender::eTexIndex LLPipeline::sRenderHighlightTextureChannel = LLRender::DIFFUSE_MAP; -bool LLPipeline::sForceOldBakedUpload = false; -S32 LLPipeline::sUseOcclusion = 0; -bool LLPipeline::sDelayVBUpdate = true; -bool LLPipeline::sAutoMaskAlphaDeferred = true; -bool LLPipeline::sAutoMaskAlphaNonDeferred = false; -bool LLPipeline::sDisableShaders = false; -bool LLPipeline::sRenderBump = true; -bool LLPipeline::sBakeSunlight = false; -bool LLPipeline::sNoAlpha = false; -bool LLPipeline::sUseTriStrips = true; -bool LLPipeline::sUseFarClip = true; -bool LLPipeline::sShadowRender = false; -bool LLPipeline::sWaterReflections = false; -bool LLPipeline::sRenderGlow = false; -bool LLPipeline::sReflectionRender = false; +bool LLPipeline::sForceOldBakedUpload = false; +S32 LLPipeline::sUseOcclusion = 0; +bool LLPipeline::sDelayVBUpdate = true; +bool LLPipeline::sAutoMaskAlphaDeferred = true; +bool LLPipeline::sAutoMaskAlphaNonDeferred = false; +bool LLPipeline::sDisableShaders = false; +bool LLPipeline::sRenderBump = true; +bool LLPipeline::sBakeSunlight = false; +bool LLPipeline::sNoAlpha = false; +bool LLPipeline::sUseTriStrips = true; +bool LLPipeline::sUseFarClip = true; +bool LLPipeline::sShadowRender = false; +bool LLPipeline::sWaterReflections = false; +bool LLPipeline::sRenderGlow = false; +bool LLPipeline::sReflectionRender = false; bool LLPipeline::sDistortionRender = false; -bool LLPipeline::sImpostorRender = false; -bool LLPipeline::sImpostorRenderAlphaDepthPass = false; -bool LLPipeline::sUnderWaterRender = false; -bool LLPipeline::sTextureBindTest = false; -bool LLPipeline::sRenderFrameTest = false; -bool LLPipeline::sRenderAttachedLights = true; -bool LLPipeline::sRenderAttachedParticles = true; -bool LLPipeline::sRenderDeferred = false; +bool LLPipeline::sImpostorRender = false; +bool LLPipeline::sImpostorRenderAlphaDepthPass = false; +bool LLPipeline::sUnderWaterRender = false; +bool LLPipeline::sTextureBindTest = false; +bool LLPipeline::sRenderFrameTest = false; +bool LLPipeline::sRenderAttachedLights = true; +bool LLPipeline::sRenderAttachedParticles = true; +bool LLPipeline::sRenderDeferred = false; bool LLPipeline::sMemAllocationThrottled = false; -S32 LLPipeline::sVisibleLightCount = 0; -F32 LLPipeline::sMinRenderSize = 0.f; -bool LLPipeline::sRenderingHUDs; +S32 LLPipeline::sVisibleLightCount = 0; +F32 LLPipeline::sMinRenderSize = 0.f; +bool LLPipeline::sRenderingHUDs; F32 LLPipeline::sDistortionWaterClipPlaneMargin = 1.0001f; // EventHost API LLPipeline listener. @@ -361,246 +361,245 @@ void validate_framebuffer_object(); bool addDeferredAttachments(LLRenderTarget& target) { - return target.addColorAttachment(GL_SRGB8_ALPHA8) && //specular - target.addColorAttachment(GL_RGB10_A2); //normal+z + return target.addColorAttachment(GL_SRGB8_ALPHA8) && //specular + target.addColorAttachment(GL_RGB10_A2); //normal+z } LLPipeline::LLPipeline() : - mBackfaceCull(false), - mMatrixOpCount(0), - mTextureMatrixOps(0), - mNumVisibleNodes(0), - mNumVisibleFaces(0), - - mInitialized(false), - mVertexShadersEnabled(false), - mVertexShadersLoaded(0), - mTransformFeedbackPrimitives(0), - mRenderDebugFeatureMask(0), - mRenderDebugMask(0), - mOldRenderDebugMask(0), - mMeshDirtyQueryObject(0), - mGroupQ1Locked(false), - mGroupQ2Locked(false), - mResetVertexBuffers(false), - mLastRebuildPool(NULL), - mAlphaPool(NULL), - mSkyPool(NULL), - mTerrainPool(NULL), - mWaterPool(NULL), - mGroundPool(NULL), - mSimplePool(NULL), - mGrassPool(NULL), - mAlphaMaskPool(NULL), - mFullbrightAlphaMaskPool(NULL), - mFullbrightPool(NULL), - mInvisiblePool(NULL), - mGlowPool(NULL), - mBumpPool(NULL), - mMaterialsPool(NULL), - mWLSkyPool(NULL), - mLightMask(0), - mLightMovingMask(0), - mLightingDetail(0), - mScreenWidth(0), - mScreenHeight(0), - mNeedsShadowTargetClear(true) -{ - mNoiseMap = 0; - mTrueNoiseMap = 0; - mLightFunc = 0; + mBackfaceCull(false), + mMatrixOpCount(0), + mTextureMatrixOps(0), + mNumVisibleNodes(0), + mNumVisibleFaces(0), + + mInitialized(false), + mVertexShadersEnabled(false), + mVertexShadersLoaded(0), + mTransformFeedbackPrimitives(0), + mRenderDebugFeatureMask(0), + mRenderDebugMask(0), + mOldRenderDebugMask(0), + mMeshDirtyQueryObject(0), + mGroupQ1Locked(false), + mGroupQ2Locked(false), + mResetVertexBuffers(false), + mLastRebuildPool(NULL), + mAlphaPool(NULL), + mSkyPool(NULL), + mTerrainPool(NULL), + mWaterPool(NULL), + mGroundPool(NULL), + mSimplePool(NULL), + mGrassPool(NULL), + mAlphaMaskPool(NULL), + mFullbrightAlphaMaskPool(NULL), + mFullbrightPool(NULL), + mInvisiblePool(NULL), + mGlowPool(NULL), + mBumpPool(NULL), + mMaterialsPool(NULL), + mWLSkyPool(NULL), + mLightMask(0), + mLightMovingMask(0), + mLightingDetail(0), + mScreenWidth(0), + mScreenHeight(0) +{ + mNoiseMap = 0; + mTrueNoiseMap = 0; + mLightFunc = 0; } void LLPipeline::connectRefreshCachedSettingsSafe(const std::string name) { - LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl(name); - if ( cntrl_ptr.isNull() ) - { - LL_WARNS() << "Global setting name not found:" << name << LL_ENDL; - } - else - { - cntrl_ptr->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - } + LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl(name); + if ( cntrl_ptr.isNull() ) + { + LL_WARNS() << "Global setting name not found:" << name << LL_ENDL; + } + else + { + cntrl_ptr->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + } } void LLPipeline::init() { - refreshCachedSettings(); - - gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); - gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize"); - sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); - sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); - sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); - LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO"); - LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO"); - LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw"); - sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights"); - sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles"); - - mInitialized = true; - - stop_glerror(); - - //create render pass pools - getPool(LLDrawPool::POOL_ALPHA); - getPool(LLDrawPool::POOL_SIMPLE); - getPool(LLDrawPool::POOL_ALPHA_MASK); - getPool(LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK); - getPool(LLDrawPool::POOL_GRASS); - getPool(LLDrawPool::POOL_FULLBRIGHT); - getPool(LLDrawPool::POOL_INVISIBLE); - getPool(LLDrawPool::POOL_BUMP); - getPool(LLDrawPool::POOL_MATERIALS); - getPool(LLDrawPool::POOL_GLOW); - - resetFrameStats(); - - if (gSavedSettings.getBOOL("DisableAllRenderFeatures")) - { - clearAllRenderDebugFeatures(); - } - else - { - setAllRenderDebugFeatures(); // By default, all debugging features on - } - clearAllRenderDebugDisplays(); // All debug displays off + refreshCachedSettings(); + + gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); + gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize"); + sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); + sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); + sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); + LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO"); + LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO"); + LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw"); + sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights"); + sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles"); + + mInitialized = true; + + stop_glerror(); + + //create render pass pools + getPool(LLDrawPool::POOL_ALPHA); + getPool(LLDrawPool::POOL_SIMPLE); + getPool(LLDrawPool::POOL_ALPHA_MASK); + getPool(LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK); + getPool(LLDrawPool::POOL_GRASS); + getPool(LLDrawPool::POOL_FULLBRIGHT); + getPool(LLDrawPool::POOL_INVISIBLE); + getPool(LLDrawPool::POOL_BUMP); + getPool(LLDrawPool::POOL_MATERIALS); + getPool(LLDrawPool::POOL_GLOW); + + resetFrameStats(); + + if (gSavedSettings.getBOOL("DisableAllRenderFeatures")) + { + clearAllRenderDebugFeatures(); + } + else + { + setAllRenderDebugFeatures(); // By default, all debugging features on + } + clearAllRenderDebugDisplays(); // All debug displays off - if (gSavedSettings.getBOOL("DisableAllRenderTypes")) - { - clearAllRenderTypes(); - } - else - { - setAllRenderTypes(); // By default, all rendering types start enabled - // Don't turn on ground when this is set - // Mac Books with intel 950s need this - if(!gSavedSettings.getBOOL("RenderGround")) - { - toggleRenderType(RENDER_TYPE_GROUND); - } - } + if (gSavedSettings.getBOOL("DisableAllRenderTypes")) + { + clearAllRenderTypes(); + } + else + { + setAllRenderTypes(); // By default, all rendering types start enabled + // Don't turn on ground when this is set + // Mac Books with intel 950s need this + if(!gSavedSettings.getBOOL("RenderGround")) + { + toggleRenderType(RENDER_TYPE_GROUND); + } + } - // make sure RenderPerformanceTest persists (hackity hack hack) - // disables non-object rendering (UI, sky, water, etc) - if (gSavedSettings.getBOOL("RenderPerformanceTest")) - { - gSavedSettings.setBOOL("RenderPerformanceTest", FALSE); - gSavedSettings.setBOOL("RenderPerformanceTest", TRUE); - } + // make sure RenderPerformanceTest persists (hackity hack hack) + // disables non-object rendering (UI, sky, water, etc) + if (gSavedSettings.getBOOL("RenderPerformanceTest")) + { + gSavedSettings.setBOOL("RenderPerformanceTest", FALSE); + gSavedSettings.setBOOL("RenderPerformanceTest", TRUE); + } - mOldRenderDebugMask = mRenderDebugMask; + mOldRenderDebugMask = mRenderDebugMask; - mBackfaceCull = true; + mBackfaceCull = true; - stop_glerror(); - - // Enable features - - LLViewerShaderMgr::instance()->setShaders(); + stop_glerror(); + + // Enable features + + LLViewerShaderMgr::instance()->setShaders(); - stop_glerror(); + stop_glerror(); - for (U32 i = 0; i < 2; ++i) - { - mSpotLightFade[i] = 1.f; - } + for (U32 i = 0; i < 2; ++i) + { + mSpotLightFade[i] = 1.f; + } - if (mCubeVB.isNull()) - { - mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); - } + if (mCubeVB.isNull()) + { + mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); + } - mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0); - mDeferredVB->allocateBuffer(8, 0, true); - setLightingDetail(-1); - - // - // Update all settings to trigger a cached settings refresh - // - connectRefreshCachedSettingsSafe("RenderAutoMaskAlphaDeferred"); - connectRefreshCachedSettingsSafe("RenderAutoMaskAlphaNonDeferred"); - connectRefreshCachedSettingsSafe("RenderUseFarClip"); - connectRefreshCachedSettingsSafe("RenderAvatarMaxNonImpostors"); - connectRefreshCachedSettingsSafe("RenderDelayVBUpdate"); - connectRefreshCachedSettingsSafe("UseOcclusion"); - connectRefreshCachedSettingsSafe("VertexShaderEnable"); - connectRefreshCachedSettingsSafe("RenderAvatarVP"); - connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders"); - connectRefreshCachedSettingsSafe("RenderDeferred"); - connectRefreshCachedSettingsSafe("RenderDeferredSunWash"); - connectRefreshCachedSettingsSafe("RenderFSAASamples"); - connectRefreshCachedSettingsSafe("RenderResolutionDivisor"); - connectRefreshCachedSettingsSafe("RenderUIBuffer"); - connectRefreshCachedSettingsSafe("RenderShadowDetail"); - connectRefreshCachedSettingsSafe("RenderDeferredSSAO"); - connectRefreshCachedSettingsSafe("RenderShadowResolutionScale"); - connectRefreshCachedSettingsSafe("RenderLocalLights"); - connectRefreshCachedSettingsSafe("RenderDelayCreation"); - connectRefreshCachedSettingsSafe("RenderAnimateRes"); - connectRefreshCachedSettingsSafe("FreezeTime"); - connectRefreshCachedSettingsSafe("DebugBeaconLineWidth"); - connectRefreshCachedSettingsSafe("RenderHighlightBrightness"); - connectRefreshCachedSettingsSafe("RenderHighlightColor"); - connectRefreshCachedSettingsSafe("RenderHighlightThickness"); - connectRefreshCachedSettingsSafe("RenderSpotLightsInNondeferred"); - connectRefreshCachedSettingsSafe("PreviewAmbientColor"); - connectRefreshCachedSettingsSafe("PreviewDiffuse0"); - connectRefreshCachedSettingsSafe("PreviewSpecular0"); - connectRefreshCachedSettingsSafe("PreviewDiffuse1"); - connectRefreshCachedSettingsSafe("PreviewSpecular1"); - connectRefreshCachedSettingsSafe("PreviewDiffuse2"); - connectRefreshCachedSettingsSafe("PreviewSpecular2"); - connectRefreshCachedSettingsSafe("PreviewDirection0"); - connectRefreshCachedSettingsSafe("PreviewDirection1"); - connectRefreshCachedSettingsSafe("PreviewDirection2"); - connectRefreshCachedSettingsSafe("RenderGlowMinLuminance"); - connectRefreshCachedSettingsSafe("RenderGlowMaxExtractAlpha"); - connectRefreshCachedSettingsSafe("RenderGlowWarmthAmount"); - connectRefreshCachedSettingsSafe("RenderGlowLumWeights"); - connectRefreshCachedSettingsSafe("RenderGlowWarmthWeights"); - connectRefreshCachedSettingsSafe("RenderGlowResolutionPow"); - connectRefreshCachedSettingsSafe("RenderGlowIterations"); - connectRefreshCachedSettingsSafe("RenderGlowWidth"); - connectRefreshCachedSettingsSafe("RenderGlowStrength"); - connectRefreshCachedSettingsSafe("RenderDepthOfField"); - connectRefreshCachedSettingsSafe("RenderDepthOfFieldInEditMode"); - connectRefreshCachedSettingsSafe("CameraFocusTransitionTime"); - connectRefreshCachedSettingsSafe("CameraFNumber"); - connectRefreshCachedSettingsSafe("CameraFocalLength"); - connectRefreshCachedSettingsSafe("CameraFieldOfView"); - connectRefreshCachedSettingsSafe("RenderShadowNoise"); - connectRefreshCachedSettingsSafe("RenderShadowBlurSize"); - connectRefreshCachedSettingsSafe("RenderSSAOScale"); - connectRefreshCachedSettingsSafe("RenderSSAOMaxScale"); - connectRefreshCachedSettingsSafe("RenderSSAOFactor"); - connectRefreshCachedSettingsSafe("RenderSSAOEffect"); - connectRefreshCachedSettingsSafe("RenderShadowOffsetError"); - connectRefreshCachedSettingsSafe("RenderShadowBiasError"); - connectRefreshCachedSettingsSafe("RenderShadowOffset"); - connectRefreshCachedSettingsSafe("RenderShadowBias"); - connectRefreshCachedSettingsSafe("RenderSpotShadowOffset"); - connectRefreshCachedSettingsSafe("RenderSpotShadowBias"); - connectRefreshCachedSettingsSafe("RenderEdgeDepthCutoff"); - connectRefreshCachedSettingsSafe("RenderEdgeNormCutoff"); - connectRefreshCachedSettingsSafe("RenderShadowGaussian"); - connectRefreshCachedSettingsSafe("RenderShadowBlurDistFactor"); - connectRefreshCachedSettingsSafe("RenderDeferredAtmospheric"); - connectRefreshCachedSettingsSafe("RenderReflectionDetail"); - connectRefreshCachedSettingsSafe("RenderHighlightFadeTime"); - connectRefreshCachedSettingsSafe("RenderShadowClipPlanes"); - connectRefreshCachedSettingsSafe("RenderShadowOrthoClipPlanes"); - connectRefreshCachedSettingsSafe("RenderShadowNearDist"); - connectRefreshCachedSettingsSafe("RenderFarClip"); - connectRefreshCachedSettingsSafe("RenderShadowSplitExponent"); - connectRefreshCachedSettingsSafe("RenderShadowErrorCutoff"); - connectRefreshCachedSettingsSafe("RenderShadowFOVCutoff"); - connectRefreshCachedSettingsSafe("CameraOffset"); - connectRefreshCachedSettingsSafe("CameraMaxCoF"); - connectRefreshCachedSettingsSafe("CameraDoFResScale"); - connectRefreshCachedSettingsSafe("RenderAutoHideSurfaceAreaLimit"); - gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0); + mDeferredVB->allocateBuffer(8, 0, true); + setLightingDetail(-1); + + // + // Update all settings to trigger a cached settings refresh + // + connectRefreshCachedSettingsSafe("RenderAutoMaskAlphaDeferred"); + connectRefreshCachedSettingsSafe("RenderAutoMaskAlphaNonDeferred"); + connectRefreshCachedSettingsSafe("RenderUseFarClip"); + connectRefreshCachedSettingsSafe("RenderAvatarMaxNonImpostors"); + connectRefreshCachedSettingsSafe("RenderDelayVBUpdate"); + connectRefreshCachedSettingsSafe("UseOcclusion"); + connectRefreshCachedSettingsSafe("VertexShaderEnable"); + connectRefreshCachedSettingsSafe("RenderAvatarVP"); + connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders"); + connectRefreshCachedSettingsSafe("RenderDeferred"); + connectRefreshCachedSettingsSafe("RenderDeferredSunWash"); + connectRefreshCachedSettingsSafe("RenderFSAASamples"); + connectRefreshCachedSettingsSafe("RenderResolutionDivisor"); + connectRefreshCachedSettingsSafe("RenderUIBuffer"); + connectRefreshCachedSettingsSafe("RenderShadowDetail"); + connectRefreshCachedSettingsSafe("RenderDeferredSSAO"); + connectRefreshCachedSettingsSafe("RenderShadowResolutionScale"); + connectRefreshCachedSettingsSafe("RenderLocalLights"); + connectRefreshCachedSettingsSafe("RenderDelayCreation"); + connectRefreshCachedSettingsSafe("RenderAnimateRes"); + connectRefreshCachedSettingsSafe("FreezeTime"); + connectRefreshCachedSettingsSafe("DebugBeaconLineWidth"); + connectRefreshCachedSettingsSafe("RenderHighlightBrightness"); + connectRefreshCachedSettingsSafe("RenderHighlightColor"); + connectRefreshCachedSettingsSafe("RenderHighlightThickness"); + connectRefreshCachedSettingsSafe("RenderSpotLightsInNondeferred"); + connectRefreshCachedSettingsSafe("PreviewAmbientColor"); + connectRefreshCachedSettingsSafe("PreviewDiffuse0"); + connectRefreshCachedSettingsSafe("PreviewSpecular0"); + connectRefreshCachedSettingsSafe("PreviewDiffuse1"); + connectRefreshCachedSettingsSafe("PreviewSpecular1"); + connectRefreshCachedSettingsSafe("PreviewDiffuse2"); + connectRefreshCachedSettingsSafe("PreviewSpecular2"); + connectRefreshCachedSettingsSafe("PreviewDirection0"); + connectRefreshCachedSettingsSafe("PreviewDirection1"); + connectRefreshCachedSettingsSafe("PreviewDirection2"); + connectRefreshCachedSettingsSafe("RenderGlowMinLuminance"); + connectRefreshCachedSettingsSafe("RenderGlowMaxExtractAlpha"); + connectRefreshCachedSettingsSafe("RenderGlowWarmthAmount"); + connectRefreshCachedSettingsSafe("RenderGlowLumWeights"); + connectRefreshCachedSettingsSafe("RenderGlowWarmthWeights"); + connectRefreshCachedSettingsSafe("RenderGlowResolutionPow"); + connectRefreshCachedSettingsSafe("RenderGlowIterations"); + connectRefreshCachedSettingsSafe("RenderGlowWidth"); + connectRefreshCachedSettingsSafe("RenderGlowStrength"); + connectRefreshCachedSettingsSafe("RenderDepthOfField"); + connectRefreshCachedSettingsSafe("RenderDepthOfFieldInEditMode"); + connectRefreshCachedSettingsSafe("CameraFocusTransitionTime"); + connectRefreshCachedSettingsSafe("CameraFNumber"); + connectRefreshCachedSettingsSafe("CameraFocalLength"); + connectRefreshCachedSettingsSafe("CameraFieldOfView"); + connectRefreshCachedSettingsSafe("RenderShadowNoise"); + connectRefreshCachedSettingsSafe("RenderShadowBlurSize"); + connectRefreshCachedSettingsSafe("RenderSSAOScale"); + connectRefreshCachedSettingsSafe("RenderSSAOMaxScale"); + connectRefreshCachedSettingsSafe("RenderSSAOFactor"); + connectRefreshCachedSettingsSafe("RenderSSAOEffect"); + connectRefreshCachedSettingsSafe("RenderShadowOffsetError"); + connectRefreshCachedSettingsSafe("RenderShadowBiasError"); + connectRefreshCachedSettingsSafe("RenderShadowOffset"); + connectRefreshCachedSettingsSafe("RenderShadowBias"); + connectRefreshCachedSettingsSafe("RenderSpotShadowOffset"); + connectRefreshCachedSettingsSafe("RenderSpotShadowBias"); + connectRefreshCachedSettingsSafe("RenderEdgeDepthCutoff"); + connectRefreshCachedSettingsSafe("RenderEdgeNormCutoff"); + connectRefreshCachedSettingsSafe("RenderShadowGaussian"); + connectRefreshCachedSettingsSafe("RenderShadowBlurDistFactor"); + connectRefreshCachedSettingsSafe("RenderDeferredAtmospheric"); + connectRefreshCachedSettingsSafe("RenderReflectionDetail"); + connectRefreshCachedSettingsSafe("RenderHighlightFadeTime"); + connectRefreshCachedSettingsSafe("RenderShadowClipPlanes"); + connectRefreshCachedSettingsSafe("RenderShadowOrthoClipPlanes"); + connectRefreshCachedSettingsSafe("RenderShadowNearDist"); + connectRefreshCachedSettingsSafe("RenderFarClip"); + connectRefreshCachedSettingsSafe("RenderShadowSplitExponent"); + connectRefreshCachedSettingsSafe("RenderShadowErrorCutoff"); + connectRefreshCachedSettingsSafe("RenderShadowFOVCutoff"); + connectRefreshCachedSettingsSafe("CameraOffset"); + connectRefreshCachedSettingsSafe("CameraMaxCoF"); + connectRefreshCachedSettingsSafe("CameraDoFResScale"); + connectRefreshCachedSettingsSafe("RenderAutoHideSurfaceAreaLimit"); + gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); } LLPipeline::~LLPipeline() @@ -610,104 +609,104 @@ LLPipeline::~LLPipeline() void LLPipeline::cleanup() { - assertInitialized(); + assertInitialized(); - mGroupQ1.clear() ; - mGroupQ2.clear() ; + mGroupQ1.clear() ; + mGroupQ2.clear() ; - for(pool_set_t::iterator iter = mPools.begin(); - iter != mPools.end(); ) - { - pool_set_t::iterator curiter = iter++; - LLDrawPool* poolp = *curiter; - if (poolp->isFacePool()) - { - LLFacePool* face_pool = (LLFacePool*) poolp; - if (face_pool->mReferences.empty()) - { - mPools.erase(curiter); - removeFromQuickLookup( poolp ); - delete poolp; - } - } - else - { - mPools.erase(curiter); - removeFromQuickLookup( poolp ); - delete poolp; - } - } - - if (!mTerrainPools.empty()) - { - LL_WARNS() << "Terrain Pools not cleaned up" << LL_ENDL; - } - if (!mTreePools.empty()) - { - LL_WARNS() << "Tree Pools not cleaned up" << LL_ENDL; - } - - delete mAlphaPool; - mAlphaPool = NULL; - delete mSkyPool; - mSkyPool = NULL; - delete mTerrainPool; - mTerrainPool = NULL; - delete mWaterPool; - mWaterPool = NULL; - delete mGroundPool; - mGroundPool = NULL; - delete mSimplePool; - mSimplePool = NULL; - delete mFullbrightPool; - mFullbrightPool = NULL; - delete mInvisiblePool; - mInvisiblePool = NULL; - delete mGlowPool; - mGlowPool = NULL; - delete mBumpPool; - mBumpPool = NULL; - // don't delete wl sky pool it was handled above in the for loop - //delete mWLSkyPool; - mWLSkyPool = NULL; - - releaseGLBuffers(); - - mFaceSelectImagep = NULL; - - mMovedBridge.clear(); - - mInitialized = false; - - mDeferredVB = NULL; - - mCubeVB = NULL; + for(pool_set_t::iterator iter = mPools.begin(); + iter != mPools.end(); ) + { + pool_set_t::iterator curiter = iter++; + LLDrawPool* poolp = *curiter; + if (poolp->isFacePool()) + { + LLFacePool* face_pool = (LLFacePool*) poolp; + if (face_pool->mReferences.empty()) + { + mPools.erase(curiter); + removeFromQuickLookup( poolp ); + delete poolp; + } + } + else + { + mPools.erase(curiter); + removeFromQuickLookup( poolp ); + delete poolp; + } + } + + if (!mTerrainPools.empty()) + { + LL_WARNS() << "Terrain Pools not cleaned up" << LL_ENDL; + } + if (!mTreePools.empty()) + { + LL_WARNS() << "Tree Pools not cleaned up" << LL_ENDL; + } + + delete mAlphaPool; + mAlphaPool = NULL; + delete mSkyPool; + mSkyPool = NULL; + delete mTerrainPool; + mTerrainPool = NULL; + delete mWaterPool; + mWaterPool = NULL; + delete mGroundPool; + mGroundPool = NULL; + delete mSimplePool; + mSimplePool = NULL; + delete mFullbrightPool; + mFullbrightPool = NULL; + delete mInvisiblePool; + mInvisiblePool = NULL; + delete mGlowPool; + mGlowPool = NULL; + delete mBumpPool; + mBumpPool = NULL; + // don't delete wl sky pool it was handled above in the for loop + //delete mWLSkyPool; + mWLSkyPool = NULL; + + releaseGLBuffers(); + + mFaceSelectImagep = NULL; + + mMovedBridge.clear(); + + mInitialized = false; + + mDeferredVB = NULL; + + mCubeVB = NULL; } //============================================================================ void LLPipeline::destroyGL() { - stop_glerror(); - unloadShaders(); - mHighlightFaces.clear(); - - resetDrawOrders(); + stop_glerror(); + unloadShaders(); + mHighlightFaces.clear(); + + resetDrawOrders(); - resetVertexBuffers(); + resetVertexBuffers(); - releaseGLBuffers(); + releaseGLBuffers(); - if (LLVertexBuffer::sEnableVBOs) - { - LLVertexBuffer::sEnableVBOs = FALSE; - } + if (LLVertexBuffer::sEnableVBOs) + { + LLVertexBuffer::sEnableVBOs = FALSE; + } - if (mMeshDirtyQueryObject) - { - glDeleteQueriesARB(1, &mMeshDirtyQueryObject); - mMeshDirtyQueryObject = 0; - } + if (mMeshDirtyQueryObject) + { + glDeleteQueriesARB(1, &mMeshDirtyQueryObject); + mMeshDirtyQueryObject = 0; + } } static LLTrace::BlockTimerStatHandle FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture"); @@ -715,148 +714,148 @@ static LLTrace::BlockTimerStatHandle FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Te //static void LLPipeline::throttleNewMemoryAllocation(bool disable) { - if(sMemAllocationThrottled != disable) - { - sMemAllocationThrottled = disable ; + if(sMemAllocationThrottled != disable) + { + sMemAllocationThrottled = disable ; - if(sMemAllocationThrottled) - { - //send out notification - LLNotification::Params params("LowMemory"); - LLNotifications::instance().add(params); + if(sMemAllocationThrottled) + { + //send out notification + LLNotification::Params params("LowMemory"); + LLNotifications::instance().add(params); - //release some memory. - } - } + //release some memory. + } + } } void LLPipeline::resizeScreenTexture() { - LL_RECORD_BLOCK_TIME(FTM_RESIZE_SCREEN_TEXTURE); - if (gPipeline.canUseVertexShaders() && assertInitialized()) - { - GLuint resX = gViewerWindow->getWorldViewWidthRaw(); - GLuint resY = gViewerWindow->getWorldViewHeightRaw(); - - if ((resX != mScreen.getWidth()) || (resY != mScreen.getHeight())) - { - releaseScreenBuffers(); - if (!allocateScreenBuffer(resX,resY)) - { + LL_RECORD_BLOCK_TIME(FTM_RESIZE_SCREEN_TEXTURE); + if (gPipeline.canUseVertexShaders() && assertInitialized()) + { + GLuint resX = gViewerWindow->getWorldViewWidthRaw(); + GLuint resY = gViewerWindow->getWorldViewHeightRaw(); + + if ((resX != mScreen.getWidth()) || (resY != mScreen.getHeight())) + { + releaseScreenBuffers(); + if (!allocateScreenBuffer(resX,resY)) + { #if PROBABLE_FALSE_DISABLES_OF_ALM_HERE - //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled - //NOTE: if the session closes successfully after this call, deferred rendering will be - // disabled on future sessions - if (LLPipeline::sRenderDeferred) - { - gSavedSettings.setBOOL("RenderDeferred", FALSE); - LLPipeline::refreshCachedSettings(); - - } + //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled + //NOTE: if the session closes successfully after this call, deferred rendering will be + // disabled on future sessions + if (LLPipeline::sRenderDeferred) + { + gSavedSettings.setBOOL("RenderDeferred", FALSE); + LLPipeline::refreshCachedSettings(); + + } #endif - } - } - } + } + } + } } void LLPipeline::allocatePhysicsBuffer() { - GLuint resX = gViewerWindow->getWorldViewWidthRaw(); - GLuint resY = gViewerWindow->getWorldViewHeightRaw(); + GLuint resX = gViewerWindow->getWorldViewWidthRaw(); + GLuint resY = gViewerWindow->getWorldViewHeightRaw(); - if (mPhysicsDisplay.getWidth() != resX || mPhysicsDisplay.getHeight() != resY) - { - mPhysicsDisplay.allocate(resX, resY, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); - } + if (mPhysicsDisplay.getWidth() != resX || mPhysicsDisplay.getHeight() != resY) + { + mPhysicsDisplay.allocate(resX, resY, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + } } bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) { - refreshCachedSettings(); - - bool save_settings = sRenderDeferred; - if (save_settings) - { - // Set this flag in case we crash while resizing window or allocating space for deferred rendering targets - gSavedSettings.setBOOL("RenderInitError", TRUE); - gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); - } + refreshCachedSettings(); + + bool save_settings = sRenderDeferred; + if (save_settings) + { + // Set this flag in case we crash while resizing window or allocating space for deferred rendering targets + gSavedSettings.setBOOL("RenderInitError", TRUE); + gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); + } - eFBOStatus ret = doAllocateScreenBuffer(resX, resY); + eFBOStatus ret = doAllocateScreenBuffer(resX, resY); - if (save_settings) - { - // don't disable shaders on next session - gSavedSettings.setBOOL("RenderInitError", FALSE); - gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); - } - - if (ret == FBO_FAILURE) - { //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled - //NOTE: if the session closes successfully after this call, deferred rendering will be - // disabled on future sessions - if (LLPipeline::sRenderDeferred) - { - gSavedSettings.setBOOL("RenderDeferred", FALSE); - LLPipeline::refreshCachedSettings(); - } - } + if (save_settings) + { + // don't disable shaders on next session + gSavedSettings.setBOOL("RenderInitError", FALSE); + gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); + } + + if (ret == FBO_FAILURE) + { //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled + //NOTE: if the session closes successfully after this call, deferred rendering will be + // disabled on future sessions + if (LLPipeline::sRenderDeferred) + { + gSavedSettings.setBOOL("RenderDeferred", FALSE); + LLPipeline::refreshCachedSettings(); + } + } - return ret == FBO_SUCCESS_FULLRES; + return ret == FBO_SUCCESS_FULLRES; } LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY) { - // try to allocate screen buffers at requested resolution and samples - // - on failure, shrink number of samples and try again - // - if not multisampled, shrink resolution and try again (favor X resolution over Y) - // Make sure to call "releaseScreenBuffers" after each failure to cleanup the partially loaded state - - U32 samples = RenderFSAASamples; - - eFBOStatus ret = FBO_SUCCESS_FULLRES; - if (!allocateScreenBuffer(resX, resY, samples)) - { - //failed to allocate at requested specification, return false - ret = FBO_FAILURE; - - releaseScreenBuffers(); - //reduce number of samples - while (samples > 0) - { - samples /= 2; - if (allocateScreenBuffer(resX, resY, samples)) - { //success - return FBO_SUCCESS_LOWRES; - } - releaseScreenBuffers(); - } - - samples = 0; - - //reduce resolution - while (resY > 0 && resX > 0) - { - resY /= 2; - if (allocateScreenBuffer(resX, resY, samples)) - { - return FBO_SUCCESS_LOWRES; - } - releaseScreenBuffers(); + // try to allocate screen buffers at requested resolution and samples + // - on failure, shrink number of samples and try again + // - if not multisampled, shrink resolution and try again (favor X resolution over Y) + // Make sure to call "releaseScreenBuffers" after each failure to cleanup the partially loaded state - resX /= 2; - if (allocateScreenBuffer(resX, resY, samples)) - { - return FBO_SUCCESS_LOWRES; - } - releaseScreenBuffers(); - } + U32 samples = RenderFSAASamples; - LL_WARNS() << "Unable to allocate screen buffer at any resolution!" << LL_ENDL; - } + eFBOStatus ret = FBO_SUCCESS_FULLRES; + if (!allocateScreenBuffer(resX, resY, samples)) + { + //failed to allocate at requested specification, return false + ret = FBO_FAILURE; + + releaseScreenBuffers(); + //reduce number of samples + while (samples > 0) + { + samples /= 2; + if (allocateScreenBuffer(resX, resY, samples)) + { //success + return FBO_SUCCESS_LOWRES; + } + releaseScreenBuffers(); + } + + samples = 0; + + //reduce resolution + while (resY > 0 && resX > 0) + { + resY /= 2; + if (allocateScreenBuffer(resX, resY, samples)) + { + return FBO_SUCCESS_LOWRES; + } + releaseScreenBuffers(); + + resX /= 2; + if (allocateScreenBuffer(resX, resY, samples)) + { + return FBO_SUCCESS_LOWRES; + } + releaseScreenBuffers(); + } + + LL_WARNS() << "Unable to allocate screen buffer at any resolution!" << LL_ENDL; + } - return ret; + return ret; } // must be even to avoid a stripe in the horizontal shadow blur @@ -864,88 +863,80 @@ inline U32 BlurHappySize(U32 x, U32 scale) { return (((x*scale)+1)&~1); } bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) { - refreshCachedSettings(); + refreshCachedSettings(); - // remember these dimensions - mScreenWidth = resX; - mScreenHeight = resY; - - U32 res_mod = RenderResolutionDivisor; + // remember these dimensions + mScreenWidth = resX; + mScreenHeight = resY; + + U32 res_mod = RenderResolutionDivisor; - if (res_mod > 1 && res_mod < resX && res_mod < resY) - { - resX /= res_mod; - resY /= res_mod; - } + if (res_mod > 1 && res_mod < resX && res_mod < resY) + { + resX /= res_mod; + resY /= res_mod; + } - if (RenderUIBuffer) - { - if (!mUIScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) - { - return false; - } - } + if (RenderUIBuffer) + { + if (!mUIScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) + { + return false; + } + } - if (LLPipeline::sRenderDeferred) - { - S32 shadow_detail = RenderShadowDetail; - bool ssao = RenderDeferredSSAO; + if (LLPipeline::sRenderDeferred) + { + S32 shadow_detail = RenderShadowDetail; + bool ssao = RenderDeferredSSAO; + + const U32 occlusion_divisor = 3; + + //allocate deferred rendering color buffers + if (!mDeferredScreen.allocate(resX, resY, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; + if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; + if (!mOcclusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; + if (!addDeferredAttachments(mDeferredScreen)) return false; + + GLuint screenFormat = GL_RGBA16; + if (gGLManager.mIsATI) + { + screenFormat = GL_RGBA12; + } + + if (gGLManager.mGLVersion < 4.f && gGLManager.mIsNVIDIA) + { + screenFormat = GL_RGBA16F_ARB; + } - const U32 occlusion_divisor = 4; - - //allocate deferred rendering color buffers - if (!mDeferredScreen.allocate(resX, resY, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; - if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; - if (!mOcclusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; - if (!addDeferredAttachments(mDeferredScreen)) return false; - - GLuint screenFormat = GL_RGBA16; - if (gGLManager.mIsATI) - { - screenFormat = GL_RGBA12; - } - - if (gGLManager.mGLVersion < 4.f && gGLManager.mIsNVIDIA) - { - screenFormat = GL_RGBA16F_ARB; - } - - if (!mScreen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; - if (samples > 0) - { - if (!mFXAABuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; - } - else - { - mFXAABuffer.release(); - } - - if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0) - { //only need mDeferredLight for shadows OR ssao OR dof OR fxaa - if (!mDeferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false; - } - else - { - mDeferredLight.release(); - } + if (!mScreen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; + if (samples > 0) + { + if (!mFXAABuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; + } + else + { + mFXAABuffer.release(); + } + + if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0) + { //only need mDeferredLight for shadows OR ssao OR dof OR fxaa + if (!mDeferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false; + } + else + { + mDeferredLight.release(); + } F32 scale = RenderShadowResolutionScale; - U32 sun_shadow_map_width = BlurHappySize(resX, scale); - U32 sun_shadow_map_height = BlurHappySize(resY, scale); + U32 sun_shadow_map_width = BlurHappySize(resX, scale); + U32 sun_shadow_map_height = BlurHappySize(resY, scale); - if (shadow_detail > 0) + if (shadow_detail > 0) { //allocate 4 sun shadow maps - for (U32 i = 0; i < 4; i++) - { - if (shadow_detail > 3) - { - //allocate VSM sun shadow map(s) - if (!mShadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, GL_RGBA16F_ARB, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) - { - return false; - } - } - else if (!mShadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) + for (U32 i = 0; i < 4; i++) + { + if (!mShadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) { return false; } @@ -973,11 +964,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) U32 spot_shadow_map_height = height; for (U32 i = 4; i < 6; i++) { - if ((shadow_detail > 3) && !mShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, GL_RGBA16F_ARB, FALSE, FALSE)) - { - return false; - } - else if (!mShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, TRUE, FALSE)) + if (!mShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, TRUE, FALSE)) { return false; } @@ -1007,201 +994,201 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) releaseShadowTargets(); - mFXAABuffer.release(); - mScreen.release(); - mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first - mDeferredDepth.release(); - mOcclusionDepth.release(); - - if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false; - } - - if (LLPipeline::sRenderDeferred) - { //share depth buffer between deferred targets - mDeferredScreen.shareDepthBuffer(mScreen); - } + mFXAABuffer.release(); + mScreen.release(); + mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first + mDeferredDepth.release(); + mOcclusionDepth.release(); + + if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false; + } + + if (LLPipeline::sRenderDeferred) + { //share depth buffer between deferred targets + mDeferredScreen.shareDepthBuffer(mScreen); + } - gGL.getTexUnit(0)->disable(); + gGL.getTexUnit(0)->disable(); - stop_glerror(); + stop_glerror(); - return true; + return true; } //static void LLPipeline::updateRenderBump() { - sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); + sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); } //static void LLPipeline::updateRenderDeferred() { - bool deferred = (bool(RenderDeferred && - LLRenderTarget::sUseFBO && - LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && - LLPipeline::sRenderBump && - VertexShaderEnable && - RenderAvatarVP && - WindLightUseAtmosShaders)) && - !gUseWireframe; - - sRenderDeferred = deferred; - if (deferred) - { //must render glow when rendering deferred since post effect pass is needed to present any lighting at all - sRenderGlow = true; - } + bool deferred = (bool(RenderDeferred && + LLRenderTarget::sUseFBO && + LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && + LLPipeline::sRenderBump && + VertexShaderEnable && + RenderAvatarVP && + WindLightUseAtmosShaders)) && + !gUseWireframe; + + sRenderDeferred = deferred; + if (deferred) + { //must render glow when rendering deferred since post effect pass is needed to present any lighting at all + sRenderGlow = true; + } } //static void LLPipeline::refreshCachedSettings() { - LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred"); - LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred"); - LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip"); - LLVOAvatar::sMaxNonImpostors = gSavedSettings.getU32("RenderAvatarMaxNonImpostors"); - LLVOAvatar::updateImpostorRendering(LLVOAvatar::sMaxNonImpostors); - LLPipeline::sDelayVBUpdate = gSavedSettings.getBOOL("RenderDelayVBUpdate"); - - LLPipeline::sUseOcclusion = - (!gUseWireframe - && LLGLSLShader::sNoFixedFunction - && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") - && gSavedSettings.getBOOL("UseOcclusion") - && gGLManager.mHasOcclusionQuery) ? 2 : 0; - - VertexShaderEnable = gSavedSettings.getBOOL("VertexShaderEnable"); - RenderAvatarVP = gSavedSettings.getBOOL("RenderAvatarVP"); - WindLightUseAtmosShaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders"); - RenderDeferred = gSavedSettings.getBOOL("RenderDeferred"); - RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash"); - RenderFSAASamples = gSavedSettings.getU32("RenderFSAASamples"); - RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor"); - RenderUIBuffer = gSavedSettings.getBOOL("RenderUIBuffer"); - RenderShadowDetail = gSavedSettings.getS32("RenderShadowDetail"); - RenderDeferredSSAO = gSavedSettings.getBOOL("RenderDeferredSSAO"); - RenderShadowResolutionScale = gSavedSettings.getF32("RenderShadowResolutionScale"); - RenderLocalLights = gSavedSettings.getBOOL("RenderLocalLights"); - RenderDelayCreation = gSavedSettings.getBOOL("RenderDelayCreation"); - RenderAnimateRes = gSavedSettings.getBOOL("RenderAnimateRes"); - FreezeTime = gSavedSettings.getBOOL("FreezeTime"); - DebugBeaconLineWidth = gSavedSettings.getS32("DebugBeaconLineWidth"); - RenderHighlightBrightness = gSavedSettings.getF32("RenderHighlightBrightness"); - RenderHighlightColor = gSavedSettings.getColor4("RenderHighlightColor"); - RenderHighlightThickness = gSavedSettings.getF32("RenderHighlightThickness"); - RenderSpotLightsInNondeferred = gSavedSettings.getBOOL("RenderSpotLightsInNondeferred"); - PreviewAmbientColor = gSavedSettings.getColor4("PreviewAmbientColor"); - PreviewDiffuse0 = gSavedSettings.getColor4("PreviewDiffuse0"); - PreviewSpecular0 = gSavedSettings.getColor4("PreviewSpecular0"); - PreviewDiffuse1 = gSavedSettings.getColor4("PreviewDiffuse1"); - PreviewSpecular1 = gSavedSettings.getColor4("PreviewSpecular1"); - PreviewDiffuse2 = gSavedSettings.getColor4("PreviewDiffuse2"); - PreviewSpecular2 = gSavedSettings.getColor4("PreviewSpecular2"); - PreviewDirection0 = gSavedSettings.getVector3("PreviewDirection0"); - PreviewDirection1 = gSavedSettings.getVector3("PreviewDirection1"); - PreviewDirection2 = gSavedSettings.getVector3("PreviewDirection2"); - RenderGlowMinLuminance = gSavedSettings.getF32("RenderGlowMinLuminance"); - RenderGlowMaxExtractAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha"); - RenderGlowWarmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount"); - RenderGlowLumWeights = gSavedSettings.getVector3("RenderGlowLumWeights"); - RenderGlowWarmthWeights = gSavedSettings.getVector3("RenderGlowWarmthWeights"); - RenderGlowResolutionPow = gSavedSettings.getS32("RenderGlowResolutionPow"); - RenderGlowIterations = gSavedSettings.getS32("RenderGlowIterations"); - RenderGlowWidth = gSavedSettings.getF32("RenderGlowWidth"); - RenderGlowStrength = gSavedSettings.getF32("RenderGlowStrength"); - RenderDepthOfField = gSavedSettings.getBOOL("RenderDepthOfField"); - RenderDepthOfFieldInEditMode = gSavedSettings.getBOOL("RenderDepthOfFieldInEditMode"); - CameraFocusTransitionTime = gSavedSettings.getF32("CameraFocusTransitionTime"); - CameraFNumber = gSavedSettings.getF32("CameraFNumber"); - CameraFocalLength = gSavedSettings.getF32("CameraFocalLength"); - CameraFieldOfView = gSavedSettings.getF32("CameraFieldOfView"); - RenderShadowNoise = gSavedSettings.getF32("RenderShadowNoise"); - RenderShadowBlurSize = gSavedSettings.getF32("RenderShadowBlurSize"); - RenderSSAOScale = gSavedSettings.getF32("RenderSSAOScale"); - RenderSSAOMaxScale = gSavedSettings.getU32("RenderSSAOMaxScale"); - RenderSSAOFactor = gSavedSettings.getF32("RenderSSAOFactor"); - RenderSSAOEffect = gSavedSettings.getVector3("RenderSSAOEffect"); - RenderShadowOffsetError = gSavedSettings.getF32("RenderShadowOffsetError"); - RenderShadowBiasError = gSavedSettings.getF32("RenderShadowBiasError"); - RenderShadowOffset = gSavedSettings.getF32("RenderShadowOffset"); - RenderShadowBias = gSavedSettings.getF32("RenderShadowBias"); - RenderSpotShadowOffset = gSavedSettings.getF32("RenderSpotShadowOffset"); - RenderSpotShadowBias = gSavedSettings.getF32("RenderSpotShadowBias"); - RenderEdgeDepthCutoff = gSavedSettings.getF32("RenderEdgeDepthCutoff"); - RenderEdgeNormCutoff = gSavedSettings.getF32("RenderEdgeNormCutoff"); - RenderShadowGaussian = gSavedSettings.getVector3("RenderShadowGaussian"); - RenderShadowBlurDistFactor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); - RenderDeferredAtmospheric = gSavedSettings.getBOOL("RenderDeferredAtmospheric"); - RenderReflectionDetail = gSavedSettings.getS32("RenderReflectionDetail"); - RenderHighlightFadeTime = gSavedSettings.getF32("RenderHighlightFadeTime"); - RenderShadowClipPlanes = gSavedSettings.getVector3("RenderShadowClipPlanes"); - RenderShadowOrthoClipPlanes = gSavedSettings.getVector3("RenderShadowOrthoClipPlanes"); - RenderShadowNearDist = gSavedSettings.getVector3("RenderShadowNearDist"); - RenderFarClip = gSavedSettings.getF32("RenderFarClip"); - RenderShadowSplitExponent = gSavedSettings.getVector3("RenderShadowSplitExponent"); - RenderShadowErrorCutoff = gSavedSettings.getF32("RenderShadowErrorCutoff"); - RenderShadowFOVCutoff = gSavedSettings.getF32("RenderShadowFOVCutoff"); - CameraOffset = gSavedSettings.getBOOL("CameraOffset"); - CameraMaxCoF = gSavedSettings.getF32("CameraMaxCoF"); - CameraDoFResScale = gSavedSettings.getF32("CameraDoFResScale"); - RenderAutoHideSurfaceAreaLimit = gSavedSettings.getF32("RenderAutoHideSurfaceAreaLimit"); - - updateRenderDeferred(); + LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred"); + LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred"); + LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip"); + LLVOAvatar::sMaxNonImpostors = gSavedSettings.getU32("RenderAvatarMaxNonImpostors"); + LLVOAvatar::updateImpostorRendering(LLVOAvatar::sMaxNonImpostors); + LLPipeline::sDelayVBUpdate = gSavedSettings.getBOOL("RenderDelayVBUpdate"); + + LLPipeline::sUseOcclusion = + (!gUseWireframe + && LLGLSLShader::sNoFixedFunction + && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") + && gSavedSettings.getBOOL("UseOcclusion") + && gGLManager.mHasOcclusionQuery) ? 2 : 0; + + VertexShaderEnable = gSavedSettings.getBOOL("VertexShaderEnable"); + RenderAvatarVP = gSavedSettings.getBOOL("RenderAvatarVP"); + WindLightUseAtmosShaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders"); + RenderDeferred = gSavedSettings.getBOOL("RenderDeferred"); + RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash"); + RenderFSAASamples = gSavedSettings.getU32("RenderFSAASamples"); + RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor"); + RenderUIBuffer = gSavedSettings.getBOOL("RenderUIBuffer"); + RenderShadowDetail = gSavedSettings.getS32("RenderShadowDetail"); + RenderDeferredSSAO = gSavedSettings.getBOOL("RenderDeferredSSAO"); + RenderShadowResolutionScale = gSavedSettings.getF32("RenderShadowResolutionScale"); + RenderLocalLights = gSavedSettings.getBOOL("RenderLocalLights"); + RenderDelayCreation = gSavedSettings.getBOOL("RenderDelayCreation"); + RenderAnimateRes = gSavedSettings.getBOOL("RenderAnimateRes"); + FreezeTime = gSavedSettings.getBOOL("FreezeTime"); + DebugBeaconLineWidth = gSavedSettings.getS32("DebugBeaconLineWidth"); + RenderHighlightBrightness = gSavedSettings.getF32("RenderHighlightBrightness"); + RenderHighlightColor = gSavedSettings.getColor4("RenderHighlightColor"); + RenderHighlightThickness = gSavedSettings.getF32("RenderHighlightThickness"); + RenderSpotLightsInNondeferred = gSavedSettings.getBOOL("RenderSpotLightsInNondeferred"); + PreviewAmbientColor = gSavedSettings.getColor4("PreviewAmbientColor"); + PreviewDiffuse0 = gSavedSettings.getColor4("PreviewDiffuse0"); + PreviewSpecular0 = gSavedSettings.getColor4("PreviewSpecular0"); + PreviewDiffuse1 = gSavedSettings.getColor4("PreviewDiffuse1"); + PreviewSpecular1 = gSavedSettings.getColor4("PreviewSpecular1"); + PreviewDiffuse2 = gSavedSettings.getColor4("PreviewDiffuse2"); + PreviewSpecular2 = gSavedSettings.getColor4("PreviewSpecular2"); + PreviewDirection0 = gSavedSettings.getVector3("PreviewDirection0"); + PreviewDirection1 = gSavedSettings.getVector3("PreviewDirection1"); + PreviewDirection2 = gSavedSettings.getVector3("PreviewDirection2"); + RenderGlowMinLuminance = gSavedSettings.getF32("RenderGlowMinLuminance"); + RenderGlowMaxExtractAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha"); + RenderGlowWarmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount"); + RenderGlowLumWeights = gSavedSettings.getVector3("RenderGlowLumWeights"); + RenderGlowWarmthWeights = gSavedSettings.getVector3("RenderGlowWarmthWeights"); + RenderGlowResolutionPow = gSavedSettings.getS32("RenderGlowResolutionPow"); + RenderGlowIterations = gSavedSettings.getS32("RenderGlowIterations"); + RenderGlowWidth = gSavedSettings.getF32("RenderGlowWidth"); + RenderGlowStrength = gSavedSettings.getF32("RenderGlowStrength"); + RenderDepthOfField = gSavedSettings.getBOOL("RenderDepthOfField"); + RenderDepthOfFieldInEditMode = gSavedSettings.getBOOL("RenderDepthOfFieldInEditMode"); + CameraFocusTransitionTime = gSavedSettings.getF32("CameraFocusTransitionTime"); + CameraFNumber = gSavedSettings.getF32("CameraFNumber"); + CameraFocalLength = gSavedSettings.getF32("CameraFocalLength"); + CameraFieldOfView = gSavedSettings.getF32("CameraFieldOfView"); + RenderShadowNoise = gSavedSettings.getF32("RenderShadowNoise"); + RenderShadowBlurSize = gSavedSettings.getF32("RenderShadowBlurSize"); + RenderSSAOScale = gSavedSettings.getF32("RenderSSAOScale"); + RenderSSAOMaxScale = gSavedSettings.getU32("RenderSSAOMaxScale"); + RenderSSAOFactor = gSavedSettings.getF32("RenderSSAOFactor"); + RenderSSAOEffect = gSavedSettings.getVector3("RenderSSAOEffect"); + RenderShadowOffsetError = gSavedSettings.getF32("RenderShadowOffsetError"); + RenderShadowBiasError = gSavedSettings.getF32("RenderShadowBiasError"); + RenderShadowOffset = gSavedSettings.getF32("RenderShadowOffset"); + RenderShadowBias = gSavedSettings.getF32("RenderShadowBias"); + RenderSpotShadowOffset = gSavedSettings.getF32("RenderSpotShadowOffset"); + RenderSpotShadowBias = gSavedSettings.getF32("RenderSpotShadowBias"); + RenderEdgeDepthCutoff = gSavedSettings.getF32("RenderEdgeDepthCutoff"); + RenderEdgeNormCutoff = gSavedSettings.getF32("RenderEdgeNormCutoff"); + RenderShadowGaussian = gSavedSettings.getVector3("RenderShadowGaussian"); + RenderShadowBlurDistFactor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); + RenderDeferredAtmospheric = gSavedSettings.getBOOL("RenderDeferredAtmospheric"); + RenderReflectionDetail = gSavedSettings.getS32("RenderReflectionDetail"); + RenderHighlightFadeTime = gSavedSettings.getF32("RenderHighlightFadeTime"); + RenderShadowClipPlanes = gSavedSettings.getVector3("RenderShadowClipPlanes"); + RenderShadowOrthoClipPlanes = gSavedSettings.getVector3("RenderShadowOrthoClipPlanes"); + RenderShadowNearDist = gSavedSettings.getVector3("RenderShadowNearDist"); + RenderFarClip = gSavedSettings.getF32("RenderFarClip"); + RenderShadowSplitExponent = gSavedSettings.getVector3("RenderShadowSplitExponent"); + RenderShadowErrorCutoff = gSavedSettings.getF32("RenderShadowErrorCutoff"); + RenderShadowFOVCutoff = gSavedSettings.getF32("RenderShadowFOVCutoff"); + CameraOffset = gSavedSettings.getBOOL("CameraOffset"); + CameraMaxCoF = gSavedSettings.getF32("CameraMaxCoF"); + CameraDoFResScale = gSavedSettings.getF32("CameraDoFResScale"); + RenderAutoHideSurfaceAreaLimit = gSavedSettings.getF32("RenderAutoHideSurfaceAreaLimit"); + + updateRenderDeferred(); } void LLPipeline::releaseGLBuffers() { - assertInitialized(); - - if (mNoiseMap) - { - LLImageGL::deleteTextures(1, &mNoiseMap); - mNoiseMap = 0; - } + assertInitialized(); + + if (mNoiseMap) + { + LLImageGL::deleteTextures(1, &mNoiseMap); + mNoiseMap = 0; + } - if (mTrueNoiseMap) - { - LLImageGL::deleteTextures(1, &mTrueNoiseMap); - mTrueNoiseMap = 0; - } + if (mTrueNoiseMap) + { + LLImageGL::deleteTextures(1, &mTrueNoiseMap); + mTrueNoiseMap = 0; + } - releaseLUTBuffers(); + releaseLUTBuffers(); - mWaterRef.release(); - mWaterDis.release(); - mHighlight.release(); - - for (U32 i = 0; i < 3; i++) - { - mGlow[i].release(); - } + mWaterRef.release(); + mWaterDis.release(); + mHighlight.release(); + + for (U32 i = 0; i < 3; i++) + { + mGlow[i].release(); + } - releaseScreenBuffers(); + releaseScreenBuffers(); - gBumpImageList.destroyGL(); - LLVOAvatar::resetImpostors(); + gBumpImageList.destroyGL(); + LLVOAvatar::resetImpostors(); } void LLPipeline::releaseLUTBuffers() { - if (mLightFunc) - { - LLImageGL::deleteTextures(1, &mLightFunc); - mLightFunc = 0; - } + if (mLightFunc) + { + LLImageGL::deleteTextures(1, &mLightFunc); + mLightFunc = 0; + } } void LLPipeline::releaseScreenBuffers() { - mUIScreen.release(); - mScreen.release(); - mFXAABuffer.release(); - mPhysicsDisplay.release(); - mDeferredScreen.release(); - mDeferredDepth.release(); - mDeferredLight.release(); - mOcclusionDepth.release(); - releaseShadowTargets(); + mUIScreen.release(); + mScreen.release(); + mFXAABuffer.release(); + mPhysicsDisplay.release(); + mDeferredScreen.release(); + mDeferredDepth.release(); + mDeferredLight.release(); + mOcclusionDepth.release(); + releaseShadowTargets(); } @@ -1221,11 +1208,10 @@ void LLPipeline::releaseShadowTargets() void LLPipeline::createGLBuffers() { - stop_glerror(); - assertInitialized(); - - updateRenderDeferred(); + stop_glerror(); + assertInitialized(); + updateRenderDeferred(); if (LLPipeline::sWaterReflections) { //water reflection texture U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512); @@ -1235,488 +1221,488 @@ void LLPipeline::createGLBuffers() mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true); } - mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE); + mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE); - stop_glerror(); + stop_glerror(); - GLuint resX = gViewerWindow->getWorldViewWidthRaw(); - GLuint resY = gViewerWindow->getWorldViewHeightRaw(); - - if (LLPipeline::sRenderGlow) - { //screen space glow buffers - const U32 glow_res = llmax(1, - llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow"))); + GLuint resX = gViewerWindow->getWorldViewWidthRaw(); + GLuint resY = gViewerWindow->getWorldViewHeightRaw(); + + if (LLPipeline::sRenderGlow) + { //screen space glow buffers + const U32 glow_res = llmax(1, + llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow"))); - for (U32 i = 0; i < 3; i++) - { - mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE); - } + for (U32 i = 0; i < 3; i++) + { + mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE); + } - allocateScreenBuffer(resX,resY); - mScreenWidth = 0; - mScreenHeight = 0; - } - - if (sRenderDeferred) - { - if (!mNoiseMap) - { - const U32 noiseRes = 128; - LLVector3 noise[noiseRes*noiseRes]; - - F32 scaler = gSavedSettings.getF32("RenderDeferredNoise")/100.f; - for (U32 i = 0; i < noiseRes*noiseRes; ++i) - { - noise[i] = LLVector3(ll_frand()-0.5f, ll_frand()-0.5f, 0.f); - noise[i].normVec(); - noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f; - } - - LLImageGL::generateTextures(1, &mNoiseMap); - - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); - LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - if (!mTrueNoiseMap) - { - const U32 noiseRes = 128; - F32 noise[noiseRes*noiseRes*3]; - for (U32 i = 0; i < noiseRes*noiseRes*3; i++) - { - noise[i] = ll_frand()*2.0-1.0; - } - - LLImageGL::generateTextures(1, &mTrueNoiseMap); - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap); - LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - createLUTBuffers(); - } + allocateScreenBuffer(resX,resY); + mScreenWidth = 0; + mScreenHeight = 0; + } + + if (sRenderDeferred) + { + if (!mNoiseMap) + { + const U32 noiseRes = 128; + LLVector3 noise[noiseRes*noiseRes]; + + F32 scaler = gSavedSettings.getF32("RenderDeferredNoise")/100.f; + for (U32 i = 0; i < noiseRes*noiseRes; ++i) + { + noise[i] = LLVector3(ll_frand()-0.5f, ll_frand()-0.5f, 0.f); + noise[i].normVec(); + noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f; + } + + LLImageGL::generateTextures(1, &mNoiseMap); + + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); + LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + + if (!mTrueNoiseMap) + { + const U32 noiseRes = 128; + F32 noise[noiseRes*noiseRes*3]; + for (U32 i = 0; i < noiseRes*noiseRes*3; i++) + { + noise[i] = ll_frand()*2.0-1.0; + } + + LLImageGL::generateTextures(1, &mTrueNoiseMap); + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap); + LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + + createLUTBuffers(); + } - gBumpImageList.restoreGL(); + gBumpImageList.restoreGL(); } F32 lerpf(F32 a, F32 b, F32 w) { - return a + w * (b - a); + return a + w * (b - a); } void LLPipeline::createLUTBuffers() { - if (sRenderDeferred) - { - if (!mLightFunc) - { - U32 lightResX = gSavedSettings.getU32("RenderSpecularResX"); - U32 lightResY = gSavedSettings.getU32("RenderSpecularResY"); - F32* ls = new F32[lightResX*lightResY]; - F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); + if (sRenderDeferred) + { + if (!mLightFunc) + { + U32 lightResX = gSavedSettings.getU32("RenderSpecularResX"); + U32 lightResY = gSavedSettings.getU32("RenderSpecularResY"); + F32* ls = new F32[lightResX*lightResY]; + F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); // Calculate the (normalized) blinn-phong specular lookup texture. (with a few tweaks) - for (U32 y = 0; y < lightResY; ++y) - { - for (U32 x = 0; x < lightResX; ++x) - { - ls[y*lightResX+x] = 0; - F32 sa = (F32) x/(lightResX-1); - F32 spec = (F32) y/(lightResY-1); - F32 n = spec * spec * specExp; - - // Nothing special here. Just your typical blinn-phong term. - spec = powf(sa, n); - - // Apply our normalization function. - // Note: This is the full equation that applies the full normalization curve, not an approximation. - // This is fine, given we only need to create our LUT once per buffer initialization. - spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n))); - - // Since we use R16F, we no longer have a dynamic range issue we need to work around here. - // Though some older drivers may not like this, newer drivers shouldn't have this problem. - ls[y*lightResX+x] = spec; - } - } - - U32 pix_format = GL_R16F; + for (U32 y = 0; y < lightResY; ++y) + { + for (U32 x = 0; x < lightResX; ++x) + { + ls[y*lightResX+x] = 0; + F32 sa = (F32) x/(lightResX-1); + F32 spec = (F32) y/(lightResY-1); + F32 n = spec * spec * specExp; + + // Nothing special here. Just your typical blinn-phong term. + spec = powf(sa, n); + + // Apply our normalization function. + // Note: This is the full equation that applies the full normalization curve, not an approximation. + // This is fine, given we only need to create our LUT once per buffer initialization. + spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n))); + + // Since we use R16F, we no longer have a dynamic range issue we need to work around here. + // Though some older drivers may not like this, newer drivers shouldn't have this problem. + ls[y*lightResX+x] = spec; + } + } + + U32 pix_format = GL_R16F; #if LL_DARWIN - // Need to work around limited precision with 10.6.8 and older drivers - // - pix_format = GL_R32F; + // Need to work around limited precision with 10.6.8 and older drivers + // + pix_format = GL_R32F; #endif - LLImageGL::generateTextures(1, &mLightFunc); - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); - LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, pix_format, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false); - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - delete [] ls; - } - } + LLImageGL::generateTextures(1, &mLightFunc); + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); + LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, pix_format, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false); + gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + delete [] ls; + } + } } void LLPipeline::restoreGL() { - assertInitialized(); + assertInitialized(); - if (mVertexShadersEnabled) - { - LLViewerShaderMgr::instance()->setShaders(); - } + if (mVertexShadersEnabled) + { + LLViewerShaderMgr::instance()->setShaders(); + } - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) - { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) - { - part->restoreGL(); - } - } - } + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + part->restoreGL(); + } + } + } } bool LLPipeline::canUseVertexShaders() { - static const std::string vertex_shader_enable_feature_string = "VertexShaderEnable"; + static const std::string vertex_shader_enable_feature_string = "VertexShaderEnable"; - if (sDisableShaders || - !gGLManager.mHasVertexShader || - !gGLManager.mHasFragmentShader || - !LLFeatureManager::getInstance()->isFeatureAvailable(vertex_shader_enable_feature_string) || - (assertInitialized() && mVertexShadersLoaded != 1) ) - { - return false; - } - else - { - return true; - } + if (sDisableShaders || + !gGLManager.mHasVertexShader || + !gGLManager.mHasFragmentShader || + !LLFeatureManager::getInstance()->isFeatureAvailable(vertex_shader_enable_feature_string) || + (assertInitialized() && mVertexShadersLoaded != 1) ) + { + return false; + } + else + { + return true; + } } bool LLPipeline::canUseWindLightShaders() const { - bool usingWindlight = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1; - bool haveShaders = ((gWLSkyProgram.mProgramObject != 0) || (gDeferredWLSkyProgram.mProgramObject != 0)); - return (!LLPipeline::sDisableShaders && haveShaders && usingWindlight); + return (!LLPipeline::sDisableShaders && + gWLSkyProgram.mProgramObject != 0 && + LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1); } bool LLPipeline::canUseWindLightShadersOnObjects() const { - return (canUseWindLightShaders() - && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0); + return (canUseWindLightShaders() + && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0); } bool LLPipeline::canUseAntiAliasing() const { - return true; + return true; } void LLPipeline::unloadShaders() { - LLViewerShaderMgr::instance()->unloadShaders(); + LLViewerShaderMgr::instance()->unloadShaders(); - mVertexShadersLoaded = 0; + mVertexShadersLoaded = 0; } void LLPipeline::assertInitializedDoError() { - LL_ERRS() << "LLPipeline used when uninitialized." << LL_ENDL; + LL_ERRS() << "LLPipeline used when uninitialized." << LL_ENDL; } //============================================================================ void LLPipeline::enableShadows(const bool enable_shadows) { - //should probably do something here to wrangle shadows.... + //should probably do something here to wrangle shadows.... } S32 LLPipeline::getMaxLightingDetail() const { - /*if (mShaderLevel[SHADER_OBJECT] >= LLDrawPoolSimple::SHADER_LEVEL_LOCAL_LIGHTS) - { - return 3; - } - else*/ - { - return 1; - } + /*if (mShaderLevel[SHADER_OBJECT] >= LLDrawPoolSimple::SHADER_LEVEL_LOCAL_LIGHTS) + { + return 3; + } + else*/ + { + return 1; + } } S32 LLPipeline::setLightingDetail(S32 level) { - refreshCachedSettings(); + refreshCachedSettings(); - if (level < 0) - { - if (RenderLocalLights) - { - level = 1; - } - else - { - level = 0; - } - } - level = llclamp(level, 0, getMaxLightingDetail()); - mLightingDetail = level; - - return mLightingDetail; + if (level < 0) + { + if (RenderLocalLights) + { + level = 1; + } + else + { + level = 0; + } + } + level = llclamp(level, 0, getMaxLightingDetail()); + mLightingDetail = level; + + return mLightingDetail; } class LLOctreeDirtyTexture : public OctreeTraveler { public: - const std::set<LLViewerFetchedTexture*>& mTextures; - - LLOctreeDirtyTexture(const std::set<LLViewerFetchedTexture*>& textures) : mTextures(textures) { } - - virtual void visit(const OctreeNode* node) - { - LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); + const std::set<LLViewerFetchedTexture*>& mTextures; - if (!group->hasState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty()) - { - for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) - { - for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) - { - LLDrawInfo* params = *j; - LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(params->mTexture); - if (tex && mTextures.find(tex) != mTextures.end()) - { - group->setState(LLSpatialGroup::GEOM_DIRTY); - } - } - } - } + LLOctreeDirtyTexture(const std::set<LLViewerFetchedTexture*>& textures) : mTextures(textures) { } - for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i) - { - LLSpatialBridge* bridge = *i; - traverse(bridge->mOctree); - } - } + virtual void visit(const OctreeNode* node) + { + LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); + + if (!group->hasState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty()) + { + for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) + { + for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) + { + LLDrawInfo* params = *j; + LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(params->mTexture); + if (tex && mTextures.find(tex) != mTextures.end()) + { + group->setState(LLSpatialGroup::GEOM_DIRTY); + } + } + } + } + + for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i) + { + LLSpatialBridge* bridge = *i; + traverse(bridge->mOctree); + } + } }; // Called when a texture changes # of channels (causes faces to move to alpha pool) void LLPipeline::dirtyPoolObjectTextures(const std::set<LLViewerFetchedTexture*>& textures) { - assertInitialized(); + assertInitialized(); - // *TODO: This is inefficient and causes frame spikes; need a better way to do this - // Most of the time is spent in dirty.traverse. + // *TODO: This is inefficient and causes frame spikes; need a better way to do this + // Most of the time is spent in dirty.traverse. - for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) - { - LLDrawPool *poolp = *iter; - if (poolp->isFacePool()) - { - ((LLFacePool*) poolp)->dirtyTextures(textures); - } - } - - LLOctreeDirtyTexture dirty(textures); - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) - { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) - { - dirty.traverse(part->mOctree); - } - } - } + for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) + { + LLDrawPool *poolp = *iter; + if (poolp->isFacePool()) + { + ((LLFacePool*) poolp)->dirtyTextures(textures); + } + } + + LLOctreeDirtyTexture dirty(textures); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + dirty.traverse(part->mOctree); + } + } + } } LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0) { - assertInitialized(); + assertInitialized(); - LLDrawPool *poolp = NULL; - switch( type ) - { - case LLDrawPool::POOL_SIMPLE: - poolp = mSimplePool; - break; - - case LLDrawPool::POOL_GRASS: - poolp = mGrassPool; - break; - - case LLDrawPool::POOL_ALPHA_MASK: - poolp = mAlphaMaskPool; - break; - - case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK: - poolp = mFullbrightAlphaMaskPool; - break; - - case LLDrawPool::POOL_FULLBRIGHT: - poolp = mFullbrightPool; - break; - - case LLDrawPool::POOL_INVISIBLE: - poolp = mInvisiblePool; - break; - - case LLDrawPool::POOL_GLOW: - poolp = mGlowPool; - break; - - case LLDrawPool::POOL_TREE: - poolp = get_if_there(mTreePools, (uintptr_t)tex0, (LLDrawPool*)0 ); - break; - - case LLDrawPool::POOL_TERRAIN: - poolp = get_if_there(mTerrainPools, (uintptr_t)tex0, (LLDrawPool*)0 ); - break; - - case LLDrawPool::POOL_BUMP: - poolp = mBumpPool; - break; - case LLDrawPool::POOL_MATERIALS: - poolp = mMaterialsPool; - break; - case LLDrawPool::POOL_ALPHA: - poolp = mAlphaPool; - break; - - case LLDrawPool::POOL_AVATAR: - break; // Do nothing - - case LLDrawPool::POOL_SKY: - poolp = mSkyPool; - break; - - case LLDrawPool::POOL_WATER: - poolp = mWaterPool; - break; - - case LLDrawPool::POOL_GROUND: - poolp = mGroundPool; - break; - - case LLDrawPool::POOL_WL_SKY: - poolp = mWLSkyPool; - break; - - default: - llassert(0); - LL_ERRS() << "Invalid Pool Type in LLPipeline::findPool() type=" << type << LL_ENDL; - break; - } + LLDrawPool *poolp = NULL; + switch( type ) + { + case LLDrawPool::POOL_SIMPLE: + poolp = mSimplePool; + break; + + case LLDrawPool::POOL_GRASS: + poolp = mGrassPool; + break; + + case LLDrawPool::POOL_ALPHA_MASK: + poolp = mAlphaMaskPool; + break; + + case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK: + poolp = mFullbrightAlphaMaskPool; + break; + + case LLDrawPool::POOL_FULLBRIGHT: + poolp = mFullbrightPool; + break; + + case LLDrawPool::POOL_INVISIBLE: + poolp = mInvisiblePool; + break; + + case LLDrawPool::POOL_GLOW: + poolp = mGlowPool; + break; + + case LLDrawPool::POOL_TREE: + poolp = get_if_there(mTreePools, (uintptr_t)tex0, (LLDrawPool*)0 ); + break; + + case LLDrawPool::POOL_TERRAIN: + poolp = get_if_there(mTerrainPools, (uintptr_t)tex0, (LLDrawPool*)0 ); + break; + + case LLDrawPool::POOL_BUMP: + poolp = mBumpPool; + break; + case LLDrawPool::POOL_MATERIALS: + poolp = mMaterialsPool; + break; + case LLDrawPool::POOL_ALPHA: + poolp = mAlphaPool; + break; + + case LLDrawPool::POOL_AVATAR: + break; // Do nothing + + case LLDrawPool::POOL_SKY: + poolp = mSkyPool; + break; + + case LLDrawPool::POOL_WATER: + poolp = mWaterPool; + break; + + case LLDrawPool::POOL_GROUND: + poolp = mGroundPool; + break; + + case LLDrawPool::POOL_WL_SKY: + poolp = mWLSkyPool; + break; + + default: + llassert(0); + LL_ERRS() << "Invalid Pool Type in LLPipeline::findPool() type=" << type << LL_ENDL; + break; + } - return poolp; + return poolp; } -LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerTexture *tex0) +LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerTexture *tex0) { - LLDrawPool *poolp = findPool(type, tex0); - if (poolp) - { - return poolp; - } + LLDrawPool *poolp = findPool(type, tex0); + if (poolp) + { + return poolp; + } - LLDrawPool *new_poolp = LLDrawPool::createPool(type, tex0); - addPool( new_poolp ); + LLDrawPool *new_poolp = LLDrawPool::createPool(type, tex0); + addPool( new_poolp ); - return new_poolp; + return new_poolp; } // static LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerTexture* imagep) { - U32 type = getPoolTypeFromTE(te, imagep); - return gPipeline.getPool(type, imagep); + U32 type = getPoolTypeFromTE(te, imagep); + return gPipeline.getPool(type, imagep); } //static U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* imagep) { - if (!te || !imagep) - { - return 0; - } - - LLMaterial* mat = te->getMaterialParams().get(); + if (!te || !imagep) + { + return 0; + } + + LLMaterial* mat = te->getMaterialParams().get(); - bool color_alpha = te->getColor().mV[3] < 0.999f; - bool alpha = color_alpha; - if (imagep) - { - alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2); - } + bool color_alpha = te->getColor().mV[3] < 0.999f; + bool alpha = color_alpha; + if (imagep) + { + alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2); + } - if (alpha && mat) - { - switch (mat->getDiffuseAlphaMode()) - { - case 1: - alpha = true; // Material's alpha mode is set to blend. Toss it into the alpha draw pool. - break; - case 0: //alpha mode set to none, never go to alpha pool - case 3: //alpha mode set to emissive, never go to alpha pool - alpha = color_alpha; - break; - default: //alpha mode set to "mask", go to alpha pool if fullbright - alpha = color_alpha; // Material's alpha mode is set to none, mask, or emissive. Toss it into the opaque material draw pool. - break; - } - } - - if (alpha) - { - return LLDrawPool::POOL_ALPHA; - } - else if ((te->getBumpmap() || te->getShiny()) && (!mat || mat->getNormalID().isNull())) - { - return LLDrawPool::POOL_BUMP; - } - else if (mat && !alpha) - { - return LLDrawPool::POOL_MATERIALS; - } - else - { - return LLDrawPool::POOL_SIMPLE; - } + if (alpha && mat) + { + switch (mat->getDiffuseAlphaMode()) + { + case 1: + alpha = true; // Material's alpha mode is set to blend. Toss it into the alpha draw pool. + break; + case 0: //alpha mode set to none, never go to alpha pool + case 3: //alpha mode set to emissive, never go to alpha pool + alpha = color_alpha; + break; + default: //alpha mode set to "mask", go to alpha pool if fullbright + alpha = color_alpha; // Material's alpha mode is set to none, mask, or emissive. Toss it into the opaque material draw pool. + break; + } + } + + if (alpha) + { + return LLDrawPool::POOL_ALPHA; + } + else if ((te->getBumpmap() || te->getShiny()) && (!mat || mat->getNormalID().isNull())) + { + return LLDrawPool::POOL_BUMP; + } + else if (mat && !alpha) + { + return LLDrawPool::POOL_MATERIALS; + } + else + { + return LLDrawPool::POOL_SIMPLE; + } } void LLPipeline::addPool(LLDrawPool *new_poolp) { - assertInitialized(); - mPools.insert(new_poolp); - addToQuickLookup( new_poolp ); + assertInitialized(); + mPools.insert(new_poolp); + addToQuickLookup( new_poolp ); } void LLPipeline::allocDrawable(LLViewerObject *vobj) { - LLDrawable *drawable = new LLDrawable(vobj); - vobj->mDrawable = drawable; - - //encompass completely sheared objects by taking - //the most extreme point possible (<1,1,0.5>) - drawable->setRadius(LLVector3(1,1,0.5f).scaleVec(vobj->getScale()).length()); - if (vobj->isOrphaned()) - { - drawable->setState(LLDrawable::FORCE_INVISIBLE); - } - drawable->updateXform(TRUE); + LLDrawable *drawable = new LLDrawable(vobj); + vobj->mDrawable = drawable; + + //encompass completely sheared objects by taking + //the most extreme point possible (<1,1,0.5>) + drawable->setRadius(LLVector3(1,1,0.5f).scaleVec(vobj->getScale()).length()); + if (vobj->isOrphaned()) + { + drawable->setState(LLDrawable::FORCE_INVISIBLE); + } + drawable->updateXform(TRUE); } @@ -1728,74 +1714,74 @@ static LLTrace::BlockTimerStatHandle FTM_REMOVE_FROM_HIGHLIGHT_SET("Highlight Se void LLPipeline::unlinkDrawable(LLDrawable *drawable) { - LL_RECORD_BLOCK_TIME(FTM_UNLINK); + LL_RECORD_BLOCK_TIME(FTM_UNLINK); - assertInitialized(); + assertInitialized(); - LLPointer<LLDrawable> drawablep = drawable; // make sure this doesn't get deleted before we are done - - // Based on flags, remove the drawable from the queues that it's on. - if (drawablep->isState(LLDrawable::ON_MOVE_LIST)) - { - LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_MOVE_LIST); - LLDrawable::drawable_vector_t::iterator iter = std::find(mMovedList.begin(), mMovedList.end(), drawablep); - if (iter != mMovedList.end()) - { - mMovedList.erase(iter); - } - } + LLPointer<LLDrawable> drawablep = drawable; // make sure this doesn't get deleted before we are done + + // Based on flags, remove the drawable from the queues that it's on. + if (drawablep->isState(LLDrawable::ON_MOVE_LIST)) + { + LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_MOVE_LIST); + LLDrawable::drawable_vector_t::iterator iter = std::find(mMovedList.begin(), mMovedList.end(), drawablep); + if (iter != mMovedList.end()) + { + mMovedList.erase(iter); + } + } - if (drawablep->getSpatialGroup()) - { - LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_SPATIAL_PARTITION); - if (!drawablep->getSpatialGroup()->getSpatialPartition()->remove(drawablep, drawablep->getSpatialGroup())) - { + if (drawablep->getSpatialGroup()) + { + LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_SPATIAL_PARTITION); + if (!drawablep->getSpatialGroup()->getSpatialPartition()->remove(drawablep, drawablep->getSpatialGroup())) + { #ifdef LL_RELEASE_FOR_DOWNLOAD - LL_WARNS() << "Couldn't remove object from spatial group!" << LL_ENDL; + LL_WARNS() << "Couldn't remove object from spatial group!" << LL_ENDL; #else - LL_ERRS() << "Couldn't remove object from spatial group!" << LL_ENDL; + LL_ERRS() << "Couldn't remove object from spatial group!" << LL_ENDL; #endif - } - } - - { - LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_LIGHT_SET); - mLights.erase(drawablep); - - for (light_set_t::iterator iter = mNearbyLights.begin(); - iter != mNearbyLights.end(); iter++) - { - if (iter->drawable == drawablep) - { - mNearbyLights.erase(iter); - break; - } - } - } - - { - LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_HIGHLIGHT_SET); - HighlightItem item(drawablep); - mHighlightSet.erase(item); + } + } - if (mHighlightObject == drawablep) - { - mHighlightObject = NULL; - } - } + { + LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_LIGHT_SET); + mLights.erase(drawablep); + + for (light_set_t::iterator iter = mNearbyLights.begin(); + iter != mNearbyLights.end(); iter++) + { + if (iter->drawable == drawablep) + { + mNearbyLights.erase(iter); + break; + } + } + } - for (U32 i = 0; i < 2; ++i) - { - if (mShadowSpotLight[i] == drawablep) - { - mShadowSpotLight[i] = NULL; - } + { + LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_HIGHLIGHT_SET); + HighlightItem item(drawablep); + mHighlightSet.erase(item); + + if (mHighlightObject == drawablep) + { + mHighlightObject = NULL; + } + } - if (mTargetShadowSpotLight[i] == drawablep) - { - mTargetShadowSpotLight[i] = NULL; - } - } + for (U32 i = 0; i < 2; ++i) + { + if (mShadowSpotLight[i] == drawablep) + { + mShadowSpotLight[i] = NULL; + } + + if (mTargetShadowSpotLight[i] == drawablep) + { + mTargetShadowSpotLight[i] = NULL; + } + } } @@ -1803,201 +1789,201 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) //static void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar) { - LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_LIGHT_SET); - for (light_set_t::iterator iter = gPipeline.mNearbyLights.begin(); - iter != gPipeline.mNearbyLights.end(); iter++) - { - if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar) - { - gPipeline.mLights.erase(iter->drawable); - gPipeline.mNearbyLights.erase(iter); - } - } + LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_LIGHT_SET); + for (light_set_t::iterator iter = gPipeline.mNearbyLights.begin(); + iter != gPipeline.mNearbyLights.end(); iter++) + { + if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar) + { + gPipeline.mLights.erase(iter->drawable); + gPipeline.mNearbyLights.erase(iter); + } + } } U32 LLPipeline::addObject(LLViewerObject *vobj) { - if (RenderDelayCreation) - { - mCreateQ.push_back(vobj); - } - else - { - createObject(vobj); - } + if (RenderDelayCreation) + { + mCreateQ.push_back(vobj); + } + else + { + createObject(vobj); + } - return 1; + return 1; } void LLPipeline::createObjects(F32 max_dtime) { - LL_RECORD_BLOCK_TIME(FTM_PIPELINE_CREATE); + LL_RECORD_BLOCK_TIME(FTM_PIPELINE_CREATE); - LLTimer update_timer; + LLTimer update_timer; - while (!mCreateQ.empty() && update_timer.getElapsedTimeF32() < max_dtime) - { - LLViewerObject* vobj = mCreateQ.front(); - if (!vobj->isDead()) - { - createObject(vobj); - } - mCreateQ.pop_front(); - } - - //for (LLViewerObject::vobj_list_t::iterator iter = mCreateQ.begin(); iter != mCreateQ.end(); ++iter) - //{ - // createObject(*iter); - //} + while (!mCreateQ.empty() && update_timer.getElapsedTimeF32() < max_dtime) + { + LLViewerObject* vobj = mCreateQ.front(); + if (!vobj->isDead()) + { + createObject(vobj); + } + mCreateQ.pop_front(); + } + + //for (LLViewerObject::vobj_list_t::iterator iter = mCreateQ.begin(); iter != mCreateQ.end(); ++iter) + //{ + // createObject(*iter); + //} - //mCreateQ.clear(); + //mCreateQ.clear(); } void LLPipeline::createObject(LLViewerObject* vobj) { - LLDrawable* drawablep = vobj->mDrawable; + LLDrawable* drawablep = vobj->mDrawable; - if (!drawablep) - { - drawablep = vobj->createDrawable(this); - } - else - { - LL_ERRS() << "Redundant drawable creation!" << LL_ENDL; - } - - llassert(drawablep); + if (!drawablep) + { + drawablep = vobj->createDrawable(this); + } + else + { + LL_ERRS() << "Redundant drawable creation!" << LL_ENDL; + } + + llassert(drawablep); - if (vobj->getParent()) - { - vobj->setDrawableParent(((LLViewerObject*)vobj->getParent())->mDrawable); // LLPipeline::addObject 1 - } - else - { - vobj->setDrawableParent(NULL); // LLPipeline::addObject 2 - } + if (vobj->getParent()) + { + vobj->setDrawableParent(((LLViewerObject*)vobj->getParent())->mDrawable); // LLPipeline::addObject 1 + } + else + { + vobj->setDrawableParent(NULL); // LLPipeline::addObject 2 + } - markRebuild(drawablep, LLDrawable::REBUILD_ALL, TRUE); + markRebuild(drawablep, LLDrawable::REBUILD_ALL, TRUE); - if (drawablep->getVOVolume() && RenderAnimateRes) - { - // fun animated res - drawablep->updateXform(TRUE); - drawablep->clearState(LLDrawable::MOVE_UNDAMPED); - drawablep->setScale(LLVector3(0,0,0)); - drawablep->makeActive(); - } + if (drawablep->getVOVolume() && RenderAnimateRes) + { + // fun animated res + drawablep->updateXform(TRUE); + drawablep->clearState(LLDrawable::MOVE_UNDAMPED); + drawablep->setScale(LLVector3(0,0,0)); + drawablep->makeActive(); + } } void LLPipeline::resetFrameStats() { - assertInitialized(); + assertInitialized(); - sCompiles = 0; - mNumVisibleFaces = 0; + sCompiles = 0; + mNumVisibleFaces = 0; - if (mOldRenderDebugMask != mRenderDebugMask) - { - gObjectList.clearDebugText(); - mOldRenderDebugMask = mRenderDebugMask; - } + if (mOldRenderDebugMask != mRenderDebugMask) + { + gObjectList.clearDebugText(); + mOldRenderDebugMask = mRenderDebugMask; + } } //external functions for asynchronous updating void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep) { - if (FreezeTime) - { - return; - } - if (!drawablep) - { - LL_ERRS() << "updateMove called with NULL drawablep" << LL_ENDL; - return; - } - if (drawablep->isState(LLDrawable::EARLY_MOVE)) - { - return; - } + if (FreezeTime) + { + return; + } + if (!drawablep) + { + LL_ERRS() << "updateMove called with NULL drawablep" << LL_ENDL; + return; + } + if (drawablep->isState(LLDrawable::EARLY_MOVE)) + { + return; + } - assertInitialized(); + assertInitialized(); - // update drawable now - drawablep->clearState(LLDrawable::MOVE_UNDAMPED); // force to DAMPED - drawablep->updateMove(); // returns done - drawablep->setState(LLDrawable::EARLY_MOVE); // flag says we already did an undamped move this frame - // Put on move list so that EARLY_MOVE gets cleared - if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) - { - mMovedList.push_back(drawablep); - drawablep->setState(LLDrawable::ON_MOVE_LIST); - } + // update drawable now + drawablep->clearState(LLDrawable::MOVE_UNDAMPED); // force to DAMPED + drawablep->updateMove(); // returns done + drawablep->setState(LLDrawable::EARLY_MOVE); // flag says we already did an undamped move this frame + // Put on move list so that EARLY_MOVE gets cleared + if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) + { + mMovedList.push_back(drawablep); + drawablep->setState(LLDrawable::ON_MOVE_LIST); + } } void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep) { - if (FreezeTime) - { - return; - } - if (!drawablep) - { - LL_ERRS() << "updateMove called with NULL drawablep" << LL_ENDL; - return; - } - if (drawablep->isState(LLDrawable::EARLY_MOVE)) - { - return; - } + if (FreezeTime) + { + return; + } + if (!drawablep) + { + LL_ERRS() << "updateMove called with NULL drawablep" << LL_ENDL; + return; + } + if (drawablep->isState(LLDrawable::EARLY_MOVE)) + { + return; + } - assertInitialized(); + assertInitialized(); - // update drawable now - drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED - drawablep->updateMove(); - drawablep->setState(LLDrawable::EARLY_MOVE); // flag says we already did an undamped move this frame - // Put on move list so that EARLY_MOVE gets cleared - if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) - { - mMovedList.push_back(drawablep); - drawablep->setState(LLDrawable::ON_MOVE_LIST); - } + // update drawable now + drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED + drawablep->updateMove(); + drawablep->setState(LLDrawable::EARLY_MOVE); // flag says we already did an undamped move this frame + // Put on move list so that EARLY_MOVE gets cleared + if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) + { + mMovedList.push_back(drawablep); + drawablep->setState(LLDrawable::ON_MOVE_LIST); + } } void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list) { - for (LLDrawable::drawable_vector_t::iterator iter = moved_list.begin(); - iter != moved_list.end(); ) - { - LLDrawable::drawable_vector_t::iterator curiter = iter++; - LLDrawable *drawablep = *curiter; - bool done = true; - if (!drawablep->isDead() && (!drawablep->isState(LLDrawable::EARLY_MOVE))) - { - done = drawablep->updateMove(); - } - drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED); - if (done) - { - if (drawablep->isRoot()) - { - drawablep->makeStatic(); - } - drawablep->clearState(LLDrawable::ON_MOVE_LIST); - if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) - { //will likely not receive any future world matrix updates - // -- this keeps attachments from getting stuck in space and falling off your avatar - drawablep->clearState(LLDrawable::ANIMATED_CHILD); - markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, TRUE); - if (drawablep->getVObj()) - { - drawablep->getVObj()->dirtySpatialGroup(TRUE); - } - } - iter = moved_list.erase(curiter); - } - } + for (LLDrawable::drawable_vector_t::iterator iter = moved_list.begin(); + iter != moved_list.end(); ) + { + LLDrawable::drawable_vector_t::iterator curiter = iter++; + LLDrawable *drawablep = *curiter; + bool done = true; + if (!drawablep->isDead() && (!drawablep->isState(LLDrawable::EARLY_MOVE))) + { + done = drawablep->updateMove(); + } + drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED); + if (done) + { + if (drawablep->isRoot()) + { + drawablep->makeStatic(); + } + drawablep->clearState(LLDrawable::ON_MOVE_LIST); + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { //will likely not receive any future world matrix updates + // -- this keeps attachments from getting stuck in space and falling off your avatar + drawablep->clearState(LLDrawable::ANIMATED_CHILD); + markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, TRUE); + if (drawablep->getVObj()) + { + drawablep->getVObj()->dirtySpatialGroup(TRUE); + } + } + iter = moved_list.erase(curiter); + } + } } static LLTrace::BlockTimerStatHandle FTM_OCTREE_BALANCE("Balance Octree"); @@ -2007,60 +1993,60 @@ static LLTrace::BlockTimerStatHandle FTM_MOVED_LIST("Moved List"); void LLPipeline::updateMove() { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_MOVE); - - if (FreezeTime) - { - return; - } - - assertInitialized(); - - { - LL_RECORD_BLOCK_TIME(FTM_RETEXTURE); + LL_RECORD_BLOCK_TIME(FTM_UPDATE_MOVE); - for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin(); - iter != mRetexturedList.end(); ++iter) - { - LLDrawable* drawablep = *iter; - if (drawablep && !drawablep->isDead()) - { - drawablep->updateTexture(); - } - } - mRetexturedList.clear(); - } + if (FreezeTime) + { + return; + } - { - LL_RECORD_BLOCK_TIME(FTM_MOVED_LIST); - updateMovedList(mMovedList); - } + assertInitialized(); - //balance octrees - { - LL_RECORD_BLOCK_TIME(FTM_OCTREE_BALANCE); + { + LL_RECORD_BLOCK_TIME(FTM_RETEXTURE); + + for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin(); + iter != mRetexturedList.end(); ++iter) + { + LLDrawable* drawablep = *iter; + if (drawablep && !drawablep->isDead()) + { + drawablep->updateTexture(); + } + } + mRetexturedList.clear(); + } - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) - { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) - { - part->mOctree->balance(); - } - } + { + LL_RECORD_BLOCK_TIME(FTM_MOVED_LIST); + updateMovedList(mMovedList); + } - //balance the VO Cache tree - LLVOCachePartition* vo_part = region->getVOCachePartition(); - if(vo_part) - { - vo_part->mOctree->balance(); - } - } - } + //balance octrees + { + LL_RECORD_BLOCK_TIME(FTM_OCTREE_BALANCE); + + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + part->mOctree->balance(); + } + } + + //balance the VO Cache tree + LLVOCachePartition* vo_part = region->getVOCachePartition(); + if(vo_part) + { + vo_part->mOctree->balance(); + } + } + } } ///////////////////////////////////////////////////////////////////////////// @@ -2070,349 +2056,349 @@ void LLPipeline::updateMove() //static F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera) { - LLVector3 lookAt = center - camera.getOrigin(); - F32 dist = lookAt.length(); + LLVector3 lookAt = center - camera.getOrigin(); + F32 dist = lookAt.length(); - //ramp down distance for nearby objects - //shrink dist by dist/16. - if (dist < 16.f) - { - dist /= 16.f; - dist *= dist; - dist *= 16.f; - } + //ramp down distance for nearby objects + //shrink dist by dist/16. + if (dist < 16.f) + { + dist /= 16.f; + dist *= dist; + dist *= 16.f; + } - //get area of circle around node - F32 app_angle = atanf(size.length()/dist); - F32 radius = app_angle*LLDrawable::sCurPixelAngle; - return radius*radius * F_PI; + //get area of circle around node + F32 app_angle = atanf(size.length()/dist); + F32 radius = app_angle*LLDrawable::sCurPixelAngle; + return radius*radius * F_PI; } //static F32 LLPipeline::calcPixelArea(const LLVector4a& center, const LLVector4a& size, LLCamera &camera) { - LLVector4a origin; - origin.load3(camera.getOrigin().mV); + LLVector4a origin; + origin.load3(camera.getOrigin().mV); - LLVector4a lookAt; - lookAt.setSub(center, origin); - F32 dist = lookAt.getLength3().getF32(); + LLVector4a lookAt; + lookAt.setSub(center, origin); + F32 dist = lookAt.getLength3().getF32(); - //ramp down distance for nearby objects - //shrink dist by dist/16. - if (dist < 16.f) - { - dist /= 16.f; - dist *= dist; - dist *= 16.f; - } + //ramp down distance for nearby objects + //shrink dist by dist/16. + if (dist < 16.f) + { + dist /= 16.f; + dist *= dist; + dist *= 16.f; + } - //get area of circle around node - F32 app_angle = atanf(size.getLength3().getF32()/dist); - F32 radius = app_angle*LLDrawable::sCurPixelAngle; - return radius*radius * F_PI; + //get area of circle around node + F32 app_angle = atanf(size.getLength3().getF32()/dist); + F32 radius = app_angle*LLDrawable::sCurPixelAngle; + return radius*radius * F_PI; } void LLPipeline::grabReferences(LLCullResult& result) { - sCull = &result; + sCull = &result; } void LLPipeline::clearReferences() { - sCull = NULL; - mGroupSaveQ1.clear(); + sCull = NULL; + mGroupSaveQ1.clear(); } void check_references(LLSpatialGroup* group, LLDrawable* drawable) { - for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) - { - if (drawable == (LLDrawable*)(*i)->getDrawable()) - { - LL_ERRS() << "LLDrawable deleted while actively reference by LLPipeline." << LL_ENDL; - } - } + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + { + if (drawable == (LLDrawable*)(*i)->getDrawable()) + { + LL_ERRS() << "LLDrawable deleted while actively reference by LLPipeline." << LL_ENDL; + } + } } void check_references(LLDrawable* drawable, LLFace* face) { - for (S32 i = 0; i < drawable->getNumFaces(); ++i) - { - if (drawable->getFace(i) == face) - { - LL_ERRS() << "LLFace deleted while actively referenced by LLPipeline." << LL_ENDL; - } - } + for (S32 i = 0; i < drawable->getNumFaces(); ++i) + { + if (drawable->getFace(i) == face) + { + LL_ERRS() << "LLFace deleted while actively referenced by LLPipeline." << LL_ENDL; + } + } } void check_references(LLSpatialGroup* group, LLFace* face) { - for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) - { - LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); - if(drawable) - { - check_references(drawable, face); - } + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + { + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(drawable) + { + check_references(drawable, face); + } } } void LLPipeline::checkReferences(LLFace* face) { -#if CHECK_PIPELINE_REFERENCES - if (sCull) - { - for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - check_references(group, face); - } - - for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - check_references(group, face); - } - - for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - check_references(group, face); - } - - for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) - { - LLDrawable* drawable = *iter; - check_references(drawable, face); - } - } +#if 0 + if (sCull) + { + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) + { + LLDrawable* drawable = *iter; + check_references(drawable, face); + } + } #endif } void LLPipeline::checkReferences(LLDrawable* drawable) { -#if CHECK_PIPELINE_REFERENCES - if (sCull) - { - for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - check_references(group, drawable); - } - - for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - check_references(group, drawable); - } - - for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - check_references(group, drawable); - } - - for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) - { - if (drawable == *iter) - { - LL_ERRS() << "LLDrawable deleted while actively referenced by LLPipeline." << LL_ENDL; - } - } - } +#if 0 + if (sCull) + { + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) + { + if (drawable == *iter) + { + LL_ERRS() << "LLDrawable deleted while actively referenced by LLPipeline." << LL_ENDL; + } + } + } #endif } void check_references(LLSpatialGroup* group, LLDrawInfo* draw_info) { - for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) - { - LLSpatialGroup::drawmap_elem_t& draw_vec = i->second; - for (LLSpatialGroup::drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) - { - LLDrawInfo* params = *j; - if (params == draw_info) - { - LL_ERRS() << "LLDrawInfo deleted while actively referenced by LLPipeline." << LL_ENDL; - } - } - } + for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) + { + LLSpatialGroup::drawmap_elem_t& draw_vec = i->second; + for (LLSpatialGroup::drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) + { + LLDrawInfo* params = *j; + if (params == draw_info) + { + LL_ERRS() << "LLDrawInfo deleted while actively referenced by LLPipeline." << LL_ENDL; + } + } + } } void LLPipeline::checkReferences(LLDrawInfo* draw_info) { -#if CHECK_PIPELINE_REFERENCES - if (sCull) - { - for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - check_references(group, draw_info); - } - - for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - check_references(group, draw_info); - } - - for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - check_references(group, draw_info); - } - } +#if 0 + if (sCull) + { + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + + for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + } #endif } void LLPipeline::checkReferences(LLSpatialGroup* group) { #if CHECK_PIPELINE_REFERENCES - if (sCull) - { - for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) - { - if (group == *iter) - { - LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL; - } - } - - for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) - { - if (group == *iter) - { - LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL; - } - } - - for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) - { - if (group == *iter) - { - LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL; - } - } - } + if (sCull) + { + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + if (group == *iter) + { + LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL; + } + } + + for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + if (group == *iter) + { + LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL; + } + } + + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + if (group == *iter) + { + LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL; + } + } + } #endif } bool LLPipeline::visibleObjectsInFrustum(LLCamera& camera) { - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) - { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) - { - if (hasRenderType(part->mDrawableType)) - { - if (part->visibleObjectsInFrustum(camera)) - { - return true; - } - } - } - } - } + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + if (hasRenderType(part->mDrawableType)) + { + if (part->visibleObjectsInFrustum(camera)) + { + return true; + } + } + } + } + } - return false; + return false; } bool LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& max) { - const F32 X = 65536.f; + const F32 X = 65536.f; - min = LLVector3(X,X,X); - max = LLVector3(-X,-X,-X); + min = LLVector3(X,X,X); + max = LLVector3(-X,-X,-X); - LLViewerCamera::eCameraID saved_camera_id = LLViewerCamera::sCurCameraID; - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; + LLViewerCamera::eCameraID saved_camera_id = LLViewerCamera::sCurCameraID; + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; - bool res = true; + bool res = true; - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) - { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) - { - if (hasRenderType(part->mDrawableType)) - { - if (!part->getVisibleExtents(camera, min, max)) - { - res = false; - } - } - } - } - } + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + if (hasRenderType(part->mDrawableType)) + { + if (!part->getVisibleExtents(camera, min, max)) + { + res = false; + } + } + } + } + } - LLViewerCamera::sCurCameraID = saved_camera_id; + LLViewerCamera::sCurCameraID = saved_camera_id; - return res; + return res; } static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling"); void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip, LLPlane* planep) { - static LLCachedControl<bool> use_occlusion(gSavedSettings,"UseOcclusion"); - static bool can_use_occlusion = LLGLSLShader::sNoFixedFunction - && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") - && gGLManager.mHasOcclusionQuery; + static LLCachedControl<bool> use_occlusion(gSavedSettings,"UseOcclusion"); + static bool can_use_occlusion = LLGLSLShader::sNoFixedFunction + && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") + && gGLManager.mHasOcclusionQuery; - LL_RECORD_BLOCK_TIME(FTM_CULL); + LL_RECORD_BLOCK_TIME(FTM_CULL); - grabReferences(result); + grabReferences(result); - sCull->clear(); + sCull->clear(); - bool to_texture = LLPipeline::sUseOcclusion > 1 && - !hasRenderType(LLPipeline::RENDER_TYPE_HUD) && - LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && - gPipeline.canUseVertexShaders() && - sRenderGlow; + bool to_texture = LLPipeline::sUseOcclusion > 1 && + !hasRenderType(LLPipeline::RENDER_TYPE_HUD) && + LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && + gPipeline.canUseVertexShaders() && + sRenderGlow; - if (to_texture) - { - if (LLPipeline::sRenderDeferred && can_use_occlusion) - { - mOcclusionDepth.bindTarget(); - } - else - { - mScreen.bindTarget(); - } - } + if (to_texture) + { + if (LLPipeline::sRenderDeferred && can_use_occlusion) + { + mOcclusionDepth.bindTarget(); + } + else + { + mScreen.bindTarget(); + } + } - if (sUseOcclusion > 1) - { - gGL.setColorMask(false, false); - } + if (sUseOcclusion > 1) + { + gGL.setColorMask(false, false); + } - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadMatrix(gGLLastProjection); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLLastModelView); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadMatrix(gGLLastProjection); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLLastModelView); - LLGLDisable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLGLDisable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); LLGLDepthTest depth(GL_TRUE, GL_FALSE); @@ -2467,32 +2453,33 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl LLPipeline::sUseFarClip = use_far_clip; - if (bound_shader) - { - gOcclusionCubeProgram.unbind(); - } + if (bound_shader) + { + gOcclusionCubeProgram.unbind(); + } - camera.disableUserClipPlane(); + camera.disableUserClipPlane(); - if (hasRenderType(LLPipeline::RENDER_TYPE_SKY) && - gSky.mVOSkyp.notNull() && - gSky.mVOSkyp->mDrawable.notNull()) - { - gSky.mVOSkyp->mDrawable->setVisible(camera); - sCull->pushDrawable(gSky.mVOSkyp->mDrawable); - gSky.updateCull(); - stop_glerror(); - } + if (hasRenderType(LLPipeline::RENDER_TYPE_SKY) && + gSky.mVOSkyp.notNull() && + gSky.mVOSkyp->mDrawable.notNull()) + { + gSky.mVOSkyp->mDrawable->setVisible(camera); + sCull->pushDrawable(gSky.mVOSkyp->mDrawable); + gSky.updateCull(); + stop_glerror(); + } + + if (hasRenderType(LLPipeline::RENDER_TYPE_GROUND) && + !gPipeline.canUseWindLightShaders() && + gSky.mVOGroundp.notNull() && + gSky.mVOGroundp->mDrawable.notNull() && + !LLPipeline::sWaterReflections) + { + gSky.mVOGroundp->mDrawable->setVisible(camera); + sCull->pushDrawable(gSky.mVOGroundp->mDrawable); + } - if (hasRenderType(LLPipeline::RENDER_TYPE_GROUND) && - !gPipeline.canUseWindLightShaders() && - gSky.mVOGroundp.notNull() && - gSky.mVOGroundp->mDrawable.notNull() && - !LLPipeline::sWaterReflections) - { - gSky.mVOGroundp->mDrawable->setVisible(camera); - sCull->pushDrawable(gSky.mVOGroundp->mDrawable); - } if (hasRenderType(LLPipeline::RENDER_TYPE_WL_SKY) && gPipeline.canUseWindLightShaders() && @@ -2514,304 +2501,247 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl } #endif - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); + + + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); if (sUseOcclusion > 1) - { - gGL.setColorMask(true, false); - } + { + gGL.setColorMask(true, false); + } - if (to_texture) - { - if (LLPipeline::sRenderDeferred && can_use_occlusion) - { - mOcclusionDepth.flush(); - } - else - { - mScreen.flush(); - } - } + if (to_texture) + { + if (LLPipeline::sRenderDeferred && can_use_occlusion) + { + mOcclusionDepth.flush(); + } + else + { + mScreen.flush(); + } + } } void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) { - if (group->isEmpty()) - { - return; - } - - group->setVisible(); + if (group->isEmpty()) + { + return; + } + + group->setVisible(); - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) - { - group->updateDistance(camera); - } - - const F32 MINIMUM_PIXEL_AREA = 16.f; + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + { + group->updateDistance(camera); + } + + const F32 MINIMUM_PIXEL_AREA = 16.f; - if (group->mPixelArea < MINIMUM_PIXEL_AREA) - { - return; - } + if (group->mPixelArea < MINIMUM_PIXEL_AREA) + { + return; + } - const LLVector4a* bounds = group->getBounds(); - if (sMinRenderSize > 0.f && - llmax(llmax(bounds[1][0], bounds[1][1]), bounds[1][2]) < sMinRenderSize) - { - return; - } + const LLVector4a* bounds = group->getBounds(); + if (sMinRenderSize > 0.f && + llmax(llmax(bounds[1][0], bounds[1][1]), bounds[1][2]) < sMinRenderSize) + { + return; + } - assertInitialized(); - - if (!group->getSpatialPartition()->mRenderByGroup) - { //render by drawable - sCull->pushDrawableGroup(group); - } - else - { //render by group - sCull->pushVisibleGroup(group); - } + assertInitialized(); + + if (!group->getSpatialPartition()->mRenderByGroup) + { //render by drawable + sCull->pushDrawableGroup(group); + } + else + { //render by group + sCull->pushVisibleGroup(group); + } - mNumVisibleNodes++; + mNumVisibleNodes++; } void LLPipeline::markOccluder(LLSpatialGroup* group) { - if (sUseOcclusion > 1 && group && !group->isOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION)) - { - LLSpatialGroup* parent = group->getParent(); - - if (!parent || !parent->isOcclusionState(LLSpatialGroup::OCCLUDED)) - { //only mark top most occluders as active occlusion - sCull->pushOcclusionGroup(group); - group->setOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION); - - if (parent && - !parent->isOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION) && - parent->getElementCount() == 0 && - parent->needsUpdate()) - { - sCull->pushOcclusionGroup(group); - parent->setOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION); - } - } - } -} - -void LLPipeline::downsampleMinMaxDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space) -{ - LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr; - - LLGLSLShader* shader = NULL; - - if (scratch_space) - { - scratch_space->copyContents(source, - 0, 0, source.getWidth(), source.getHeight(), - 0, 0, scratch_space->getWidth(), scratch_space->getHeight(), source.hasStencil() ? GL_DEPTH_BUFFER_BIT : GL_COLOR_BUFFER_BIT, GL_NEAREST); - } - - dest.bindTarget(); - dest.clear(GL_COLOR_BUFFER_BIT); // dest should be an RG16F target - - LLStrider<LLVector3> vert; - mDeferredVB->getVertexStrider(vert); - LLStrider<LLVector2> tc0; - - vert[0].set(-1, 1, 0); - vert[1].set(-1, -3, 0); - vert[2].set(3, 1, 0); - - if (source.getUsage() == LLTexUnit::TT_RECT_TEXTURE) - { - shader = &gDownsampleMinMaxDepthRectProgram; - shader->bind(); - shader->uniform2f(sDelta, 1.f, 1.f); - shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, source.getWidth(), source.getHeight()); - } - else - { - shader = &gDownsampleMinMaxDepthRectProgram; - shader->bind(); - shader->uniform2f(sDelta, 1.f / source.getWidth(), 1.f / source.getHeight()); - shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, 1.f, 1.f); - } - - gGL.getTexUnit(0)->bind(scratch_space ? scratch_space : &source, TRUE); - - { - LLGLDepthTest depth(GL_FALSE, GL_FALSE, GL_ALWAYS); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } - - dest.flush(); - - if (last_shader) - { - last_shader->bind(); - } - else - { - shader->unbind(); - } + if (sUseOcclusion > 1 && group && !group->isOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION)) + { + LLSpatialGroup* parent = group->getParent(); + + if (!parent || !parent->isOcclusionState(LLSpatialGroup::OCCLUDED)) + { //only mark top most occluders as active occlusion + sCull->pushOcclusionGroup(group); + group->setOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION); + + if (parent && + !parent->isOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION) && + parent->getElementCount() == 0 && + parent->needsUpdate()) + { + sCull->pushOcclusionGroup(group); + parent->setOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION); + } + } + } } void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space) { - LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr; + LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr; - LLGLSLShader* shader = NULL; + LLGLSLShader* shader = NULL; - if (scratch_space) - { - scratch_space->copyContents(source, - 0, 0, source.getWidth(), source.getHeight(), - 0, 0, scratch_space->getWidth(), scratch_space->getHeight(), source.hasStencil() ? (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT) : GL_COLOR_BUFFER_BIT, GL_NEAREST); - } - - dest.bindTarget(); - dest.clear(GL_DEPTH_BUFFER_BIT); + if (scratch_space) + { + scratch_space->copyContents(source, + 0, 0, source.getWidth(), source.getHeight(), + 0, 0, scratch_space->getWidth(), scratch_space->getHeight(), source.hasStencil() ? (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT) : GL_COLOR_BUFFER_BIT, GL_NEAREST); + } - LLStrider<LLVector3> vert; - mDeferredVB->getVertexStrider(vert); - LLStrider<LLVector2> tc0; - - vert[0].set(-1,1,0); - vert[1].set(-1,-3,0); - vert[2].set(3,1,0); - - if (source.getUsage() == LLTexUnit::TT_RECT_TEXTURE) - { - shader = &gDownsampleDepthRectProgram; - shader->bind(); - shader->uniform2f(sDelta, 1.f, 1.f); - shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, source.getWidth(), source.getHeight()); - } - else - { - shader = &gDownsampleDepthProgram; - shader->bind(); - shader->uniform2f(sDelta, 1.f/source.getWidth(), 1.f/source.getHeight()); - shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, 1.f, 1.f); - } + dest.bindTarget(); + dest.clear(GL_DEPTH_BUFFER_BIT); + + LLStrider<LLVector3> vert; + mDeferredVB->getVertexStrider(vert); + LLStrider<LLVector2> tc0; + + vert[0].set(-1,1,0); + vert[1].set(-1,-3,0); + vert[2].set(3,1,0); + + if (source.getUsage() == LLTexUnit::TT_RECT_TEXTURE) + { + shader = &gDownsampleDepthRectProgram; + shader->bind(); + shader->uniform2f(sDelta, 1.f, 1.f); + shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, source.getWidth(), source.getHeight()); + } + else + { + shader = &gDownsampleDepthProgram; + shader->bind(); + shader->uniform2f(sDelta, 1.f/source.getWidth(), 1.f/source.getHeight()); + shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, 1.f, 1.f); + } - gGL.getTexUnit(0)->bind(scratch_space ? scratch_space : &source, TRUE); + gGL.getTexUnit(0)->bind(scratch_space ? scratch_space : &source, TRUE); - { - LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } - - dest.flush(); - - if (last_shader) - { - last_shader->bind(); - } - else - { - shader->unbind(); - } + { + LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + } + + dest.flush(); + + if (last_shader) + { + last_shader->bind(); + } + else + { + shader->unbind(); + } } void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space) { - downsampleDepthBuffer(source, dest, scratch_space); - dest.bindTarget(); - doOcclusion(camera); - dest.flush(); + downsampleDepthBuffer(source, dest, scratch_space); + dest.bindTarget(); + doOcclusion(camera); + dest.flush(); } void LLPipeline::doOcclusion(LLCamera& camera) { - if (LLPipeline::sUseOcclusion > 1 && !LLSpatialPartition::sTeleportRequested && - (sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck)) - { - LLVertexBuffer::unbind(); - - if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) - { - gGL.setColorMask(true, false, false, false); - } - else - { - gGL.setColorMask(false, false); - } - LLGLDisable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - - LLGLDisable cull(GL_CULL_FACE); - - - bool bind_shader = LLGLSLShader::sNoFixedFunction && LLGLSLShader::sCurBoundShader == 0; - if (bind_shader) - { - if (LLPipeline::sShadowRender) - { - gDeferredShadowCubeProgram.bind(); - } - else - { - gOcclusionCubeProgram.bind(); - } - } - - if (mCubeVB.isNull()) - { //cube VB will be used for issuing occlusion queries - mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); - } - mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - - for (LLCullResult::sg_iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - group->doOcclusion(&camera); - group->clearOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION); - } - - //apply occlusion culling to object cache tree - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLVOCachePartition* vo_part = (*iter)->getVOCachePartition(); - if(vo_part) - { - vo_part->processOccluders(&camera); - } - } - - if (bind_shader) - { - if (LLPipeline::sShadowRender) - { - gDeferredShadowCubeProgram.unbind(); - } - else - { - gOcclusionCubeProgram.unbind(); - } - } - - gGL.setColorMask(true, false); - } + if (LLPipeline::sUseOcclusion > 1 && !LLSpatialPartition::sTeleportRequested && + (sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck)) + { + LLVertexBuffer::unbind(); + + if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) + { + gGL.setColorMask(true, false, false, false); + } + else + { + gGL.setColorMask(false, false); + } + LLGLDisable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + + LLGLDisable cull(GL_CULL_FACE); + + + bool bind_shader = LLGLSLShader::sNoFixedFunction && LLGLSLShader::sCurBoundShader == 0; + if (bind_shader) + { + if (LLPipeline::sShadowRender) + { + gDeferredShadowCubeProgram.bind(); + } + else + { + gOcclusionCubeProgram.bind(); + } + } + + if (mCubeVB.isNull()) + { //cube VB will be used for issuing occlusion queries + mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); + } + mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + + for (LLCullResult::sg_iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + group->doOcclusion(&camera); + group->clearOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION); + } + + //apply occlusion culling to object cache tree + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLVOCachePartition* vo_part = (*iter)->getVOCachePartition(); + if(vo_part) + { + vo_part->processOccluders(&camera); + } + } + + if (bind_shader) + { + if (LLPipeline::sShadowRender) + { + gDeferredShadowCubeProgram.unbind(); + } + else + { + gOcclusionCubeProgram.unbind(); + } + } + + gGL.setColorMask(true, false); + } } - + bool LLPipeline::updateDrawableGeom(LLDrawable* drawablep, bool priority) { - bool update_complete = drawablep->updateGeometry(priority); - if (update_complete && assertInitialized()) - { - drawablep->setState(LLDrawable::BUILT); - } - return update_complete; + bool update_complete = drawablep->updateGeometry(priority); + if (update_complete && assertInitialized()) + { + drawablep->setState(LLDrawable::BUILT); + } + return update_complete; } static LLTrace::BlockTimerStatHandle FTM_SEED_VBO_POOLS("Seed VBO Pool"); @@ -2820,150 +2750,150 @@ static LLTrace::BlockTimerStatHandle FTM_UPDATE_GL("Update GL"); void LLPipeline::updateGL() { - { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_GL); - while (!LLGLUpdate::sGLQ.empty()) - { - LLGLUpdate* glu = LLGLUpdate::sGLQ.front(); - glu->updateGL(); - glu->mInQ = FALSE; - LLGLUpdate::sGLQ.pop_front(); - } - } + { + LL_RECORD_BLOCK_TIME(FTM_UPDATE_GL); + while (!LLGLUpdate::sGLQ.empty()) + { + LLGLUpdate* glu = LLGLUpdate::sGLQ.front(); + glu->updateGL(); + glu->mInQ = FALSE; + LLGLUpdate::sGLQ.pop_front(); + } + } - { //seed VBO Pools - LL_RECORD_BLOCK_TIME(FTM_SEED_VBO_POOLS); - LLVertexBuffer::seedPools(); - } + { //seed VBO Pools + LL_RECORD_BLOCK_TIME(FTM_SEED_VBO_POOLS); + LLVertexBuffer::seedPools(); + } } static LLTrace::BlockTimerStatHandle FTM_REBUILD_PRIORITY_GROUPS("Rebuild Priority Groups"); void LLPipeline::clearRebuildGroups() { - LLSpatialGroup::sg_vector_t hudGroups; - - mGroupQ1Locked = true; - // Iterate through all drawables on the priority build queue, - for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin(); - iter != mGroupQ1.end(); ++iter) - { - LLSpatialGroup* group = *iter; - - // If the group contains HUD objects, save the group - if (group->isHUDGroup()) - { - hudGroups.push_back(group); - } - // Else, no HUD objects so clear the build state - else - { - group->clearState(LLSpatialGroup::IN_BUILD_Q1); - } - } + LLSpatialGroup::sg_vector_t hudGroups; - // Clear the group - mGroupQ1.clear(); - - // Copy the saved HUD groups back in - mGroupQ1.assign(hudGroups.begin(), hudGroups.end()); - mGroupQ1Locked = false; + mGroupQ1Locked = true; + // Iterate through all drawables on the priority build queue, + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin(); + iter != mGroupQ1.end(); ++iter) + { + LLSpatialGroup* group = *iter; + + // If the group contains HUD objects, save the group + if (group->isHUDGroup()) + { + hudGroups.push_back(group); + } + // Else, no HUD objects so clear the build state + else + { + group->clearState(LLSpatialGroup::IN_BUILD_Q1); + } + } - // Clear the HUD groups - hudGroups.clear(); + // Clear the group + mGroupQ1.clear(); - mGroupQ2Locked = true; - for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); - iter != mGroupQ2.end(); ++iter) - { - LLSpatialGroup* group = *iter; + // Copy the saved HUD groups back in + mGroupQ1.assign(hudGroups.begin(), hudGroups.end()); + mGroupQ1Locked = false; - // If the group contains HUD objects, save the group - if (group->isHUDGroup()) - { - hudGroups.push_back(group); - } - // Else, no HUD objects so clear the build state - else - { - group->clearState(LLSpatialGroup::IN_BUILD_Q2); - } - } - // Clear the group - mGroupQ2.clear(); + // Clear the HUD groups + hudGroups.clear(); - // Copy the saved HUD groups back in - mGroupQ2.assign(hudGroups.begin(), hudGroups.end()); - mGroupQ2Locked = false; + mGroupQ2Locked = true; + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); + iter != mGroupQ2.end(); ++iter) + { + LLSpatialGroup* group = *iter; + + // If the group contains HUD objects, save the group + if (group->isHUDGroup()) + { + hudGroups.push_back(group); + } + // Else, no HUD objects so clear the build state + else + { + group->clearState(LLSpatialGroup::IN_BUILD_Q2); + } + } + // Clear the group + mGroupQ2.clear(); + + // Copy the saved HUD groups back in + mGroupQ2.assign(hudGroups.begin(), hudGroups.end()); + mGroupQ2Locked = false; } void LLPipeline::clearRebuildDrawables() { - // Clear all drawables on the priority build queue, - for (LLDrawable::drawable_list_t::iterator iter = mBuildQ1.begin(); - iter != mBuildQ1.end(); ++iter) - { - LLDrawable* drawablep = *iter; - if (drawablep && !drawablep->isDead()) - { - drawablep->clearState(LLDrawable::IN_REBUILD_Q2); - drawablep->clearState(LLDrawable::IN_REBUILD_Q1); - } - } - mBuildQ1.clear(); + // Clear all drawables on the priority build queue, + for (LLDrawable::drawable_list_t::iterator iter = mBuildQ1.begin(); + iter != mBuildQ1.end(); ++iter) + { + LLDrawable* drawablep = *iter; + if (drawablep && !drawablep->isDead()) + { + drawablep->clearState(LLDrawable::IN_REBUILD_Q2); + drawablep->clearState(LLDrawable::IN_REBUILD_Q1); + } + } + mBuildQ1.clear(); - // clear drawables on the non-priority build queue - for (LLDrawable::drawable_list_t::iterator iter = mBuildQ2.begin(); - iter != mBuildQ2.end(); ++iter) - { - LLDrawable* drawablep = *iter; - if (!drawablep->isDead()) - { - drawablep->clearState(LLDrawable::IN_REBUILD_Q2); - } - } - mBuildQ2.clear(); - - //clear all moving bridges - for (LLDrawable::drawable_vector_t::iterator iter = mMovedBridge.begin(); - iter != mMovedBridge.end(); ++iter) - { - LLDrawable *drawablep = *iter; - drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD); - } - mMovedBridge.clear(); + // clear drawables on the non-priority build queue + for (LLDrawable::drawable_list_t::iterator iter = mBuildQ2.begin(); + iter != mBuildQ2.end(); ++iter) + { + LLDrawable* drawablep = *iter; + if (!drawablep->isDead()) + { + drawablep->clearState(LLDrawable::IN_REBUILD_Q2); + } + } + mBuildQ2.clear(); + + //clear all moving bridges + for (LLDrawable::drawable_vector_t::iterator iter = mMovedBridge.begin(); + iter != mMovedBridge.end(); ++iter) + { + LLDrawable *drawablep = *iter; + drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD); + } + mMovedBridge.clear(); - //clear all moving drawables - for (LLDrawable::drawable_vector_t::iterator iter = mMovedList.begin(); - iter != mMovedList.end(); ++iter) - { - LLDrawable *drawablep = *iter; - drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD); - } - mMovedList.clear(); + //clear all moving drawables + for (LLDrawable::drawable_vector_t::iterator iter = mMovedList.begin(); + iter != mMovedList.end(); ++iter) + { + LLDrawable *drawablep = *iter; + drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD); + } + mMovedList.clear(); } void LLPipeline::rebuildPriorityGroups() { - LL_RECORD_BLOCK_TIME(FTM_REBUILD_PRIORITY_GROUPS); - LLTimer update_timer; - assertInitialized(); + LL_RECORD_BLOCK_TIME(FTM_REBUILD_PRIORITY_GROUPS); + LLTimer update_timer; + assertInitialized(); - gMeshRepo.notifyLoadedMeshes(); + gMeshRepo.notifyLoadedMeshes(); - mGroupQ1Locked = true; - // Iterate through all drawables on the priority build queue, - for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin(); - iter != mGroupQ1.end(); ++iter) - { - LLSpatialGroup* group = *iter; - group->rebuildGeom(); - group->clearState(LLSpatialGroup::IN_BUILD_Q1); - } + mGroupQ1Locked = true; + // Iterate through all drawables on the priority build queue, + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin(); + iter != mGroupQ1.end(); ++iter) + { + LLSpatialGroup* group = *iter; + group->rebuildGeom(); + group->clearState(LLSpatialGroup::IN_BUILD_Q1); + } - mGroupSaveQ1 = mGroupQ1; - mGroupQ1.clear(); - mGroupQ1Locked = false; + mGroupSaveQ1 = mGroupQ1; + mGroupQ1.clear(); + mGroupQ1Locked = false; } @@ -2971,254 +2901,254 @@ static LLTrace::BlockTimerStatHandle FTM_REBUILD_GROUPS("Rebuild Groups"); void LLPipeline::rebuildGroups() { - if (mGroupQ2.empty()) - { - return; - } - - LL_RECORD_BLOCK_TIME(FTM_REBUILD_GROUPS); - mGroupQ2Locked = true; - // Iterate through some drawables on the non-priority build queue - S32 size = (S32) mGroupQ2.size(); - S32 min_count = llclamp((S32) ((F32) (size * size)/4096*0.25f), 1, size); - - S32 count = 0; - - std::sort(mGroupQ2.begin(), mGroupQ2.end(), LLSpatialGroup::CompareUpdateUrgency()); - - LLSpatialGroup::sg_vector_t::iterator iter; - LLSpatialGroup::sg_vector_t::iterator last_iter = mGroupQ2.begin(); + if (mGroupQ2.empty()) + { + return; + } - for (iter = mGroupQ2.begin(); - iter != mGroupQ2.end() && count <= min_count; ++iter) - { - LLSpatialGroup* group = *iter; - last_iter = iter; + LL_RECORD_BLOCK_TIME(FTM_REBUILD_GROUPS); + mGroupQ2Locked = true; + // Iterate through some drawables on the non-priority build queue + S32 size = (S32) mGroupQ2.size(); + S32 min_count = llclamp((S32) ((F32) (size * size)/4096*0.25f), 1, size); + + S32 count = 0; + + std::sort(mGroupQ2.begin(), mGroupQ2.end(), LLSpatialGroup::CompareUpdateUrgency()); + + LLSpatialGroup::sg_vector_t::iterator iter; + LLSpatialGroup::sg_vector_t::iterator last_iter = mGroupQ2.begin(); + + for (iter = mGroupQ2.begin(); + iter != mGroupQ2.end() && count <= min_count; ++iter) + { + LLSpatialGroup* group = *iter; + last_iter = iter; - if (!group->isDead()) - { - group->rebuildGeom(); - - if (group->getSpatialPartition()->mRenderByGroup) - { - count++; - } - } + if (!group->isDead()) + { + group->rebuildGeom(); + + if (group->getSpatialPartition()->mRenderByGroup) + { + count++; + } + } - group->clearState(LLSpatialGroup::IN_BUILD_Q2); - } + group->clearState(LLSpatialGroup::IN_BUILD_Q2); + } - mGroupQ2.erase(mGroupQ2.begin(), ++last_iter); + mGroupQ2.erase(mGroupQ2.begin(), ++last_iter); - mGroupQ2Locked = false; + mGroupQ2Locked = false; - updateMovedList(mMovedBridge); + updateMovedList(mMovedBridge); } void LLPipeline::updateGeom(F32 max_dtime) { - LLTimer update_timer; - LLPointer<LLDrawable> drawablep; - - LL_RECORD_BLOCK_TIME(FTM_GEO_UPDATE); - - assertInitialized(); + LLTimer update_timer; + LLPointer<LLDrawable> drawablep; - // notify various object types to reset internal cost metrics, etc. - // for now, only LLVOVolume does this to throttle LOD changes - LLVOVolume::preUpdateGeom(); + LL_RECORD_BLOCK_TIME(FTM_GEO_UPDATE); - // Iterate through all drawables on the priority build queue, - for (LLDrawable::drawable_list_t::iterator iter = mBuildQ1.begin(); - iter != mBuildQ1.end();) - { - LLDrawable::drawable_list_t::iterator curiter = iter++; - LLDrawable* drawablep = *curiter; - if (drawablep && !drawablep->isDead()) - { - if (drawablep->isState(LLDrawable::IN_REBUILD_Q2)) - { - drawablep->clearState(LLDrawable::IN_REBUILD_Q2); - LLDrawable::drawable_list_t::iterator find = std::find(mBuildQ2.begin(), mBuildQ2.end(), drawablep); - if (find != mBuildQ2.end()) - { - mBuildQ2.erase(find); - } - } + assertInitialized(); - if (drawablep->isUnload()) - { - drawablep->unload(); - drawablep->clearState(LLDrawable::FOR_UNLOAD); - } + // notify various object types to reset internal cost metrics, etc. + // for now, only LLVOVolume does this to throttle LOD changes + LLVOVolume::preUpdateGeom(); - if (updateDrawableGeom(drawablep, TRUE)) - { - drawablep->clearState(LLDrawable::IN_REBUILD_Q1); - mBuildQ1.erase(curiter); - } - } - else - { - mBuildQ1.erase(curiter); - } - } - - // Iterate through some drawables on the non-priority build queue - S32 min_count = 16; - S32 size = (S32) mBuildQ2.size(); - if (size > 1024) - { - min_count = llclamp((S32) (size * (F32) size/4096), 16, size); - } - - S32 count = 0; - - max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, F32SecondsImplicit(max_dtime)); - LLSpatialGroup* last_group = NULL; - LLSpatialBridge* last_bridge = NULL; - - for (LLDrawable::drawable_list_t::iterator iter = mBuildQ2.begin(); - iter != mBuildQ2.end(); ) - { - LLDrawable::drawable_list_t::iterator curiter = iter++; - LLDrawable* drawablep = *curiter; - - LLSpatialBridge* bridge = drawablep->isRoot() ? drawablep->getSpatialBridge() : - drawablep->getParent()->getSpatialBridge(); - - if (drawablep->getSpatialGroup() != last_group && - (!last_bridge || bridge != last_bridge) && - (update_timer.getElapsedTimeF32() >= max_dtime) && count > min_count) - { - break; - } - - //make sure updates don't stop in the middle of a spatial group - //to avoid thrashing (objects are enqueued by group) - last_group = drawablep->getSpatialGroup(); - last_bridge = bridge; - - bool update_complete = true; - if (!drawablep->isDead()) - { - update_complete = updateDrawableGeom(drawablep, FALSE); - count++; - } - if (update_complete) - { - drawablep->clearState(LLDrawable::IN_REBUILD_Q2); - mBuildQ2.erase(curiter); - } - } - - updateMovedList(mMovedBridge); + // Iterate through all drawables on the priority build queue, + for (LLDrawable::drawable_list_t::iterator iter = mBuildQ1.begin(); + iter != mBuildQ1.end();) + { + LLDrawable::drawable_list_t::iterator curiter = iter++; + LLDrawable* drawablep = *curiter; + if (drawablep && !drawablep->isDead()) + { + if (drawablep->isState(LLDrawable::IN_REBUILD_Q2)) + { + drawablep->clearState(LLDrawable::IN_REBUILD_Q2); + LLDrawable::drawable_list_t::iterator find = std::find(mBuildQ2.begin(), mBuildQ2.end(), drawablep); + if (find != mBuildQ2.end()) + { + mBuildQ2.erase(find); + } + } + + if (drawablep->isUnload()) + { + drawablep->unload(); + drawablep->clearState(LLDrawable::FOR_UNLOAD); + } + + if (updateDrawableGeom(drawablep, TRUE)) + { + drawablep->clearState(LLDrawable::IN_REBUILD_Q1); + mBuildQ1.erase(curiter); + } + } + else + { + mBuildQ1.erase(curiter); + } + } + + // Iterate through some drawables on the non-priority build queue + S32 min_count = 16; + S32 size = (S32) mBuildQ2.size(); + if (size > 1024) + { + min_count = llclamp((S32) (size * (F32) size/4096), 16, size); + } + + S32 count = 0; + + max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, F32SecondsImplicit(max_dtime)); + LLSpatialGroup* last_group = NULL; + LLSpatialBridge* last_bridge = NULL; + + for (LLDrawable::drawable_list_t::iterator iter = mBuildQ2.begin(); + iter != mBuildQ2.end(); ) + { + LLDrawable::drawable_list_t::iterator curiter = iter++; + LLDrawable* drawablep = *curiter; + + LLSpatialBridge* bridge = drawablep->isRoot() ? drawablep->getSpatialBridge() : + drawablep->getParent()->getSpatialBridge(); + + if (drawablep->getSpatialGroup() != last_group && + (!last_bridge || bridge != last_bridge) && + (update_timer.getElapsedTimeF32() >= max_dtime) && count > min_count) + { + break; + } + + //make sure updates don't stop in the middle of a spatial group + //to avoid thrashing (objects are enqueued by group) + last_group = drawablep->getSpatialGroup(); + last_bridge = bridge; + + bool update_complete = true; + if (!drawablep->isDead()) + { + update_complete = updateDrawableGeom(drawablep, FALSE); + count++; + } + if (update_complete) + { + drawablep->clearState(LLDrawable::IN_REBUILD_Q2); + mBuildQ2.erase(curiter); + } + } + + updateMovedList(mMovedBridge); } void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) { - if(drawablep && !drawablep->isDead()) - { - if (drawablep->isSpatialBridge()) - { - const LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable; - llassert(root); // trying to catch a bad assumption - - if (root && // // this test may not be needed, see above - root->getVObj()->isAttachment()) - { - LLDrawable* rootparent = root->getParent(); - if (rootparent) // this IS sometimes NULL - { - LLViewerObject *vobj = rootparent->getVObj(); - llassert(vobj); // trying to catch a bad assumption - if (vobj) // this test may not be needed, see above - { - LLVOAvatar* av = vobj->asAvatar(); - if (av && (av->isImpostor() - || av->isInMuteList() - || (LLVOAvatar::AV_DO_NOT_RENDER == av->getVisualMuteSettings() && !av->needsImpostorUpdate()) )) - { - return; - } - } - } - } - sCull->pushBridge((LLSpatialBridge*) drawablep); - } - else - { - - sCull->pushDrawable(drawablep); - } - - drawablep->setVisible(camera); - } + if(drawablep && !drawablep->isDead()) + { + if (drawablep->isSpatialBridge()) + { + const LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable; + llassert(root); // trying to catch a bad assumption + + if (root && // // this test may not be needed, see above + root->getVObj()->isAttachment()) + { + LLDrawable* rootparent = root->getParent(); + if (rootparent) // this IS sometimes NULL + { + LLViewerObject *vobj = rootparent->getVObj(); + llassert(vobj); // trying to catch a bad assumption + if (vobj) // this test may not be needed, see above + { + LLVOAvatar* av = vobj->asAvatar(); + if (av && (av->isImpostor() + || av->isInMuteList() + || (LLVOAvatar::AV_DO_NOT_RENDER == av->getVisualMuteSettings() && !av->needsImpostorUpdate()) )) + { + return; + } + } + } + } + sCull->pushBridge((LLSpatialBridge*) drawablep); + } + else + { + + sCull->pushDrawable(drawablep); + } + + drawablep->setVisible(camera); + } } void LLPipeline::markMoved(LLDrawable *drawablep, bool damped_motion) { - if (!drawablep) - { - //LL_ERRS() << "Sending null drawable to moved list!" << LL_ENDL; - return; - } - - if (drawablep->isDead()) - { - LL_WARNS() << "Marking NULL or dead drawable moved!" << LL_ENDL; - return; - } - - if (drawablep->getParent()) - { - //ensure that parent drawables are moved first - markMoved(drawablep->getParent(), damped_motion); - } + if (!drawablep) + { + //LL_ERRS() << "Sending null drawable to moved list!" << LL_ENDL; + return; + } + + if (drawablep->isDead()) + { + LL_WARNS() << "Marking NULL or dead drawable moved!" << LL_ENDL; + return; + } + + if (drawablep->getParent()) + { + //ensure that parent drawables are moved first + markMoved(drawablep->getParent(), damped_motion); + } - assertInitialized(); + assertInitialized(); - if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) - { - if (drawablep->isSpatialBridge()) - { - mMovedBridge.push_back(drawablep); - } - else - { - mMovedList.push_back(drawablep); - } - drawablep->setState(LLDrawable::ON_MOVE_LIST); - } - if (! damped_motion) - { - drawablep->setState(LLDrawable::MOVE_UNDAMPED); // UNDAMPED trumps DAMPED - } - else if (drawablep->isState(LLDrawable::MOVE_UNDAMPED)) - { - drawablep->clearState(LLDrawable::MOVE_UNDAMPED); - } + if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) + { + if (drawablep->isSpatialBridge()) + { + mMovedBridge.push_back(drawablep); + } + else + { + mMovedList.push_back(drawablep); + } + drawablep->setState(LLDrawable::ON_MOVE_LIST); + } + if (! damped_motion) + { + drawablep->setState(LLDrawable::MOVE_UNDAMPED); // UNDAMPED trumps DAMPED + } + else if (drawablep->isState(LLDrawable::MOVE_UNDAMPED)) + { + drawablep->clearState(LLDrawable::MOVE_UNDAMPED); + } } void LLPipeline::markShift(LLDrawable *drawablep) { - if (!drawablep || drawablep->isDead()) - { - return; - } + if (!drawablep || drawablep->isDead()) + { + return; + } - assertInitialized(); + assertInitialized(); - if (!drawablep->isState(LLDrawable::ON_SHIFT_LIST)) - { - drawablep->getVObj()->setChanged(LLXform::SHIFTED | LLXform::SILHOUETTE); - if (drawablep->getParent()) - { - markShift(drawablep->getParent()); - } - mShiftList.push_back(drawablep); - drawablep->setState(LLDrawable::ON_SHIFT_LIST); - } + if (!drawablep->isState(LLDrawable::ON_SHIFT_LIST)) + { + drawablep->getVObj()->setChanged(LLXform::SHIFTED | LLXform::SILHOUETTE); + if (drawablep->getParent()) + { + markShift(drawablep->getParent()); + } + mShiftList.push_back(drawablep); + drawablep->setState(LLDrawable::ON_SHIFT_LIST); + } } static LLTrace::BlockTimerStatHandle FTM_SHIFT_DRAWABLE("Shift Drawable"); @@ -3227,150 +3157,150 @@ static LLTrace::BlockTimerStatHandle FTM_SHIFT_HUD("Shift HUD"); void LLPipeline::shiftObjects(const LLVector3 &offset) { - assertInitialized(); + assertInitialized(); - glClear(GL_DEPTH_BUFFER_BIT); - gDepthDirty = true; - - LLVector4a offseta; - offseta.load3(offset.mV); + glClear(GL_DEPTH_BUFFER_BIT); + gDepthDirty = true; + + LLVector4a offseta; + offseta.load3(offset.mV); - { - LL_RECORD_BLOCK_TIME(FTM_SHIFT_DRAWABLE); - - for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); - iter != mShiftList.end(); iter++) - { - LLDrawable *drawablep = *iter; - if (drawablep->isDead()) - { - continue; - } - drawablep->shiftPos(offseta); - drawablep->clearState(LLDrawable::ON_SHIFT_LIST); - } - mShiftList.resize(0); - } + { + LL_RECORD_BLOCK_TIME(FTM_SHIFT_DRAWABLE); + + for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); + iter != mShiftList.end(); iter++) + { + LLDrawable *drawablep = *iter; + if (drawablep->isDead()) + { + continue; + } + drawablep->shiftPos(offseta); + drawablep->clearState(LLDrawable::ON_SHIFT_LIST); + } + mShiftList.resize(0); + } - - { - LL_RECORD_BLOCK_TIME(FTM_SHIFT_OCTREE); - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) - { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) - { - part->shift(offseta); - } - } - } - } + + { + LL_RECORD_BLOCK_TIME(FTM_SHIFT_OCTREE); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + part->shift(offseta); + } + } + } + } - { - LL_RECORD_BLOCK_TIME(FTM_SHIFT_HUD); - LLHUDText::shiftAll(offset); - LLHUDNameTag::shiftAll(offset); - } - display_update_camera(); + { + LL_RECORD_BLOCK_TIME(FTM_SHIFT_HUD); + LLHUDText::shiftAll(offset); + LLHUDNameTag::shiftAll(offset); + } + display_update_camera(); } void LLPipeline::markTextured(LLDrawable *drawablep) { - if (drawablep && !drawablep->isDead() && assertInitialized()) - { - mRetexturedList.insert(drawablep); - } + if (drawablep && !drawablep->isDead() && assertInitialized()) + { + mRetexturedList.insert(drawablep); + } } void LLPipeline::markGLRebuild(LLGLUpdate* glu) { - if (glu && !glu->mInQ) - { - LLGLUpdate::sGLQ.push_back(glu); - glu->mInQ = TRUE; - } + if (glu && !glu->mInQ) + { + LLGLUpdate::sGLQ.push_back(glu); + glu->mInQ = TRUE; + } } void LLPipeline::markPartitionMove(LLDrawable* drawable) { - if (!drawable->isState(LLDrawable::PARTITION_MOVE) && - !drawable->getPositionGroup().equals3(LLVector4a::getZero())) - { - drawable->setState(LLDrawable::PARTITION_MOVE); - mPartitionQ.push_back(drawable); - } + if (!drawable->isState(LLDrawable::PARTITION_MOVE) && + !drawable->getPositionGroup().equals3(LLVector4a::getZero())) + { + drawable->setState(LLDrawable::PARTITION_MOVE); + mPartitionQ.push_back(drawable); + } } static LLTrace::BlockTimerStatHandle FTM_PROCESS_PARTITIONQ("PartitionQ"); void LLPipeline::processPartitionQ() { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_PARTITIONQ); - for (LLDrawable::drawable_list_t::iterator iter = mPartitionQ.begin(); iter != mPartitionQ.end(); ++iter) - { - LLDrawable* drawable = *iter; - if (!drawable->isDead()) - { - drawable->updateBinRadius(); - drawable->movePartition(); - } - drawable->clearState(LLDrawable::PARTITION_MOVE); - } + LL_RECORD_BLOCK_TIME(FTM_PROCESS_PARTITIONQ); + for (LLDrawable::drawable_list_t::iterator iter = mPartitionQ.begin(); iter != mPartitionQ.end(); ++iter) + { + LLDrawable* drawable = *iter; + if (!drawable->isDead()) + { + drawable->updateBinRadius(); + drawable->movePartition(); + } + drawable->clearState(LLDrawable::PARTITION_MOVE); + } - mPartitionQ.clear(); + mPartitionQ.clear(); } void LLPipeline::markMeshDirty(LLSpatialGroup* group) { - mMeshDirtyGroup.push_back(group); + mMeshDirtyGroup.push_back(group); } void LLPipeline::markRebuild(LLSpatialGroup* group, bool priority) { - if (group && !group->isDead() && group->getSpatialPartition()) - { - if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD) - { - priority = true; - } - - if (priority) - { - if (!group->hasState(LLSpatialGroup::IN_BUILD_Q1)) - { - llassert_always(!mGroupQ1Locked); - - mGroupQ1.push_back(group); - group->setState(LLSpatialGroup::IN_BUILD_Q1); - - if (group->hasState(LLSpatialGroup::IN_BUILD_Q2)) - { - LLSpatialGroup::sg_vector_t::iterator iter = std::find(mGroupQ2.begin(), mGroupQ2.end(), group); - if (iter != mGroupQ2.end()) - { - mGroupQ2.erase(iter); - } - group->clearState(LLSpatialGroup::IN_BUILD_Q2); - } - } - } - else if (!group->hasState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1)) - { - llassert_always(!mGroupQ2Locked); - mGroupQ2.push_back(group); - group->setState(LLSpatialGroup::IN_BUILD_Q2); - - } - } + if (group && !group->isDead() && group->getSpatialPartition()) + { + if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD) + { + priority = true; + } + + if (priority) + { + if (!group->hasState(LLSpatialGroup::IN_BUILD_Q1)) + { + llassert_always(!mGroupQ1Locked); + + mGroupQ1.push_back(group); + group->setState(LLSpatialGroup::IN_BUILD_Q1); + + if (group->hasState(LLSpatialGroup::IN_BUILD_Q2)) + { + LLSpatialGroup::sg_vector_t::iterator iter = std::find(mGroupQ2.begin(), mGroupQ2.end(), group); + if (iter != mGroupQ2.end()) + { + mGroupQ2.erase(iter); + } + group->clearState(LLSpatialGroup::IN_BUILD_Q2); + } + } + } + else if (!group->hasState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1)) + { + llassert_always(!mGroupQ2Locked); + mGroupQ2.push_back(group); + group->setState(LLSpatialGroup::IN_BUILD_Q2); + + } + } } void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag, bool priority) { - if (drawablep && !drawablep->isDead() && assertInitialized()) - { + if (drawablep && !drawablep->isDead() && assertInitialized()) + { if (debugLoggingEnabled("AnimatedObjectsLinkset")) { LLVOVolume *vol_obj = drawablep->getVOVolume(); @@ -3383,968 +3313,975 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f } } - if (!drawablep->isState(LLDrawable::BUILT)) - { - priority = true; - } - if (priority) - { - if (!drawablep->isState(LLDrawable::IN_REBUILD_Q1)) - { - mBuildQ1.push_back(drawablep); - drawablep->setState(LLDrawable::IN_REBUILD_Q1); // mark drawable as being in priority queue - } - } - else if (!drawablep->isState(LLDrawable::IN_REBUILD_Q2)) - { - mBuildQ2.push_back(drawablep); - drawablep->setState(LLDrawable::IN_REBUILD_Q2); // need flag here because it is just a list - } - if (flag & (LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION)) - { - drawablep->getVObj()->setChanged(LLXform::SILHOUETTE); - } - drawablep->setState(flag); - } + if (!drawablep->isState(LLDrawable::BUILT)) + { + priority = true; + } + if (priority) + { + if (!drawablep->isState(LLDrawable::IN_REBUILD_Q1)) + { + mBuildQ1.push_back(drawablep); + drawablep->setState(LLDrawable::IN_REBUILD_Q1); // mark drawable as being in priority queue + } + } + else if (!drawablep->isState(LLDrawable::IN_REBUILD_Q2)) + { + mBuildQ2.push_back(drawablep); + drawablep->setState(LLDrawable::IN_REBUILD_Q2); // need flag here because it is just a list + } + if (flag & (LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION)) + { + drawablep->getVObj()->setChanged(LLXform::SILHOUETTE); + } + drawablep->setState(flag); + } } static LLTrace::BlockTimerStatHandle FTM_RESET_DRAWORDER("Reset Draw Order"); void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) { - if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR, - LLPipeline::RENDER_TYPE_GROUND, - LLPipeline::RENDER_TYPE_TERRAIN, - LLPipeline::RENDER_TYPE_TREE, - LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_VOIDWATER, - LLPipeline::RENDER_TYPE_WATER, - LLPipeline::END_RENDER_TYPES)) - { - //clear faces from face pools - LL_RECORD_BLOCK_TIME(FTM_RESET_DRAWORDER); - gPipeline.resetDrawOrders(); - } - - LL_RECORD_BLOCK_TIME(FTM_STATESORT); - - //LLVertexBuffer::unbind(); - - grabReferences(result); - for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - group->checkOcclusion(); - if (sUseOcclusion > 1 && group->isOcclusionState(LLSpatialGroup::OCCLUDED)) - { - markOccluder(group); - } - else - { - group->setVisible(); - for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) - { - markVisible((LLDrawable*)(*i)->getDrawable(), camera); - } - - if (!sDelayVBUpdate) - { //rebuild mesh as soon as we know it's visible - group->rebuildMesh(); - } - } - } - - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) - { - LLSpatialGroup* last_group = NULL; - BOOL fov_changed = LLViewerCamera::getInstance()->isDefaultFOVChanged(); - for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) - { - LLCullResult::bridge_iterator cur_iter = i; - LLSpatialBridge* bridge = *cur_iter; - LLSpatialGroup* group = bridge->getSpatialGroup(); - - if (last_group == NULL) - { - last_group = group; - } - - if (!bridge->isDead() && group && !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) - { - stateSort(bridge, camera, fov_changed); - } + if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_GROUND, + LLPipeline::RENDER_TYPE_TERRAIN, + LLPipeline::RENDER_TYPE_TREE, + LLPipeline::RENDER_TYPE_SKY, + LLPipeline::RENDER_TYPE_VOIDWATER, + LLPipeline::RENDER_TYPE_WATER, + LLPipeline::END_RENDER_TYPES)) + { + //clear faces from face pools + LL_RECORD_BLOCK_TIME(FTM_RESET_DRAWORDER); + gPipeline.resetDrawOrders(); + } - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && - last_group != group && last_group->changeLOD()) - { - last_group->mLastUpdateDistance = last_group->mDistance; - } + LL_RECORD_BLOCK_TIME(FTM_STATESORT); - last_group = group; - } + //LLVertexBuffer::unbind(); - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && - last_group && last_group->changeLOD()) - { - last_group->mLastUpdateDistance = last_group->mDistance; - } - } + grabReferences(result); + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + group->checkOcclusion(); + if (sUseOcclusion > 1 && group->isOcclusionState(LLSpatialGroup::OCCLUDED)) + { + markOccluder(group); + } + else + { + group->setVisible(); + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + { + markVisible((LLDrawable*)(*i)->getDrawable(), camera); + } + + if (!sDelayVBUpdate) + { //rebuild mesh as soon as we know it's visible + group->rebuildMesh(); + } + } + } - for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) - { - LLSpatialGroup* group = *iter; - group->checkOcclusion(); - if (sUseOcclusion > 1 && group->isOcclusionState(LLSpatialGroup::OCCLUDED)) - { - markOccluder(group); - } - else - { - group->setVisible(); - stateSort(group, camera); + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + { + LLSpatialGroup* last_group = NULL; + BOOL fov_changed = LLViewerCamera::getInstance()->isDefaultFOVChanged(); + for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + { + LLCullResult::bridge_iterator cur_iter = i; + LLSpatialBridge* bridge = *cur_iter; + LLSpatialGroup* group = bridge->getSpatialGroup(); + + if (last_group == NULL) + { + last_group = group; + } + + if (!bridge->isDead() && group && !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) + { + stateSort(bridge, camera, fov_changed); + } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && + last_group != group && last_group->changeLOD()) + { + last_group->mLastUpdateDistance = last_group->mDistance; + } + + last_group = group; + } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && + last_group && last_group->changeLOD()) + { + last_group->mLastUpdateDistance = last_group->mDistance; + } + } - if (!sDelayVBUpdate) - { //rebuild mesh as soon as we know it's visible - group->rebuildMesh(); - } - } - } - - { - LL_RECORD_BLOCK_TIME(FTM_STATESORT_DRAWABLE); - for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); - iter != sCull->endVisibleList(); ++iter) - { - LLDrawable *drawablep = *iter; - if (!drawablep->isDead()) - { - stateSort(drawablep, camera); - } - } - } - - postSort(camera); + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + group->checkOcclusion(); + if (sUseOcclusion > 1 && group->isOcclusionState(LLSpatialGroup::OCCLUDED)) + { + markOccluder(group); + } + else + { + group->setVisible(); + stateSort(group, camera); + + if (!sDelayVBUpdate) + { //rebuild mesh as soon as we know it's visible + group->rebuildMesh(); + } + } + } + + { + LL_RECORD_BLOCK_TIME(FTM_STATESORT_DRAWABLE); + for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); + iter != sCull->endVisibleList(); ++iter) + { + LLDrawable *drawablep = *iter; + if (!drawablep->isDead()) + { + stateSort(drawablep, camera); + } + } + } + + postSort(camera); } void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) { - if (group->changeLOD()) - { - for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) - { - stateSort((LLDrawable*)(*i)->getDrawable(), camera); - } - - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) - { //avoid redundant stateSort calls - group->mLastUpdateDistance = group->mDistance; - } - } + if (group->changeLOD()) + { + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + { + stateSort((LLDrawable*)(*i)->getDrawable(), camera); + } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + { //avoid redundant stateSort calls + group->mLastUpdateDistance = group->mDistance; + } + } } void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed) { - if (bridge->getSpatialGroup()->changeLOD() || fov_changed) - { - bool force_update = false; - bridge->updateDistance(camera, force_update); - } + if (bridge->getSpatialGroup()->changeLOD() || fov_changed) + { + bool force_update = false; + bridge->updateDistance(camera, force_update); + } } void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) { - if (!drawablep - || drawablep->isDead() - || !hasRenderType(drawablep->getRenderType())) - { - return; - } - - if (LLSelectMgr::getInstance()->mHideSelectedObjects) - { - if (drawablep->getVObj().notNull() && - drawablep->getVObj()->isSelected()) - { - return; - } - } - - if (drawablep->isAvatar()) - { //don't draw avatars beyond render distance or if we don't have a spatial group. - if ((drawablep->getSpatialGroup() == NULL) || - (drawablep->getSpatialGroup()->mDistance > LLVOAvatar::sRenderDistance)) - { - return; - } - - LLVOAvatar* avatarp = (LLVOAvatar*) drawablep->getVObj().get(); - if (!avatarp->isVisible()) - { - return; - } - } + if (!drawablep + || drawablep->isDead() + || !hasRenderType(drawablep->getRenderType())) + { + return; + } + + if (LLSelectMgr::getInstance()->mHideSelectedObjects) + { + if (drawablep->getVObj().notNull() && + drawablep->getVObj()->isSelected()) + { + return; + } + } - assertInitialized(); + if (drawablep->isAvatar()) + { //don't draw avatars beyond render distance or if we don't have a spatial group. + if ((drawablep->getSpatialGroup() == NULL) || + (drawablep->getSpatialGroup()->mDistance > LLVOAvatar::sRenderDistance)) + { + return; + } + + LLVOAvatar* avatarp = (LLVOAvatar*) drawablep->getVObj().get(); + if (!avatarp->isVisible()) + { + return; + } + } - if (hasRenderType(drawablep->mRenderType)) - { - if (!drawablep->isState(LLDrawable::INVISIBLE|LLDrawable::FORCE_INVISIBLE)) - { - drawablep->setVisible(camera, NULL, FALSE); - } - } + assertInitialized(); - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) - { - //if (drawablep->isVisible()) isVisible() check here is redundant, if it wasn't visible, it wouldn't be here - { - if (!drawablep->isActive()) - { - bool force_update = false; - drawablep->updateDistance(camera, force_update); - } - else if (drawablep->isAvatar()) - { - bool force_update = false; - drawablep->updateDistance(camera, force_update); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility() - } - } - } + if (hasRenderType(drawablep->mRenderType)) + { + if (!drawablep->isState(LLDrawable::INVISIBLE|LLDrawable::FORCE_INVISIBLE)) + { + drawablep->setVisible(camera, NULL, FALSE); + } + } - if (!drawablep->getVOVolume()) - { - for (LLDrawable::face_list_t::iterator iter = drawablep->mFaces.begin(); - iter != drawablep->mFaces.end(); iter++) - { - LLFace* facep = *iter; + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + { + //if (drawablep->isVisible()) isVisible() check here is redundant, if it wasn't visible, it wouldn't be here + { + if (!drawablep->isActive()) + { + bool force_update = false; + drawablep->updateDistance(camera, force_update); + } + else if (drawablep->isAvatar()) + { + bool force_update = false; + drawablep->updateDistance(camera, force_update); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility() + } + } + } - if (facep->hasGeometry()) - { - if (facep->getPool()) - { - facep->getPool()->enqueue(facep); - } - else - { - break; - } - } - } - } - - mNumVisibleFaces += drawablep->getNumFaces(); + if (!drawablep->getVOVolume()) + { + for (LLDrawable::face_list_t::iterator iter = drawablep->mFaces.begin(); + iter != drawablep->mFaces.end(); iter++) + { + LLFace* facep = *iter; + + if (facep->hasGeometry()) + { + if (facep->getPool()) + { + facep->getPool()->enqueue(facep); + } + else + { + break; + } + } + } + } + + mNumVisibleFaces += drawablep->getNumFaces(); } void forAllDrawables(LLCullResult::sg_iterator begin, - LLCullResult::sg_iterator end, - void (*func)(LLDrawable*)) + LLCullResult::sg_iterator end, + void (*func)(LLDrawable*)) { - for (LLCullResult::sg_iterator i = begin; i != end; ++i) - { - for (LLSpatialGroup::element_iter j = (*i)->getDataBegin(); j != (*i)->getDataEnd(); ++j) - { - if((*j)->hasDrawable()) - { - func((LLDrawable*)(*j)->getDrawable()); - } - } - } + for (LLCullResult::sg_iterator i = begin; i != end; ++i) + { + for (LLSpatialGroup::element_iter j = (*i)->getDataBegin(); j != (*i)->getDataEnd(); ++j) + { + if((*j)->hasDrawable()) + { + func((LLDrawable*)(*j)->getDrawable()); + } + } + } } void LLPipeline::forAllVisibleDrawables(void (*func)(LLDrawable*)) { - forAllDrawables(sCull->beginDrawableGroups(), sCull->endDrawableGroups(), func); - forAllDrawables(sCull->beginVisibleGroups(), sCull->endVisibleGroups(), func); + forAllDrawables(sCull->beginDrawableGroups(), sCull->endDrawableGroups(), func); + forAllDrawables(sCull->beginVisibleGroups(), sCull->endVisibleGroups(), func); } //function for creating scripted beacons void renderScriptedBeacons(LLDrawable* drawablep) { - LLViewerObject *vobj = drawablep->getVObj(); - if (vobj - && !vobj->isAvatar() - && !vobj->getParent() - && vobj->flagScripted()) - { - if (gPipeline.sRenderBeacons) - { - gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth); - } - - if (gPipeline.sRenderHighlight) - { - S32 face_id; - S32 count = drawablep->getNumFaces(); - for (face_id = 0; face_id < count; face_id++) - { - LLFace * facep = drawablep->getFace(face_id); - if (facep) - { - gPipeline.mHighlightFaces.push_back(facep); - } - } - } - } + LLViewerObject *vobj = drawablep->getVObj(); + if (vobj + && !vobj->isAvatar() + && !vobj->getParent() + && vobj->flagScripted()) + { + if (gPipeline.sRenderBeacons) + { + gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth); + } + + if (gPipeline.sRenderHighlight) + { + S32 face_id; + S32 count = drawablep->getNumFaces(); + for (face_id = 0; face_id < count; face_id++) + { + LLFace * facep = drawablep->getFace(face_id); + if (facep) + { + gPipeline.mHighlightFaces.push_back(facep); + } + } + } + } } void renderScriptedTouchBeacons(LLDrawable* drawablep) { - LLViewerObject *vobj = drawablep->getVObj(); - if (vobj - && !vobj->isAvatar() - && !vobj->getParent() - && vobj->flagScripted() - && vobj->flagHandleTouch()) - { - if (gPipeline.sRenderBeacons) - { - gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth); - } - - if (gPipeline.sRenderHighlight) - { - S32 face_id; - S32 count = drawablep->getNumFaces(); - for (face_id = 0; face_id < count; face_id++) - { - LLFace * facep = drawablep->getFace(face_id); - if (facep) - { - gPipeline.mHighlightFaces.push_back(facep); - } - } - } + LLViewerObject *vobj = drawablep->getVObj(); + if (vobj + && !vobj->isAvatar() + && !vobj->getParent() + && vobj->flagScripted() + && vobj->flagHandleTouch()) + { + if (gPipeline.sRenderBeacons) + { + gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth); + } + + if (gPipeline.sRenderHighlight) + { + S32 face_id; + S32 count = drawablep->getNumFaces(); + for (face_id = 0; face_id < count; face_id++) + { + LLFace * facep = drawablep->getFace(face_id); + if (facep) + { + gPipeline.mHighlightFaces.push_back(facep); + } + } + } } } void renderPhysicalBeacons(LLDrawable* drawablep) { - LLViewerObject *vobj = drawablep->getVObj(); - if (vobj - && !vobj->isAvatar() - //&& !vobj->getParent() - && vobj->flagUsePhysics()) - { - if (gPipeline.sRenderBeacons) - { - gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(0.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth); - } - - if (gPipeline.sRenderHighlight) - { - S32 face_id; - S32 count = drawablep->getNumFaces(); - for (face_id = 0; face_id < count; face_id++) - { - LLFace * facep = drawablep->getFace(face_id); - if (facep) - { - gPipeline.mHighlightFaces.push_back(facep); - } - } - } + LLViewerObject *vobj = drawablep->getVObj(); + if (vobj + && !vobj->isAvatar() + //&& !vobj->getParent() + && vobj->flagUsePhysics()) + { + if (gPipeline.sRenderBeacons) + { + gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(0.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth); + } + + if (gPipeline.sRenderHighlight) + { + S32 face_id; + S32 count = drawablep->getNumFaces(); + for (face_id = 0; face_id < count; face_id++) + { + LLFace * facep = drawablep->getFace(face_id); + if (facep) + { + gPipeline.mHighlightFaces.push_back(facep); + } + } + } } } void renderMOAPBeacons(LLDrawable* drawablep) { - LLViewerObject *vobj = drawablep->getVObj(); + LLViewerObject *vobj = drawablep->getVObj(); - if(!vobj || vobj->isAvatar()) - return; + if(!vobj || vobj->isAvatar()) + return; - bool beacon=false; - U8 tecount=vobj->getNumTEs(); - for(int x=0;x<tecount;x++) - { - if(vobj->getTE(x)->hasMedia()) - { - beacon=true; - break; - } - } - if(beacon) - { - if (gPipeline.sRenderBeacons) - { - gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 1.f, 1.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth); - } - - if (gPipeline.sRenderHighlight) - { - S32 face_id; - S32 count = drawablep->getNumFaces(); - for (face_id = 0; face_id < count; face_id++) - { - LLFace * facep = drawablep->getFace(face_id); - if (facep) - { - gPipeline.mHighlightFaces.push_back(facep); - } - } - } + bool beacon=false; + U8 tecount=vobj->getNumTEs(); + for(int x=0;x<tecount;x++) + { + if(vobj->getTE(x)->hasMedia()) + { + beacon=true; + break; + } + } + if(beacon) + { + if (gPipeline.sRenderBeacons) + { + gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 1.f, 1.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth); + } + + if (gPipeline.sRenderHighlight) + { + S32 face_id; + S32 count = drawablep->getNumFaces(); + for (face_id = 0; face_id < count; face_id++) + { + LLFace * facep = drawablep->getFace(face_id); + if (facep) + { + gPipeline.mHighlightFaces.push_back(facep); + } + } + } } } void renderParticleBeacons(LLDrawable* drawablep) { - // Look for attachments, objects, etc. - LLViewerObject *vobj = drawablep->getVObj(); - if (vobj - && vobj->isParticleSource()) - { - if (gPipeline.sRenderBeacons) - { - LLColor4 light_blue(0.5f, 0.5f, 1.f, 0.5f); - gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", light_blue, LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth); - } - - if (gPipeline.sRenderHighlight) - { - S32 face_id; - S32 count = drawablep->getNumFaces(); - for (face_id = 0; face_id < count; face_id++) - { - LLFace * facep = drawablep->getFace(face_id); - if (facep) - { - gPipeline.mHighlightFaces.push_back(facep); - } - } - } + // Look for attachments, objects, etc. + LLViewerObject *vobj = drawablep->getVObj(); + if (vobj + && vobj->isParticleSource()) + { + if (gPipeline.sRenderBeacons) + { + LLColor4 light_blue(0.5f, 0.5f, 1.f, 0.5f); + gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", light_blue, LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth); + } + + if (gPipeline.sRenderHighlight) + { + S32 face_id; + S32 count = drawablep->getNumFaces(); + for (face_id = 0; face_id < count; face_id++) + { + LLFace * facep = drawablep->getFace(face_id); + if (facep) + { + gPipeline.mHighlightFaces.push_back(facep); + } + } + } } } void renderSoundHighlights(LLDrawable* drawablep) { - // Look for attachments, objects, etc. - LLViewerObject *vobj = drawablep->getVObj(); - if (vobj && vobj->isAudioSource()) - { - if (gPipeline.sRenderHighlight) - { - S32 face_id; - S32 count = drawablep->getNumFaces(); - for (face_id = 0; face_id < count; face_id++) - { - LLFace * facep = drawablep->getFace(face_id); - if (facep) - { - gPipeline.mHighlightFaces.push_back(facep); - } - } - } + // Look for attachments, objects, etc. + LLViewerObject *vobj = drawablep->getVObj(); + if (vobj && vobj->isAudioSource()) + { + if (gPipeline.sRenderHighlight) + { + S32 face_id; + S32 count = drawablep->getNumFaces(); + for (face_id = 0; face_id < count; face_id++) + { + LLFace * facep = drawablep->getFace(face_id); + if (facep) + { + gPipeline.mHighlightFaces.push_back(facep); + } + } + } } } void LLPipeline::postSort(LLCamera& camera) { - LL_RECORD_BLOCK_TIME(FTM_STATESORT_POSTSORT); - - assertInitialized(); - - LL_PUSH_CALLSTACKS(); - //rebuild drawable geometry - for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i) - { - LLSpatialGroup* group = *i; - if (!sUseOcclusion || - !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) - { - group->rebuildGeom(); - } - } - LL_PUSH_CALLSTACKS(); - //rebuild groups - sCull->assertDrawMapsEmpty(); - - rebuildPriorityGroups(); - LL_PUSH_CALLSTACKS(); - - - //build render map - for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) - { - LLSpatialGroup* group = *i; - if ((sUseOcclusion && - group->isOcclusionState(LLSpatialGroup::OCCLUDED)) || - (RenderAutoHideSurfaceAreaLimit > 0.f && - group->mSurfaceArea > RenderAutoHideSurfaceAreaLimit*llmax(group->mObjectBoxSize, 10.f))) - { - continue; - } - - if (group->hasState(LLSpatialGroup::NEW_DRAWINFO) && group->hasState(LLSpatialGroup::GEOM_DIRTY)) - { //no way this group is going to be drawable without a rebuild - group->rebuildGeom(); - } - - for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j) - { - LLSpatialGroup::drawmap_elem_t& src_vec = j->second; - if (!hasRenderType(j->first)) - { - continue; - } - - for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k) - { - if (sMinRenderSize > 0.f) - { - LLVector4a bounds; - bounds.setSub((*k)->mExtents[1],(*k)->mExtents[0]); + LL_RECORD_BLOCK_TIME(FTM_STATESORT_POSTSORT); - if (llmax(llmax(bounds[0], bounds[1]), bounds[2]) > sMinRenderSize) - { - sCull->pushDrawInfo(j->first, *k); - } - } - else - { - sCull->pushDrawInfo(j->first, *k); - } - } - } + assertInitialized(); - if (hasRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA)) - { - LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA); - - if (alpha != group->mDrawMap.end()) - { //store alpha groups for sorting - LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge(); - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) - { - if (bridge) - { - LLCamera trans_camera = bridge->transformCamera(camera); - group->updateDistance(trans_camera); - } - else - { - group->updateDistance(camera); - } - } - - if (hasRenderType(LLDrawPool::POOL_ALPHA)) - { - sCull->pushAlphaGroup(group); - } - } - } - } - - //flush particle VB - if (LLVOPartGroup::sVB) - { - LLVOPartGroup::sVB->flush(); - } - else - { - LL_WARNS_ONCE() << "Missing particle buffer" << LL_ENDL; - } - - /*bool use_transform_feedback = gTransformPositionProgram.mProgramObject && !mMeshDirtyGroup.empty(); - - if (use_transform_feedback) - { //place a query around potential transform feedback code for synchronization - mTransformFeedbackPrimitives = 0; - - if (!mMeshDirtyQueryObject) - { - glGenQueriesARB(1, &mMeshDirtyQueryObject); - } - - - glBeginQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, mMeshDirtyQueryObject); - }*/ - - //pack vertex buffers for groups that chose to delay their updates - for (LLSpatialGroup::sg_vector_t::iterator iter = mMeshDirtyGroup.begin(); iter != mMeshDirtyGroup.end(); ++iter) - { - (*iter)->rebuildMesh(); - } + LL_PUSH_CALLSTACKS(); + //rebuild drawable geometry + for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i) + { + LLSpatialGroup* group = *i; + if (!sUseOcclusion || + !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) + { + group->rebuildGeom(); + } + } + LL_PUSH_CALLSTACKS(); + //rebuild groups + sCull->assertDrawMapsEmpty(); - /*if (use_transform_feedback) - { - glEndQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); - }*/ - - mMeshDirtyGroup.clear(); + rebuildPriorityGroups(); + LL_PUSH_CALLSTACKS(); - if (!sShadowRender) - { - std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater()); - } + + //build render map + for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) + { + LLSpatialGroup* group = *i; + if ((sUseOcclusion && + group->isOcclusionState(LLSpatialGroup::OCCLUDED)) || + (RenderAutoHideSurfaceAreaLimit > 0.f && + group->mSurfaceArea > RenderAutoHideSurfaceAreaLimit*llmax(group->mObjectBoxSize, 10.f))) + { + continue; + } + + if (group->hasState(LLSpatialGroup::NEW_DRAWINFO) && group->hasState(LLSpatialGroup::GEOM_DIRTY)) + { //no way this group is going to be drawable without a rebuild + group->rebuildGeom(); + } + + for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j) + { + LLSpatialGroup::drawmap_elem_t& src_vec = j->second; + if (!hasRenderType(j->first)) + { + continue; + } + + for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k) + { + if (sMinRenderSize > 0.f) + { + LLVector4a bounds; + bounds.setSub((*k)->mExtents[1],(*k)->mExtents[0]); + + if (llmax(llmax(bounds[0], bounds[1]), bounds[2]) > sMinRenderSize) + { + sCull->pushDrawInfo(j->first, *k); + } + } + else + { + sCull->pushDrawInfo(j->first, *k); + } + } + } + + if (hasRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA)) + { + LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA); + + if (alpha != group->mDrawMap.end()) + { //store alpha groups for sorting + LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge(); + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + { + if (bridge) + { + LLCamera trans_camera = bridge->transformCamera(camera); + group->updateDistance(trans_camera); + } + else + { + group->updateDistance(camera); + } + } + + if (hasRenderType(LLDrawPool::POOL_ALPHA)) + { + sCull->pushAlphaGroup(group); + } + } + } + } + + //flush particle VB + if (LLVOPartGroup::sVB) + { + LLVOPartGroup::sVB->flush(); + } + else + { + LL_WARNS_ONCE() << "Missing particle buffer" << LL_ENDL; + } - LL_PUSH_CALLSTACKS(); - // only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus - if (LLFloaterReg::instanceVisible("beacons") && !sShadowRender) - { - if (sRenderScriptedTouchBeacons) - { - // Only show the beacon on the root object. - forAllVisibleDrawables(renderScriptedTouchBeacons); - } - else - if (sRenderScriptedBeacons) - { - // Only show the beacon on the root object. - forAllVisibleDrawables(renderScriptedBeacons); - } + /*bool use_transform_feedback = gTransformPositionProgram.mProgramObject && !mMeshDirtyGroup.empty(); - if (sRenderPhysicalBeacons) - { - // Only show the beacon on the root object. - forAllVisibleDrawables(renderPhysicalBeacons); - } + if (use_transform_feedback) + { //place a query around potential transform feedback code for synchronization + mTransformFeedbackPrimitives = 0; - if(sRenderMOAPBeacons) - { - forAllVisibleDrawables(renderMOAPBeacons); - } + if (!mMeshDirtyQueryObject) + { + glGenQueriesARB(1, &mMeshDirtyQueryObject); + } - if (sRenderParticleBeacons) - { - forAllVisibleDrawables(renderParticleBeacons); - } + + glBeginQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, mMeshDirtyQueryObject); + }*/ - // If god mode, also show audio cues - if (sRenderSoundBeacons && gAudiop) - { - // Walk all sound sources and render out beacons for them. Note, this isn't done in the ForAllVisibleDrawables function, because some are not visible. - LLAudioEngine::source_map::iterator iter; - for (iter = gAudiop->mAllSources.begin(); iter != gAudiop->mAllSources.end(); ++iter) - { - LLAudioSource *sourcep = iter->second; + //pack vertex buffers for groups that chose to delay their updates + for (LLSpatialGroup::sg_vector_t::iterator iter = mMeshDirtyGroup.begin(); iter != mMeshDirtyGroup.end(); ++iter) + { + (*iter)->rebuildMesh(); + } - LLVector3d pos_global = sourcep->getPositionGlobal(); - LLVector3 pos = gAgent.getPosAgentFromGlobal(pos_global); - if (gPipeline.sRenderBeacons) - { - //pos += LLVector3(0.f, 0.f, 0.2f); - gObjectList.addDebugBeacon(pos, "", LLColor4(1.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), DebugBeaconLineWidth); - } - } - // now deal with highlights for all those seeable sound sources - forAllVisibleDrawables(renderSoundHighlights); - } - } - LL_PUSH_CALLSTACKS(); - // If managing your telehub, draw beacons at telehub and currently selected spawnpoint. - if (LLFloaterTelehub::renderBeacons()) - { - LLFloaterTelehub::addBeacons(); - } + /*if (use_transform_feedback) + { + glEndQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); + }*/ + + mMeshDirtyGroup.clear(); - if (!sShadowRender) - { - mSelectedFaces.clear(); + if (!sShadowRender) + { + std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater()); + } - LLPipeline::setRenderHighlightTextureChannel(gFloaterTools->getPanelFace()->getTextureChannelToEdit()); + LL_PUSH_CALLSTACKS(); + // only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus + if (LLFloaterReg::instanceVisible("beacons") && !sShadowRender) + { + if (sRenderScriptedTouchBeacons) + { + // Only show the beacon on the root object. + forAllVisibleDrawables(renderScriptedTouchBeacons); + } + else + if (sRenderScriptedBeacons) + { + // Only show the beacon on the root object. + forAllVisibleDrawables(renderScriptedBeacons); + } + + if (sRenderPhysicalBeacons) + { + // Only show the beacon on the root object. + forAllVisibleDrawables(renderPhysicalBeacons); + } + + if(sRenderMOAPBeacons) + { + forAllVisibleDrawables(renderMOAPBeacons); + } + + if (sRenderParticleBeacons) + { + forAllVisibleDrawables(renderParticleBeacons); + } + + // If god mode, also show audio cues + if (sRenderSoundBeacons && gAudiop) + { + // Walk all sound sources and render out beacons for them. Note, this isn't done in the ForAllVisibleDrawables function, because some are not visible. + LLAudioEngine::source_map::iterator iter; + for (iter = gAudiop->mAllSources.begin(); iter != gAudiop->mAllSources.end(); ++iter) + { + LLAudioSource *sourcep = iter->second; + + LLVector3d pos_global = sourcep->getPositionGlobal(); + LLVector3 pos = gAgent.getPosAgentFromGlobal(pos_global); + if (gPipeline.sRenderBeacons) + { + //pos += LLVector3(0.f, 0.f, 0.2f); + gObjectList.addDebugBeacon(pos, "", LLColor4(1.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), DebugBeaconLineWidth); + } + } + // now deal with highlights for all those seeable sound sources + forAllVisibleDrawables(renderSoundHighlights); + } + } + LL_PUSH_CALLSTACKS(); + // If managing your telehub, draw beacons at telehub and currently selected spawnpoint. + if (LLFloaterTelehub::renderBeacons()) + { + LLFloaterTelehub::addBeacons(); + } - // Draw face highlights for selected faces. - if (LLSelectMgr::getInstance()->getTEMode()) - { - struct f : public LLSelectedTEFunctor - { - virtual bool apply(LLViewerObject* object, S32 te) - { - if (object->mDrawable) - { - LLFace * facep = object->mDrawable->getFace(te); - if (facep) - { - gPipeline.mSelectedFaces.push_back(facep); - } - } - return true; - } - } func; - LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func); - } - } + if (!sShadowRender) + { + mSelectedFaces.clear(); + + LLPipeline::setRenderHighlightTextureChannel(gFloaterTools->getPanelFace()->getTextureChannelToEdit()); + + // Draw face highlights for selected faces. + if (LLSelectMgr::getInstance()->getTEMode()) + { + struct f : public LLSelectedTEFunctor + { + virtual bool apply(LLViewerObject* object, S32 te) + { + if (object->mDrawable) + { + LLFace * facep = object->mDrawable->getFace(te); + if (facep) + { + gPipeline.mSelectedFaces.push_back(facep); + } + } + return true; + } + } func; + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func); + } + } - //LLSpatialGroup::sNoDelete = FALSE; - LL_PUSH_CALLSTACKS(); + //LLSpatialGroup::sNoDelete = FALSE; + LL_PUSH_CALLSTACKS(); } void render_hud_elements() { - gPipeline.disableLights(); - - LLGLDisable fog(GL_FOG); - LLGLSUIDefault gls_ui; - - LLGLEnable stencil(GL_STENCIL_TEST); - glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF); - glStencilMask(0xFFFFFFFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - - gGL.color4f(1,1,1,1); - - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } - LLGLDepthTest depth(GL_TRUE, GL_FALSE); + LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); + gPipeline.disableLights(); + + LLGLDisable fog(GL_FOG); + LLGLSUIDefault gls_ui; + + LLGLEnable stencil(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF); + glStencilMask(0xFFFFFFFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + + gGL.color4f(1,1,1,1); + + if (LLGLSLShader::sNoFixedFunction) + { + gUIProgram.bind(); + } + LLGLDepthTest depth(GL_TRUE, GL_FALSE); - if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) - { - LLGLEnable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); - gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d() - - // Draw the tracking overlays - LLTracker::render3D(); - - // Show the property lines - LLWorld::getInstance()->renderPropertyLines(); - LLViewerParcelMgr::getInstance()->render(); - LLViewerParcelMgr::getInstance()->renderParcelCollision(); - - // Render name tags. - LLHUDObject::renderAll(); - } - else if (gForceRenderLandFence) - { - // This is only set when not rendering the UI, for parcel snapshots - LLViewerParcelMgr::getInstance()->render(); - } - else if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) - { - LLHUDText::renderAllHUD(); - } + if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { + LLGLEnable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); + gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d() + + // Draw the tracking overlays + LLTracker::render3D(); + + // Show the property lines + LLWorld::getInstance()->renderPropertyLines(); + LLViewerParcelMgr::getInstance()->render(); + LLViewerParcelMgr::getInstance()->renderParcelCollision(); + + // Render name tags. + LLHUDObject::renderAll(); + } + else if (gForceRenderLandFence) + { + // This is only set when not rendering the UI, for parcel snapshots + LLViewerParcelMgr::getInstance()->render(); + } + else if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) + { + LLHUDText::renderAllHUD(); + } - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.unbind(); - } - gGL.flush(); + if (LLGLSLShader::sNoFixedFunction) + { + gUIProgram.unbind(); + } + gGL.flush(); } void LLPipeline::renderHighlights() { - assertInitialized(); + assertInitialized(); - // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD) - // Render highlighted faces. - LLGLSPipelineAlpha gls_pipeline_alpha; - LLColor4 color(1.f, 1.f, 1.f, 0.5f); - LLGLEnable color_mat(GL_COLOR_MATERIAL); - disableLights(); + // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD) + // Render highlighted faces. + LLGLSPipelineAlpha gls_pipeline_alpha; + LLColor4 color(1.f, 1.f, 1.f, 0.5f); + LLGLEnable color_mat(GL_COLOR_MATERIAL); + disableLights(); - if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD) && !mHighlightSet.empty()) - { //draw blurry highlight image over screen - LLGLEnable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - LLGLDisable test(GL_ALPHA_TEST); - - LLGLEnable stencil(GL_STENCIL_TEST); - gGL.flush(); - glStencilMask(0xFFFFFFFF); - glClearStencil(1); - glClear(GL_STENCIL_BUFFER_BIT); - - glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF); - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - - gGL.setColorMask(false, false); - for (std::set<HighlightItem>::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); ++iter) - { - renderHighlight(iter->mItem->getVObj(), 1.f); - } - gGL.setColorMask(true, false); + if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD) && !mHighlightSet.empty()) + { //draw blurry highlight image over screen + LLGLEnable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); + LLGLDisable test(GL_ALPHA_TEST); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF); - - //gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); + LLGLEnable stencil(GL_STENCIL_TEST); + gGL.flush(); + glStencilMask(0xFFFFFFFF); + glClearStencil(1); + glClear(GL_STENCIL_BUFFER_BIT); - gGL.pushMatrix(); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadIdentity(); - - gGL.getTexUnit(0)->bind(&mHighlight); - - LLVector2 tc1; - LLVector2 tc2; - - tc1.setVec(0,0); - tc2.setVec(2,2); - - gGL.begin(LLRender::TRIANGLES); - - F32 scale = RenderHighlightBrightness; - LLColor4 color = RenderHighlightColor; - F32 thickness = RenderHighlightThickness; - - for (S32 pass = 0; pass < 2; ++pass) - { - if (pass == 0) - { - gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); - } - else - { - gGL.setSceneBlendType(LLRender::BT_ALPHA); - } - - for (S32 i = 0; i < 8; ++i) - { - for (S32 j = 0; j < 8; ++j) - { - LLVector2 tc(i-4+0.5f, j-4+0.5f); - - F32 dist = 1.f-(tc.length()/sqrtf(32.f)); - dist *= scale/64.f; - - tc *= thickness; - tc.mV[0] = (tc.mV[0])/mHighlight.getWidth(); - tc.mV[1] = (tc.mV[1])/mHighlight.getHeight(); - - gGL.color4f(color.mV[0], - color.mV[1], - color.mV[2], - color.mV[3]*dist); - - gGL.texCoord2f(tc.mV[0]+tc1.mV[0], tc.mV[1]+tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc.mV[0]+tc1.mV[0], tc.mV[1]+tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc.mV[0]+tc2.mV[0], tc.mV[1]+tc1.mV[1]); - gGL.vertex2f(3,-1); - } - } - } - - gGL.end(); - - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); - - //gGL.setSceneBlendType(LLRender::BT_ALPHA); - } - - if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) - { - gHighlightProgram.bind(); - gGL.diffuseColor4f(1,1,1,0.5f); - } - - if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && !mFaceSelectImagep) - { - mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT); - } - - if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::DIFFUSE_MAP)) - { - // Make sure the selection image gets downloaded and decoded - mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); - - U32 count = mSelectedFaces.size(); - for (U32 i = 0; i < count; i++) - { - LLFace *facep = mSelectedFaces[i]; - if (!facep || facep->getDrawable()->isDead()) - { - LL_ERRS() << "Bad face on selection" << LL_ENDL; - return; - } - - facep->renderSelected(mFaceSelectImagep, color); - } - } - - if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED)) - { - // Paint 'em red! - color.setVec(1.f, 0.f, 0.f, 0.5f); - - int count = mHighlightFaces.size(); - for (S32 i = 0; i < count; i++) - { - LLFace* facep = mHighlightFaces[i]; - facep->renderSelected(LLViewerTexture::sNullImagep, color); - } - } + glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF); + glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); + + gGL.setColorMask(false, false); - // Contains a list of the faces of objects that are physical or - // have touch-handlers. - mHighlightFaces.clear(); - - if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0) - { - gHighlightProgram.unbind(); - } - - - if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP)) - { - color.setVec(1.0f, 0.5f, 0.5f, 0.5f); - if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + if (LLGLSLShader::sNoFixedFunction) { - gHighlightNormalProgram.bind(); - gGL.diffuseColor4f(1,1,1,0.5f); - } - - mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); + gHighlightProgram.bind(); + } + + for (std::set<HighlightItem>::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); ++iter) + { + renderHighlight(iter->mItem->getVObj(), 1.f); + } + gGL.setColorMask(true, false); + + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF); + + //gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); + + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); + + gGL.getTexUnit(0)->bind(&mHighlight); + + LLVector2 tc1; + LLVector2 tc2; + + tc1.setVec(0,0); + tc2.setVec(2,2); + + gGL.begin(LLRender::TRIANGLES); + + F32 scale = RenderHighlightBrightness; + LLColor4 color = RenderHighlightColor; + F32 thickness = RenderHighlightThickness; + + for (S32 pass = 0; pass < 2; ++pass) + { + if (pass == 0) + { + gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); + } + else + { + gGL.setSceneBlendType(LLRender::BT_ALPHA); + } + + for (S32 i = 0; i < 8; ++i) + { + for (S32 j = 0; j < 8; ++j) + { + LLVector2 tc(i-4+0.5f, j-4+0.5f); + + F32 dist = 1.f-(tc.length()/sqrtf(32.f)); + dist *= scale/64.f; + + tc *= thickness; + tc.mV[0] = (tc.mV[0])/mHighlight.getWidth(); + tc.mV[1] = (tc.mV[1])/mHighlight.getHeight(); + + gGL.color4f(color.mV[0], + color.mV[1], + color.mV[2], + color.mV[3]*dist); + + gGL.texCoord2f(tc.mV[0]+tc1.mV[0], tc.mV[1]+tc2.mV[1]); + gGL.vertex2f(-1,3); + + gGL.texCoord2f(tc.mV[0]+tc1.mV[0], tc.mV[1]+tc1.mV[1]); + gGL.vertex2f(-1,-1); + + gGL.texCoord2f(tc.mV[0]+tc2.mV[0], tc.mV[1]+tc1.mV[1]); + gGL.vertex2f(3,-1); + } + } + } + + gGL.end(); + + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); + + //gGL.setSceneBlendType(LLRender::BT_ALPHA); + } - U32 count = mSelectedFaces.size(); - for (U32 i = 0; i < count; i++) - { - LLFace *facep = mSelectedFaces[i]; - if (!facep || facep->getDrawable()->isDead()) - { - LL_ERRS() << "Bad face on selection" << LL_ENDL; - return; - } + if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + { + gHighlightProgram.bind(); + gGL.diffuseColor4f(1,1,1,0.5f); + } + + if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && !mFaceSelectImagep) + { + mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT); + } - facep->renderSelected(mFaceSelectImagep, color); - } + if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::DIFFUSE_MAP)) + { + // Make sure the selection image gets downloaded and decoded + mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); + + U32 count = mSelectedFaces.size(); + for (U32 i = 0; i < count; i++) + { + LLFace *facep = mSelectedFaces[i]; + if (!facep || facep->getDrawable()->isDead()) + { + LL_ERRS() << "Bad face on selection" << LL_ENDL; + return; + } + + facep->renderSelected(mFaceSelectImagep, color); + } + } - if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) - { - gHighlightNormalProgram.unbind(); - } - } + if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED)) + { + // Paint 'em red! + color.setVec(1.f, 0.f, 0.f, 0.5f); + + int count = mHighlightFaces.size(); + for (S32 i = 0; i < count; i++) + { + LLFace* facep = mHighlightFaces[i]; + facep->renderSelected(LLViewerTexture::sNullImagep, color); + } + } - if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP)) - { - color.setVec(0.0f, 0.3f, 1.0f, 0.8f); - if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) - { - gHighlightSpecularProgram.bind(); - gGL.diffuseColor4f(1,1,1,0.5f); - } + // Contains a list of the faces of objects that are physical or + // have touch-handlers. + mHighlightFaces.clear(); - mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); + if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0) + { + gHighlightProgram.unbind(); + } - U32 count = mSelectedFaces.size(); - for (U32 i = 0; i < count; i++) - { - LLFace *facep = mSelectedFaces[i]; - if (!facep || facep->getDrawable()->isDead()) - { - LL_ERRS() << "Bad face on selection" << LL_ENDL; - return; - } - facep->renderSelected(mFaceSelectImagep, color); - } + if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP)) + { + color.setVec(1.0f, 0.5f, 0.5f, 0.5f); + if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + { + gHighlightNormalProgram.bind(); + gGL.diffuseColor4f(1,1,1,0.5f); + } + + mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); + + U32 count = mSelectedFaces.size(); + for (U32 i = 0; i < count; i++) + { + LLFace *facep = mSelectedFaces[i]; + if (!facep || facep->getDrawable()->isDead()) + { + LL_ERRS() << "Bad face on selection" << LL_ENDL; + return; + } + + facep->renderSelected(mFaceSelectImagep, color); + } + + if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + { + gHighlightNormalProgram.unbind(); + } + } - if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) - { - gHighlightSpecularProgram.unbind(); - } - } + if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP)) + { + color.setVec(0.0f, 0.3f, 1.0f, 0.8f); + if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + { + gHighlightSpecularProgram.bind(); + gGL.diffuseColor4f(1,1,1,0.5f); + } + + mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); + + U32 count = mSelectedFaces.size(); + for (U32 i = 0; i < count; i++) + { + LLFace *facep = mSelectedFaces[i]; + if (!facep || facep->getDrawable()->isDead()) + { + LL_ERRS() << "Bad face on selection" << LL_ENDL; + return; + } + + facep->renderSelected(mFaceSelectImagep, color); + } + + if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + { + gHighlightSpecularProgram.unbind(); + } + } } //debug use @@ -4352,1627 +4289,1642 @@ U32 LLPipeline::sCurRenderPoolType = 0 ; void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); - - assertInitialized(); - - F32 saved_modelview[16]; - F32 saved_projection[16]; + LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); - //HACK: preserve/restore matrices around HUD render - if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) - { - for (U32 i = 0; i < 16; i++) - { - saved_modelview[i] = gGLModelView[i]; - saved_projection[i] = gGLProjection[i]; - } - } - - /////////////////////////////////////////// - // - // Sync and verify GL state - // - // - - stop_glerror(); + assertInitialized(); - LLVertexBuffer::unbind(); + F32 saved_modelview[16]; + F32 saved_projection[16]; - // Do verification of GL state - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); - if (mRenderDebugMask & RENDER_DEBUG_VERIFY) - { - if (!verify()) - { - LL_ERRS() << "Pipeline verification failed!" << LL_ENDL; - } - } - - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:ForceVBO"); - - // Initialize lots of GL state to "safe" values - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - - LLGLSPipeline gls_pipeline; - LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); - - LLGLState gls_color_material(GL_COLOR_MATERIAL, mLightingDetail < 2); - - // Toggle backface culling for debugging - LLGLEnable cull_face(mBackfaceCull ? GL_CULL_FACE : 0); - // Set fog - bool use_fog = hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG); - LLGLEnable fog_enable(use_fog && - !gPipeline.canUseWindLightShadersOnObjects() ? GL_FOG : 0); - gSky.updateFog(camera.getFar()); - if (!use_fog) - { - sUnderWaterRender = false; - } - - gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sDefaultImagep); - LLViewerFetchedTexture::sDefaultImagep->setAddressMode(LLTexUnit::TAM_WRAP); - - - ////////////////////////////////////////////// - // - // Actually render all of the geometry - // - // - stop_glerror(); - - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPools"); - - for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) - { - LLDrawPool *poolp = *iter; - if (hasRenderType(poolp->getType())) - { - poolp->prerender(); - } - } - - { - LL_RECORD_BLOCK_TIME(FTM_POOLS); - - // HACK: don't calculate local lights if we're rendering the HUD! - // Removing this check will cause bad flickering when there are - // HUD elements being rendered AND the user is in flycam mode -nyx - if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) - { - calcNearbyLights(camera); - setupHWLights(NULL); - } - - bool occlude = sUseOcclusion > 1; - U32 cur_type = 0; - - pool_set_t::iterator iter1 = mPools.begin(); - while ( iter1 != mPools.end() ) - { - LLDrawPool *poolp = *iter1; - - cur_type = poolp->getType(); - - //debug use - sCurRenderPoolType = cur_type ; + //HACK: preserve/restore matrices around HUD render + if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) + { + for (U32 i = 0; i < 16; i++) + { + saved_modelview[i] = gGLModelView[i]; + saved_projection[i] = gGLProjection[i]; + } + } - if (occlude && cur_type >= LLDrawPool::POOL_GRASS) - { - occlude = false; - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - LLGLSLShader::bindNoShader(); - doOcclusion(camera); - } + /////////////////////////////////////////// + // + // Sync and verify GL state + // + // - pool_set_t::iterator iter2 = iter1; - if (hasRenderType(poolp->getType()) && poolp->getNumPasses() > 0) - { - LL_RECORD_BLOCK_TIME(FTM_POOLRENDER); + stop_glerror(); - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - - for( S32 i = 0; i < poolp->getNumPasses(); i++ ) - { - LLVertexBuffer::unbind(); - poolp->beginRenderPass(i); - for (iter2 = iter1; iter2 != mPools.end(); iter2++) - { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) - { - break; - } - - if ( !p->getSkipRenderFlag() ) { p->render(i); } - } - poolp->endRenderPass(i); - LLVertexBuffer::unbind(); - if (gDebugGL) - { - std::string msg = llformat("pass %d", i); - LLGLState::checkStates(msg); - //LLGLState::checkTextureChannels(msg); - //LLGLState::checkClientArrays(msg); - } - } - } - else - { - // Skip all pools of this type - for (iter2 = iter1; iter2 != mPools.end(); iter2++) - { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) - { - break; - } - } - } - iter1 = iter2; - stop_glerror(); - } - - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPoolsEnd"); + LLVertexBuffer::unbind(); - LLVertexBuffer::unbind(); - - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - - if (occlude) - { - occlude = false; - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - LLGLSLShader::bindNoShader(); - doOcclusion(camera); - } - } - - LLVertexBuffer::unbind(); - LLGLState::checkStates(); + // Do verification of GL state + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); + if (mRenderDebugMask & RENDER_DEBUG_VERIFY) + { + if (!verify()) + { + LL_ERRS() << "Pipeline verification failed!" << LL_ENDL; + } + } - if (!LLPipeline::sImpostorRender) - { - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderHighlights"); + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:ForceVBO"); + + // Initialize lots of GL state to "safe" values + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + + LLGLSPipeline gls_pipeline; + LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); + + LLGLState gls_color_material(GL_COLOR_MATERIAL, mLightingDetail < 2); + + // Toggle backface culling for debugging + LLGLEnable cull_face(mBackfaceCull ? GL_CULL_FACE : 0); + // Set fog + bool use_fog = hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG); + LLGLEnable fog_enable(use_fog && + !gPipeline.canUseWindLightShadersOnObjects() ? GL_FOG : 0); + gSky.updateFog(camera.getFar()); + if (!use_fog) + { + sUnderWaterRender = false; + } - if (!sReflectionRender) - { - renderHighlights(); - } + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sDefaultImagep); + LLViewerFetchedTexture::sDefaultImagep->setAddressMode(LLTexUnit::TAM_WRAP); + - // Contains a list of the faces of objects that are physical or - // have touch-handlers. - mHighlightFaces.clear(); + ////////////////////////////////////////////// + // + // Actually render all of the geometry + // + // + stop_glerror(); + + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPools"); - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDebug"); - - renderDebug(); + for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) + { + LLDrawPool *poolp = *iter; + if (hasRenderType(poolp->getType())) + { + poolp->prerender(); + } + } - LLVertexBuffer::unbind(); - - if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred) - { - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) - { - // Render debugging beacons. - gObjectList.renderObjectBeacons(); - gObjectList.resetObjectBeacons(); - gSky.addSunMoonBeacons(); - } - else - { - // Make sure particle effects disappear - LLHUDObject::renderAllForTimer(); - } - } - else - { - // Make sure particle effects disappear - LLHUDObject::renderAllForTimer(); - } + { + LL_RECORD_BLOCK_TIME(FTM_POOLS); + + // HACK: don't calculate local lights if we're rendering the HUD! + // Removing this check will cause bad flickering when there are + // HUD elements being rendered AND the user is in flycam mode -nyx + if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) + { + calcNearbyLights(camera); + setupHWLights(NULL); + } + + bool occlude = sUseOcclusion > 1; + U32 cur_type = 0; + + pool_set_t::iterator iter1 = mPools.begin(); + while ( iter1 != mPools.end() ) + { + LLDrawPool *poolp = *iter1; + + cur_type = poolp->getType(); + + //debug use + sCurRenderPoolType = cur_type ; + + if (occlude && cur_type >= LLDrawPool::POOL_GRASS) + { + occlude = false; + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + LLGLSLShader::bindNoShader(); + doOcclusion(camera); + } + + pool_set_t::iterator iter2 = iter1; + if (hasRenderType(poolp->getType()) && poolp->getNumPasses() > 0) + { + LL_RECORD_BLOCK_TIME(FTM_POOLRENDER); + + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + + for( S32 i = 0; i < poolp->getNumPasses(); i++ ) + { + LLVertexBuffer::unbind(); + poolp->beginRenderPass(i); + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + + if ( !p->getSkipRenderFlag() ) { p->render(i); } + } + poolp->endRenderPass(i); + LLVertexBuffer::unbind(); + if (gDebugGL) + { + std::string msg = llformat("pass %d", i); + LLGLState::checkStates(msg); + //LLGLState::checkTextureChannels(msg); + //LLGLState::checkClientArrays(msg); + } + } + } + else + { + // Skip all pools of this type + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + } + } + iter1 = iter2; + stop_glerror(); + } + + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPoolsEnd"); + + LLVertexBuffer::unbind(); + + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + + if (occlude) + { + occlude = false; + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + LLGLSLShader::bindNoShader(); + doOcclusion(camera); + } + } - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomEnd"); + LLVertexBuffer::unbind(); + LLGLState::checkStates(); - //HACK: preserve/restore matrices around HUD render - if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) - { - for (U32 i = 0; i < 16; i++) - { - gGLModelView[i] = saved_modelview[i]; - gGLProjection[i] = saved_projection[i]; - } - } - } + if (!LLPipeline::sImpostorRender) + { + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderHighlights"); + + if (!sReflectionRender) + { + renderHighlights(); + } + + // Contains a list of the faces of objects that are physical or + // have touch-handlers. + mHighlightFaces.clear(); + + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDebug"); + + renderDebug(); + + LLVertexBuffer::unbind(); + + if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred) + { + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { + // Render debugging beacons. + gObjectList.renderObjectBeacons(); + gObjectList.resetObjectBeacons(); + } + else + { + // Make sure particle effects disappear + LLHUDObject::renderAllForTimer(); + } + } + else + { + // Make sure particle effects disappear + LLHUDObject::renderAllForTimer(); + } + + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomEnd"); + + //HACK: preserve/restore matrices around HUD render + if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) + { + for (U32 i = 0; i < 16; i++) + { + gGLModelView[i] = saved_modelview[i]; + gGLProjection[i] = saved_projection[i]; + } + } + } - LLVertexBuffer::unbind(); + LLVertexBuffer::unbind(); - LLGLState::checkStates(); -// LLGLState::checkTextureChannels(); -// LLGLState::checkClientArrays(); + LLGLState::checkStates(); +// LLGLState::checkTextureChannels(); +// LLGLState::checkClientArrays(); } void LLPipeline::renderGeomDeferred(LLCamera& camera) { - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred"); - - LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred"); - LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS); + LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); - LLGLEnable cull(GL_CULL_FACE); - - for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) - { - LLDrawPool *poolp = *iter; - if (hasRenderType(poolp->getType())) - { - poolp->prerender(); - } - } + LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS); - LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); + LLGLEnable cull(GL_CULL_FACE); - LLVertexBuffer::unbind(); - - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); - - gGL.setColorMask(true, true); - - pool_set_t::iterator iter = mPools.begin(); - while ( iter != mPools.end() ) - { - LLDrawPool* poolp = *iter; - llassert(poolp != nullptr); - if (poolp) - { - U32 pool_type = poolp->getType(); - S32 deferred_passes = poolp->getNumDeferredPasses(); - if (hasRenderType(pool_type) && (deferred_passes > 0)) - { - LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLRENDER); + for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) + { + LLDrawPool *poolp = *iter; + if (hasRenderType(poolp->getType())) + { + poolp->prerender(); + } + } - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); - for( S32 i = 0; i < deferred_passes; i++ ) - { - LLVertexBuffer::unbind(); - stop_glerror(); + LLVertexBuffer::unbind(); - poolp->beginDeferredPass(i); - poolp->renderDeferred(i); - poolp->endDeferredPass(i); + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); - // per-pass validation that our conception of current GL state is correct - if (gDebugGL || gDebugPipeline) - { - LLGLState::checkStates(); - } - } + U32 cur_type = 0; - LLVertexBuffer::unbind(); - stop_glerror(); - } - } + gGL.setColorMask(true, true); + + pool_set_t::iterator iter1 = mPools.begin(); - iter++; - } + while ( iter1 != mPools.end() ) + { + LLDrawPool *poolp = *iter1; + + cur_type = poolp->getType(); + + pool_set_t::iterator iter2 = iter1; + if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0) + { + LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLRENDER); + + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + + for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ ) + { + LLVertexBuffer::unbind(); + poolp->beginDeferredPass(i); + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + + if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); } + } + poolp->endDeferredPass(i); + LLVertexBuffer::unbind(); + + if (gDebugGL || gDebugPipeline) + { + LLGLState::checkStates(); + } + } + } + else + { + // Skip all pools of this type + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + } + } + iter1 = iter2; + stop_glerror(); + } - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.loadMatrix(gGLModelView); - gGL.setColorMask(true, false); + gGL.setColorMask(true, false); } void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion) { - LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_POOLS); - U32 cur_type = 0; - - LLGLEnable cull(GL_CULL_FACE); - - LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); + LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_POOLS); + U32 cur_type = 0; - calcNearbyLights(camera); - setupHWLights(NULL); + LLGLEnable cull(GL_CULL_FACE); - gGL.setColorMask(true, false); + LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); - pool_set_t::iterator iter1 = mPools.begin(); - bool occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion; + calcNearbyLights(camera); + setupHWLights(NULL); - while ( iter1 != mPools.end() ) - { - LLDrawPool *poolp = *iter1; - - cur_type = poolp->getType(); + gGL.setColorMask(true, false); - if (occlude && cur_type >= LLDrawPool::POOL_GRASS) - { - occlude = false; - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - LLGLSLShader::bindNoShader(); + pool_set_t::iterator iter1 = mPools.begin(); + bool occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion; - doOcclusion(camera, mScreen, mOcclusionDepth, &mDeferredDepth); - gGL.setColorMask(true, false); - } - - pool_set_t::iterator iter2 = iter1; - if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0) - { - LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_POOLRENDER); - - gGLLastMatrix = NULL; - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.loadMatrix(gGLModelView); - - for( S32 i = 0; i < poolp->getNumPostDeferredPasses(); i++ ) - { - LLVertexBuffer::unbind(); - poolp->beginPostDeferredPass(i); - for (iter2 = iter1; iter2 != mPools.end(); iter2++) - { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) - { - break; - } - - p->renderPostDeferred(i); - } - poolp->endPostDeferredPass(i); - LLVertexBuffer::unbind(); - - if (gDebugGL || gDebugPipeline) - { - LLGLState::checkStates(); - } - } - } - else - { - // Skip all pools of this type - for (iter2 = iter1; iter2 != mPools.end(); iter2++) - { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) - { - break; - } - } - } - iter1 = iter2; - stop_glerror(); - } + while ( iter1 != mPools.end() ) + { + LLDrawPool *poolp = *iter1; + + cur_type = poolp->getType(); + + if (occlude && cur_type >= LLDrawPool::POOL_GRASS) + { + occlude = false; + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + LLGLSLShader::bindNoShader(); + doOcclusion(camera, mScreen, mOcclusionDepth, &mDeferredDepth); + gGL.setColorMask(true, false); + } + + pool_set_t::iterator iter2 = iter1; + if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0) + { + LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_POOLRENDER); + + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + + for( S32 i = 0; i < poolp->getNumPostDeferredPasses(); i++ ) + { + LLVertexBuffer::unbind(); + poolp->beginPostDeferredPass(i); + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + + p->renderPostDeferred(i); + } + poolp->endPostDeferredPass(i); + LLVertexBuffer::unbind(); + + if (gDebugGL || gDebugPipeline) + { + LLGLState::checkStates(); + } + } + } + else + { + // Skip all pools of this type + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + } + } + iter1 = iter2; + stop_glerror(); + } - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.loadMatrix(gGLModelView); - if (occlude) - { - occlude = false; - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - LLGLSLShader::bindNoShader(); - doOcclusion(camera); - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - } + if (occlude) + { + occlude = false; + LLGLSLShader::bindNoShader(); + doOcclusion(camera); + gGLLastMatrix = NULL; + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.loadMatrix(gGLModelView); + } } void LLPipeline::renderGeomShadow(LLCamera& camera) { - U32 cur_type = 0; - - LLGLEnable cull(GL_CULL_FACE); - - LLVertexBuffer::unbind(); + U32 cur_type = 0; + + LLGLEnable cull(GL_CULL_FACE); - pool_set_t::iterator iter1 = mPools.begin(); - - while ( iter1 != mPools.end() ) - { - LLDrawPool *poolp = *iter1; - - cur_type = poolp->getType(); - - pool_set_t::iterator iter2 = iter1; - if (hasRenderType(poolp->getType()) && poolp->getNumShadowPasses() > 0) - { - poolp->prerender() ; - - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - - for( S32 i = 0; i < poolp->getNumShadowPasses(); i++ ) - { - LLVertexBuffer::unbind(); - poolp->beginShadowPass(i); - for (iter2 = iter1; iter2 != mPools.end(); iter2++) - { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) - { - break; - } - - p->renderShadow(i); - } - poolp->endShadowPass(i); - LLVertexBuffer::unbind(); + LLVertexBuffer::unbind(); - LLGLState::checkStates(); - } - } - else - { - // Skip all pools of this type - for (iter2 = iter1; iter2 != mPools.end(); iter2++) - { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) - { - break; - } - } - } - iter1 = iter2; - stop_glerror(); - } + pool_set_t::iterator iter1 = mPools.begin(); + + while ( iter1 != mPools.end() ) + { + LLDrawPool *poolp = *iter1; + + cur_type = poolp->getType(); + + pool_set_t::iterator iter2 = iter1; + if (hasRenderType(poolp->getType()) && poolp->getNumShadowPasses() > 0) + { + poolp->prerender() ; + + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + + for( S32 i = 0; i < poolp->getNumShadowPasses(); i++ ) + { + LLVertexBuffer::unbind(); + poolp->beginShadowPass(i); + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + + p->renderShadow(i); + } + poolp->endShadowPass(i); + LLVertexBuffer::unbind(); + + LLGLState::checkStates(); + } + } + else + { + // Skip all pools of this type + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + } + } + iter1 = iter2; + stop_glerror(); + } - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); } void LLPipeline::addTrianglesDrawn(S32 index_count, U32 render_type) { - assertInitialized(); - S32 count = 0; - if (render_type == LLRender::TRIANGLE_STRIP) - { - count = index_count-2; - } - else - { - count = index_count/3; - } + assertInitialized(); + S32 count = 0; + if (render_type == LLRender::TRIANGLE_STRIP) + { + count = index_count-2; + } + else + { + count = index_count/3; + } - record(sStatBatchSize, count); - add(LLStatViewer::TRIANGLES_DRAWN, LLUnits::Triangles::fromValue(count)); + record(sStatBatchSize, count); + add(LLStatViewer::TRIANGLES_DRAWN, LLUnits::Triangles::fromValue(count)); - if (LLPipeline::sRenderFrameTest) - { - gViewerWindow->getWindow()->swapBuffers(); - ms_sleep(16); - } + if (LLPipeline::sRenderFrameTest) + { + gViewerWindow->getWindow()->swapBuffers(); + ms_sleep(16); + } } void LLPipeline::renderPhysicsDisplay() { - if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) - { - return; - } + if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) + { + return; + } - allocatePhysicsBuffer(); + allocatePhysicsBuffer(); - gGL.flush(); - mPhysicsDisplay.bindTarget(); - glClearColor(0,0,0,1); - gGL.setColorMask(true, true); - mPhysicsDisplay.clear(); - glClearColor(0,0,0,0); + gGL.flush(); + mPhysicsDisplay.bindTarget(); + glClearColor(0,0,0,1); + gGL.setColorMask(true, true); + mPhysicsDisplay.clear(); + glClearColor(0,0,0,0); - gGL.setColorMask(true, false); + gGL.setColorMask(true, false); - if (LLGLSLShader::sNoFixedFunction) - { - gDebugProgram.bind(); - } + if (LLGLSLShader::sNoFixedFunction) + { + gDebugProgram.bind(); + } - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) - { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) - { - if (hasRenderType(part->mDrawableType)) - { - part->renderPhysicsShapes(); - } - } - } - } + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + if (hasRenderType(part->mDrawableType)) + { + part->renderPhysicsShapes(); + } + } + } + } - gGL.flush(); + gGL.flush(); - if (LLGLSLShader::sNoFixedFunction) - { - gDebugProgram.unbind(); - } + if (LLGLSLShader::sNoFixedFunction) + { + gDebugProgram.unbind(); + } - mPhysicsDisplay.flush(); + mPhysicsDisplay.flush(); } extern std::set<LLSpatialGroup*> visible_selected_groups; void LLPipeline::renderDebug() { - assertInitialized(); - - bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD); - - if (!hud_only ) - { - //Render any navmesh geometry - LLPathingLib *llPathingLibInstance = LLPathingLib::getInstance(); - if ( llPathingLibInstance != NULL ) - { - //character floater renderables - - LLHandle<LLFloaterPathfindingCharacters> pathfindingCharacterHandle = LLFloaterPathfindingCharacters::getInstanceHandle(); - if ( !pathfindingCharacterHandle.isDead() ) - { - LLFloaterPathfindingCharacters *pathfindingCharacter = pathfindingCharacterHandle.get(); - - if ( pathfindingCharacter->getVisible() || gAgentCamera.cameraMouselook() ) - { - if (LLGLSLShader::sNoFixedFunction) - { - gPathfindingProgram.bind(); - gPathfindingProgram.uniform1f(sTint, 1.f); - gPathfindingProgram.uniform1f(sAmbiance, 1.f); - gPathfindingProgram.uniform1f(sAlphaScale, 1.f); - } - - //Requried character physics capsule render parameters - LLUUID id; - LLVector3 pos; - LLQuaternion rot; - - if ( pathfindingCharacter->isPhysicsCapsuleEnabled( id, pos, rot ) ) - { - if (LLGLSLShader::sNoFixedFunction) - { - //remove blending artifacts - gGL.setColorMask(false, false); - llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); - gGL.setColorMask(true, false); - LLGLEnable blend(GL_BLEND); - gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); - llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); - gPathfindingProgram.bind(); - } - else - { - llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); - } - } - } - } - - - //pathing console renderables - LLHandle<LLFloaterPathfindingConsole> pathfindingConsoleHandle = LLFloaterPathfindingConsole::getInstanceHandle(); - if (!pathfindingConsoleHandle.isDead()) - { - LLFloaterPathfindingConsole *pathfindingConsole = pathfindingConsoleHandle.get(); - - if ( pathfindingConsole->getVisible() || gAgentCamera.cameraMouselook() ) - { - F32 ambiance = gSavedSettings.getF32("PathfindingAmbiance"); - - if (LLGLSLShader::sNoFixedFunction) - { - gPathfindingProgram.bind(); - - gPathfindingProgram.uniform1f(sTint, 1.f); - gPathfindingProgram.uniform1f(sAmbiance, ambiance); - gPathfindingProgram.uniform1f(sAlphaScale, 1.f); - } - - if ( !pathfindingConsole->isRenderWorld() ) - { - const LLColor4 clearColor = gSavedSettings.getColor4("PathfindingNavMeshClear"); - gGL.setColorMask(true, true); - glClearColor(clearColor.mV[0],clearColor.mV[1],clearColor.mV[2],0); - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - gGL.setColorMask(true, false); - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - } - - //NavMesh - if ( pathfindingConsole->isRenderNavMesh() ) - { - gGL.flush(); - glLineWidth(2.0f); - LLGLEnable cull(GL_CULL_FACE); - LLGLDisable blend(GL_BLEND); - - if ( pathfindingConsole->isRenderWorld() ) - { - LLGLEnable blend(GL_BLEND); - gPathfindingProgram.uniform1f(sAlphaScale, 0.66f); - llPathingLibInstance->renderNavMesh(); - } - else - { - llPathingLibInstance->renderNavMesh(); - } - - //render edges - if (LLGLSLShader::sNoFixedFunction) - { - gPathfindingNoNormalsProgram.bind(); - gPathfindingNoNormalsProgram.uniform1f(sTint, 1.f); - gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, 1.f); - llPathingLibInstance->renderNavMeshEdges(); - gPathfindingProgram.bind(); - } - else - { - llPathingLibInstance->renderNavMeshEdges(); - } - - gGL.flush(); - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - glLineWidth(1.0f); - gGL.flush(); - } - //User designated path - if ( LLPathfindingPathTool::getInstance()->isRenderPath() ) - { - //The path - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); - llPathingLibInstance->renderPath(); - gPathfindingProgram.bind(); - } - else - { - llPathingLibInstance->renderPath(); - } - //The bookends - if (LLGLSLShader::sNoFixedFunction) - { - //remove blending artifacts - gGL.setColorMask(false, false); - llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START ); - llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END ); - - gGL.setColorMask(true, false); - //render the bookends - LLGLEnable blend(GL_BLEND); - gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); - llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START ); - llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END ); - gPathfindingProgram.bind(); - } - else - { - llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START ); - llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END ); - } - - } - - if ( pathfindingConsole->isRenderWaterPlane() ) - { - if (LLGLSLShader::sNoFixedFunction) - { - LLGLEnable blend(GL_BLEND); - gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); - llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() ); - } - else - { - llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() ); - } - } - //physics/exclusion shapes - if ( pathfindingConsole->isRenderAnyShapes() ) - { - U32 render_order[] = { - 1 << LLPathingLib::LLST_ObstacleObjects, - 1 << LLPathingLib::LLST_WalkableObjects, - 1 << LLPathingLib::LLST_ExclusionPhantoms, - 1 << LLPathingLib::LLST_MaterialPhantoms, - }; - - U32 flags = pathfindingConsole->getRenderShapeFlags(); - - for (U32 i = 0; i < 4; i++) - { - if (!(flags & render_order[i])) - { - continue; - } - - //turn off backface culling for volumes so they are visible when camera is inside volume - LLGLDisable cull(i >= 2 ? GL_CULL_FACE : 0); - - gGL.flush(); - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - - //get rid of some z-fighting - LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(1.0f, 1.0f); - - //render to depth first to avoid blending artifacts - gGL.setColorMask(false, false); - llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); - gGL.setColorMask(true, false); - - //get rid of some z-fighting - glPolygonOffset(0.f, 0.f); - - LLGLEnable blend(GL_BLEND); - - { - gPathfindingProgram.uniform1f(sAmbiance, ambiance); - - { //draw solid overlay - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_LEQUAL); - llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); - gGL.flush(); - } - - LLGLEnable lineOffset(GL_POLYGON_OFFSET_LINE); - glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); - - F32 offset = gSavedSettings.getF32("PathfindingLineOffset"); - - if (pathfindingConsole->isRenderXRay()) - { - gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint")); - gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity")); - LLGLEnable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); - - glPolygonOffset(offset, -offset); - - if (gSavedSettings.getBOOL("PathfindingXRayWireframe")) - { //draw hidden wireframe as darker and less opaque - gPathfindingProgram.uniform1f(sAmbiance, 1.f); - llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); - } - else - { - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - gPathfindingProgram.uniform1f(sAmbiance, ambiance); - llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - } - } - - { //draw visible wireframe as brighter, thicker and more opaque - glPolygonOffset(offset, offset); - gPathfindingProgram.uniform1f(sAmbiance, 1.f); - gPathfindingProgram.uniform1f(sTint, 1.f); - gPathfindingProgram.uniform1f(sAlphaScale, 1.f); - - glLineWidth(gSavedSettings.getF32("PathfindingLineWidth")); - LLGLDisable blendOut(GL_BLEND); - llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); - gGL.flush(); - glLineWidth(1.f); - } - - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - } - } - } + assertInitialized(); - glPolygonOffset(0.f, 0.f); - - if ( pathfindingConsole->isRenderNavMesh() && pathfindingConsole->isRenderXRay() ) - { //render navmesh xray - F32 ambiance = gSavedSettings.getF32("PathfindingAmbiance"); - - LLGLEnable lineOffset(GL_POLYGON_OFFSET_LINE); - LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); - - F32 offset = gSavedSettings.getF32("PathfindingLineOffset"); - glPolygonOffset(offset, -offset); - - LLGLEnable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); - gGL.flush(); - glLineWidth(2.0f); - LLGLEnable cull(GL_CULL_FACE); - - gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint")); - gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity")); - - if (gSavedSettings.getBOOL("PathfindingXRayWireframe")) - { //draw hidden wireframe as darker and less opaque - glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); - gPathfindingProgram.uniform1f(sAmbiance, 1.f); - llPathingLibInstance->renderNavMesh(); - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - } - else - { - gPathfindingProgram.uniform1f(sAmbiance, ambiance); - llPathingLibInstance->renderNavMesh(); - } + bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD); - //render edges - if (LLGLSLShader::sNoFixedFunction) - { - gPathfindingNoNormalsProgram.bind(); - gPathfindingNoNormalsProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint")); - gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity")); - llPathingLibInstance->renderNavMeshEdges(); - gPathfindingProgram.bind(); - } - else - { - llPathingLibInstance->renderNavMeshEdges(); - } - - gGL.flush(); - glLineWidth(1.0f); - } - - glPolygonOffset(0.f, 0.f); - - gGL.flush(); - if (LLGLSLShader::sNoFixedFunction) - { - gPathfindingProgram.unbind(); - } - } - } - } - } - - gGL.color4f(1,1,1,1); - - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - gGL.setColorMask(true, false); - - - if (!hud_only && !mDebugBlips.empty()) - { //render debug blips - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } - - gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep, true); - - glPointSize(8.f); - LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); - - gGL.begin(LLRender::POINTS); - for (std::list<DebugBlip>::iterator iter = mDebugBlips.begin(); iter != mDebugBlips.end(); ) - { - DebugBlip& blip = *iter; - - blip.mAge += gFrameIntervalSeconds.value(); - if (blip.mAge > 2.f) - { - mDebugBlips.erase(iter++); - } - else - { - iter++; - } - - blip.mPosition.mV[2] += gFrameIntervalSeconds.value()*2.f; - - gGL.color4fv(blip.mColor.mV); - gGL.vertex3fv(blip.mPosition.mV); - } - gGL.end(); - gGL.flush(); - glPointSize(1.f); - } - - - // Debug stuff. - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) - { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) - { - if ( (hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES)) || - (!hud_only && hasRenderType(part->mDrawableType)) ) - { - part->renderDebug(); - } - } - } - } - - for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) - { - LLSpatialBridge* bridge = *i; - if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) - { - gGL.pushMatrix(); - gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); - bridge->renderDebug(); - gGL.popMatrix(); - } - } - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION) && LLGLSLShader::sNoFixedFunction) - { //render visible selected group occlusion geometry - gDebugProgram.bind(); - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - gGL.diffuseColor3f(1,0,1); - for (std::set<LLSpatialGroup*>::iterator iter = visible_selected_groups.begin(); iter != visible_selected_groups.end(); ++iter) - { - LLSpatialGroup* group = *iter; - - LLVector4a fudge; - fudge.splat(0.25f); //SG_OCCLUSION_FUDGE - - LLVector4a size; - const LLVector4a* bounds = group->getBounds(); - size.setAdd(fudge, bounds[1]); - - drawBox(bounds[0], size); - } - } - - visible_selected_groups.clear(); - - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.bind(); - } - - if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST) && !hud_only) - { //draw crosshairs on particle intersection - if (gDebugRaycastParticle) - { - if (LLGLSLShader::sNoFixedFunction) - { //this debug display requires shaders - gDebugProgram.bind(); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - LLVector3 center(gDebugRaycastParticleIntersection.getF32ptr()); - LLVector3 size(0.1f, 0.1f, 0.1f); - - LLVector3 p[6]; - - p[0] = center + size.scaledVec(LLVector3(1,0,0)); - p[1] = center + size.scaledVec(LLVector3(-1,0,0)); - p[2] = center + size.scaledVec(LLVector3(0,1,0)); - p[3] = center + size.scaledVec(LLVector3(0,-1,0)); - p[4] = center + size.scaledVec(LLVector3(0,0,1)); - p[5] = center + size.scaledVec(LLVector3(0,0,-1)); - - gGL.begin(LLRender::LINES); - gGL.diffuseColor3f(1.f, 1.f, 0.f); - for (U32 i = 0; i < 6; i++) - { - gGL.vertex3fv(p[i].mV); - } - gGL.end(); - gGL.flush(); - - gDebugProgram.unbind(); - } - } - } - - if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) - { - LLVertexBuffer::unbind(); - - LLGLEnable blend(GL_BLEND); - LLGLDepthTest depth(TRUE, FALSE); - LLGLDisable cull(GL_CULL_FACE); - - gGL.color4f(1,1,1,1); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - F32 a = 0.1f; - - F32 col[] = - { - 1,0,0,a, - 0,1,0,a, - 0,0,1,a, - 1,0,1,a, - - 1,1,0,a, - 0,1,1,a, - 1,1,1,a, - 1,0,1,a, - }; - - for (U32 i = 0; i < 8; i++) - { - LLVector3* frust = mShadowCamera[i].mAgentFrustum; - - if (i > 3) - { //render shadow frusta as volumes - if (mShadowFrustPoints[i-4].empty()) - { - continue; - } - - gGL.color4fv(col+(i-4)*4); - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); - gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV); - gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV); - gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); - gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); - gGL.end(); - - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex3fv(frust[0].mV); - gGL.vertex3fv(frust[1].mV); - gGL.vertex3fv(frust[3].mV); - gGL.vertex3fv(frust[2].mV); - gGL.end(); - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex3fv(frust[4].mV); - gGL.vertex3fv(frust[5].mV); - gGL.vertex3fv(frust[7].mV); - gGL.vertex3fv(frust[6].mV); - gGL.end(); - } - - - if (i < 4) - { - - //if (i == 0 || !mShadowFrustPoints[i].empty()) - { - //render visible point cloud - gGL.flush(); - glPointSize(8.f); - gGL.begin(LLRender::POINTS); - - F32* c = col+i*4; - gGL.color3fv(c); - - for (U32 j = 0; j < mShadowFrustPoints[i].size(); ++j) - { - gGL.vertex3fv(mShadowFrustPoints[i][j].mV); - - } - gGL.end(); - - gGL.flush(); - glPointSize(1.f); - - LLVector3* ext = mShadowExtents[i]; - LLVector3 pos = (ext[0]+ext[1])*0.5f; - LLVector3 size = (ext[1]-ext[0])*0.5f; - drawBoxOutline(pos, size); - - //render camera frustum splits as outlines - gGL.begin(LLRender::LINES); - gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[1].mV); - gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[2].mV); - gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[3].mV); - gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[0].mV); - gGL.vertex3fv(frust[4].mV); gGL.vertex3fv(frust[5].mV); - gGL.vertex3fv(frust[5].mV); gGL.vertex3fv(frust[6].mV); - gGL.vertex3fv(frust[6].mV); gGL.vertex3fv(frust[7].mV); - gGL.vertex3fv(frust[7].mV); gGL.vertex3fv(frust[4].mV); - gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); - gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV); - gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV); - gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); - gGL.end(); - } - } - - /*gGL.flush(); - glLineWidth(16-i*2); - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++) - { - LLSpatialPartition* part = region->getSpatialPartition(j); - if (part) - { - if (hasRenderType(part->mDrawableType)) - { - part->renderIntersectingBBoxes(&mShadowCamera[i]); - } - } - } - } - gGL.flush(); - glLineWidth(1.f);*/ - } - } - - if (mRenderDebugMask & RENDER_DEBUG_WIND_VECTORS) - { - gAgent.getRegion()->mWind.renderVectors(); - } - - if (mRenderDebugMask & RENDER_DEBUG_COMPOSITION) - { - // Debug composition layers - F32 x, y; - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - if (gAgent.getRegion()) - { - gGL.begin(LLRender::POINTS); - // Draw the composition layer for the region that I'm in. - for (x = 0; x <= 260; x++) - { - for (y = 0; y <= 260; y++) - { - if ((x > 255) || (y > 255)) - { - gGL.color4f(1.f, 0.f, 0.f, 1.f); - } - else - { - gGL.color4f(0.f, 0.f, 1.f, 1.f); - } - F32 z = gAgent.getRegion()->getCompositionXY((S32)x, (S32)y); - z *= 5.f; - z += 50.f; - gGL.vertex3f(x, y, z); - } - } - gGL.end(); - } - } + if (!hud_only ) + { + //Render any navmesh geometry + LLPathingLib *llPathingLibInstance = LLPathingLib::getInstance(); + if ( llPathingLibInstance != NULL ) + { + //character floater renderables + + LLHandle<LLFloaterPathfindingCharacters> pathfindingCharacterHandle = LLFloaterPathfindingCharacters::getInstanceHandle(); + if ( !pathfindingCharacterHandle.isDead() ) + { + LLFloaterPathfindingCharacters *pathfindingCharacter = pathfindingCharacterHandle.get(); + + if ( pathfindingCharacter->getVisible() || gAgentCamera.cameraMouselook() ) + { + if (LLGLSLShader::sNoFixedFunction) + { + gPathfindingProgram.bind(); + gPathfindingProgram.uniform1f(sTint, 1.f); + gPathfindingProgram.uniform1f(sAmbiance, 1.f); + gPathfindingProgram.uniform1f(sAlphaScale, 1.f); + } + + //Requried character physics capsule render parameters + LLUUID id; + LLVector3 pos; + LLQuaternion rot; + + if ( pathfindingCharacter->isPhysicsCapsuleEnabled( id, pos, rot ) ) + { + if (LLGLSLShader::sNoFixedFunction) + { + //remove blending artifacts + gGL.setColorMask(false, false); + llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); + gGL.setColorMask(true, false); + LLGLEnable blend(GL_BLEND); + gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); + llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); + gPathfindingProgram.bind(); + } + else + { + llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot ); + } + } + } + } + + + //pathing console renderables + LLHandle<LLFloaterPathfindingConsole> pathfindingConsoleHandle = LLFloaterPathfindingConsole::getInstanceHandle(); + if (!pathfindingConsoleHandle.isDead()) + { + LLFloaterPathfindingConsole *pathfindingConsole = pathfindingConsoleHandle.get(); + + if ( pathfindingConsole->getVisible() || gAgentCamera.cameraMouselook() ) + { + F32 ambiance = gSavedSettings.getF32("PathfindingAmbiance"); + + if (LLGLSLShader::sNoFixedFunction) + { + gPathfindingProgram.bind(); + + gPathfindingProgram.uniform1f(sTint, 1.f); + gPathfindingProgram.uniform1f(sAmbiance, ambiance); + gPathfindingProgram.uniform1f(sAlphaScale, 1.f); + } + + if ( !pathfindingConsole->isRenderWorld() ) + { + const LLColor4 clearColor = gSavedSettings.getColor4("PathfindingNavMeshClear"); + gGL.setColorMask(true, true); + glClearColor(clearColor.mV[0],clearColor.mV[1],clearColor.mV[2],0); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + gGL.setColorMask(true, false); + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } + + //NavMesh + if ( pathfindingConsole->isRenderNavMesh() ) + { + gGL.flush(); + glLineWidth(2.0f); + LLGLEnable cull(GL_CULL_FACE); + LLGLDisable blend(GL_BLEND); + + if ( pathfindingConsole->isRenderWorld() ) + { + LLGLEnable blend(GL_BLEND); + gPathfindingProgram.uniform1f(sAlphaScale, 0.66f); + llPathingLibInstance->renderNavMesh(); + } + else + { + llPathingLibInstance->renderNavMesh(); + } + + //render edges + if (LLGLSLShader::sNoFixedFunction) + { + gPathfindingNoNormalsProgram.bind(); + gPathfindingNoNormalsProgram.uniform1f(sTint, 1.f); + gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, 1.f); + llPathingLibInstance->renderNavMeshEdges(); + gPathfindingProgram.bind(); + } + else + { + llPathingLibInstance->renderNavMeshEdges(); + } + + gGL.flush(); + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + glLineWidth(1.0f); + gGL.flush(); + } + //User designated path + if ( LLPathfindingPathTool::getInstance()->isRenderPath() ) + { + //The path + if (LLGLSLShader::sNoFixedFunction) + { + gUIProgram.bind(); + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); + llPathingLibInstance->renderPath(); + gPathfindingProgram.bind(); + } + else + { + llPathingLibInstance->renderPath(); + } + //The bookends + if (LLGLSLShader::sNoFixedFunction) + { + //remove blending artifacts + gGL.setColorMask(false, false); + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START ); + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END ); + + gGL.setColorMask(true, false); + //render the bookends + LLGLEnable blend(GL_BLEND); + gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START ); + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END ); + gPathfindingProgram.bind(); + } + else + { + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START ); + llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END ); + } + + } + + if ( pathfindingConsole->isRenderWaterPlane() ) + { + if (LLGLSLShader::sNoFixedFunction) + { + LLGLEnable blend(GL_BLEND); + gPathfindingProgram.uniform1f(sAlphaScale, 0.90f); + llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() ); + } + else + { + llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() ); + } + } + //physics/exclusion shapes + if ( pathfindingConsole->isRenderAnyShapes() ) + { + U32 render_order[] = { + 1 << LLPathingLib::LLST_ObstacleObjects, + 1 << LLPathingLib::LLST_WalkableObjects, + 1 << LLPathingLib::LLST_ExclusionPhantoms, + 1 << LLPathingLib::LLST_MaterialPhantoms, + }; + + U32 flags = pathfindingConsole->getRenderShapeFlags(); + + for (U32 i = 0; i < 4; i++) + { + if (!(flags & render_order[i])) + { + continue; + } + + //turn off backface culling for volumes so they are visible when camera is inside volume + LLGLDisable cull(i >= 2 ? GL_CULL_FACE : 0); + + gGL.flush(); + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + + //get rid of some z-fighting + LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(1.0f, 1.0f); + + //render to depth first to avoid blending artifacts + gGL.setColorMask(false, false); + llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); + gGL.setColorMask(true, false); + + //get rid of some z-fighting + glPolygonOffset(0.f, 0.f); + + LLGLEnable blend(GL_BLEND); + + { + gPathfindingProgram.uniform1f(sAmbiance, ambiance); + + { //draw solid overlay + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_LEQUAL); + llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); + gGL.flush(); + } + + LLGLEnable lineOffset(GL_POLYGON_OFFSET_LINE); + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + + F32 offset = gSavedSettings.getF32("PathfindingLineOffset"); + + if (pathfindingConsole->isRenderXRay()) + { + gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint")); + gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity")); + LLGLEnable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); + + glPolygonOffset(offset, -offset); + + if (gSavedSettings.getBOOL("PathfindingXRayWireframe")) + { //draw hidden wireframe as darker and less opaque + gPathfindingProgram.uniform1f(sAmbiance, 1.f); + llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); + } + else + { + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + gPathfindingProgram.uniform1f(sAmbiance, ambiance); + llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + } + } + + { //draw visible wireframe as brighter, thicker and more opaque + glPolygonOffset(offset, offset); + gPathfindingProgram.uniform1f(sAmbiance, 1.f); + gPathfindingProgram.uniform1f(sTint, 1.f); + gPathfindingProgram.uniform1f(sAlphaScale, 1.f); + + glLineWidth(gSavedSettings.getF32("PathfindingLineWidth")); + LLGLDisable blendOut(GL_BLEND); + llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] ); + gGL.flush(); + glLineWidth(1.f); + } + + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } + } + } + + glPolygonOffset(0.f, 0.f); + + if ( pathfindingConsole->isRenderNavMesh() && pathfindingConsole->isRenderXRay() ) + { //render navmesh xray + F32 ambiance = gSavedSettings.getF32("PathfindingAmbiance"); + + LLGLEnable lineOffset(GL_POLYGON_OFFSET_LINE); + LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); + + F32 offset = gSavedSettings.getF32("PathfindingLineOffset"); + glPolygonOffset(offset, -offset); + + LLGLEnable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); + gGL.flush(); + glLineWidth(2.0f); + LLGLEnable cull(GL_CULL_FACE); + + gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint")); + gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity")); + + if (gSavedSettings.getBOOL("PathfindingXRayWireframe")) + { //draw hidden wireframe as darker and less opaque + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + gPathfindingProgram.uniform1f(sAmbiance, 1.f); + llPathingLibInstance->renderNavMesh(); + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } + else + { + gPathfindingProgram.uniform1f(sAmbiance, ambiance); + llPathingLibInstance->renderNavMesh(); + } + + //render edges + if (LLGLSLShader::sNoFixedFunction) + { + gPathfindingNoNormalsProgram.bind(); + gPathfindingNoNormalsProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint")); + gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity")); + llPathingLibInstance->renderNavMeshEdges(); + gPathfindingProgram.bind(); + } + else + { + llPathingLibInstance->renderNavMeshEdges(); + } + + gGL.flush(); + glLineWidth(1.0f); + } + + glPolygonOffset(0.f, 0.f); + + gGL.flush(); + if (LLGLSLShader::sNoFixedFunction) + { + gPathfindingProgram.unbind(); + } + } + } + } + } - if (mRenderDebugMask & LLPipeline::RENDER_DEBUG_BUILD_QUEUE) - { - U32 count = 0; - U32 size = mGroupQ2.size(); - LLColor4 col; + gGL.color4f(1,1,1,1); + + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + gGL.setColorMask(true, false); + + + if (!hud_only && !mDebugBlips.empty()) + { //render debug blips + if (LLGLSLShader::sNoFixedFunction) + { + gUIProgram.bind(); + } + + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep, true); + + glPointSize(8.f); + LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); + + gGL.begin(LLRender::POINTS); + for (std::list<DebugBlip>::iterator iter = mDebugBlips.begin(); iter != mDebugBlips.end(); ) + { + DebugBlip& blip = *iter; + + blip.mAge += gFrameIntervalSeconds.value(); + if (blip.mAge > 2.f) + { + mDebugBlips.erase(iter++); + } + else + { + iter++; + } + + blip.mPosition.mV[2] += gFrameIntervalSeconds.value()*2.f; + + gGL.color4fv(blip.mColor.mV); + gGL.vertex3fv(blip.mPosition.mV); + } + gGL.end(); + gGL.flush(); + glPointSize(1.f); + } - LLVertexBuffer::unbind(); - LLGLEnable blend(GL_BLEND); - gGL.setSceneBlendType(LLRender::BT_ALPHA); - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); - - gGL.pushMatrix(); - gGL.loadMatrix(gGLModelView); - gGLLastMatrix = NULL; - for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); iter != mGroupQ2.end(); ++iter) - { - LLSpatialGroup* group = *iter; - if (group->isDead()) - { - continue; - } + // Debug stuff. + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + if ( (hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES)) || + (!hud_only && hasRenderType(part->mDrawableType)) ) + { + part->renderDebug(); + } + } + } + } - LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge(); + for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + { + LLSpatialBridge* bridge = *i; + if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) + { + gGL.pushMatrix(); + gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); + bridge->renderDebug(); + gGL.popMatrix(); + } + } - if (bridge && (!bridge->mDrawable || bridge->mDrawable->isDead())) - { - continue; - } + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION) && LLGLSLShader::sNoFixedFunction) + { //render visible selected group occlusion geometry + gDebugProgram.bind(); + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + gGL.diffuseColor3f(1,0,1); + for (std::set<LLSpatialGroup*>::iterator iter = visible_selected_groups.begin(); iter != visible_selected_groups.end(); ++iter) + { + LLSpatialGroup* group = *iter; + + LLVector4a fudge; + fudge.splat(0.25f); //SG_OCCLUSION_FUDGE + + LLVector4a size; + const LLVector4a* bounds = group->getBounds(); + size.setAdd(fudge, bounds[1]); + + drawBox(bounds[0], size); + } + } - if (bridge) - { - gGL.pushMatrix(); - gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); - } + visible_selected_groups.clear(); - F32 alpha = llclamp((F32) (size-count)/size, 0.f, 1.f); + if (LLGLSLShader::sNoFixedFunction) + { + gUIProgram.bind(); + } - - LLVector2 c(1.f-alpha, alpha); - c.normVec(); + if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST) && !hud_only) + { //draw crosshairs on particle intersection + if (gDebugRaycastParticle) + { + if (LLGLSLShader::sNoFixedFunction) + { //this debug display requires shaders + gDebugProgram.bind(); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + LLVector3 center(gDebugRaycastParticleIntersection.getF32ptr()); + LLVector3 size(0.1f, 0.1f, 0.1f); + + LLVector3 p[6]; + + p[0] = center + size.scaledVec(LLVector3(1,0,0)); + p[1] = center + size.scaledVec(LLVector3(-1,0,0)); + p[2] = center + size.scaledVec(LLVector3(0,1,0)); + p[3] = center + size.scaledVec(LLVector3(0,-1,0)); + p[4] = center + size.scaledVec(LLVector3(0,0,1)); + p[5] = center + size.scaledVec(LLVector3(0,0,-1)); + + gGL.begin(LLRender::LINES); + gGL.diffuseColor3f(1.f, 1.f, 0.f); + for (U32 i = 0; i < 6; i++) + { + gGL.vertex3fv(p[i].mV); + } + gGL.end(); + gGL.flush(); + + gDebugProgram.unbind(); + } + } + } - - ++count; - col.set(c.mV[0], c.mV[1], 0, alpha*0.5f+0.5f); - group->drawObjectBox(col); + if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) + { + LLVertexBuffer::unbind(); + + LLGLEnable blend(GL_BLEND); + LLGLDepthTest depth(TRUE, FALSE); + LLGLDisable cull(GL_CULL_FACE); + + gGL.color4f(1,1,1,1); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + F32 a = 0.1f; + + F32 col[] = + { + 1,0,0,a, + 0,1,0,a, + 0,0,1,a, + 1,0,1,a, + + 1,1,0,a, + 0,1,1,a, + 1,1,1,a, + 1,0,1,a, + }; + + for (U32 i = 0; i < 8; i++) + { + LLVector3* frust = mShadowCamera[i].mAgentFrustum; + + if (i > 3) + { //render shadow frusta as volumes + if (mShadowFrustPoints[i-4].empty()) + { + continue; + } + + gGL.color4fv(col+(i-4)*4); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); + gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV); + gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV); + gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); + gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); + gGL.end(); + + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3fv(frust[0].mV); + gGL.vertex3fv(frust[1].mV); + gGL.vertex3fv(frust[3].mV); + gGL.vertex3fv(frust[2].mV); + gGL.end(); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3fv(frust[4].mV); + gGL.vertex3fv(frust[5].mV); + gGL.vertex3fv(frust[7].mV); + gGL.vertex3fv(frust[6].mV); + gGL.end(); + } + + + if (i < 4) + { + + //if (i == 0 || !mShadowFrustPoints[i].empty()) + { + //render visible point cloud + gGL.flush(); + glPointSize(8.f); + gGL.begin(LLRender::POINTS); + + F32* c = col+i*4; + gGL.color3fv(c); + + for (U32 j = 0; j < mShadowFrustPoints[i].size(); ++j) + { + gGL.vertex3fv(mShadowFrustPoints[i][j].mV); + + } + gGL.end(); + + gGL.flush(); + glPointSize(1.f); + + LLVector3* ext = mShadowExtents[i]; + LLVector3 pos = (ext[0]+ext[1])*0.5f; + LLVector3 size = (ext[1]-ext[0])*0.5f; + drawBoxOutline(pos, size); + + //render camera frustum splits as outlines + gGL.begin(LLRender::LINES); + gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[1].mV); + gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[2].mV); + gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[3].mV); + gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[0].mV); + gGL.vertex3fv(frust[4].mV); gGL.vertex3fv(frust[5].mV); + gGL.vertex3fv(frust[5].mV); gGL.vertex3fv(frust[6].mV); + gGL.vertex3fv(frust[6].mV); gGL.vertex3fv(frust[7].mV); + gGL.vertex3fv(frust[7].mV); gGL.vertex3fv(frust[4].mV); + gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); + gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV); + gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV); + gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); + gGL.end(); + } + } + + /*gGL.flush(); + glLineWidth(16-i*2); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++) + { + LLSpatialPartition* part = region->getSpatialPartition(j); + if (part) + { + if (hasRenderType(part->mDrawableType)) + { + part->renderIntersectingBBoxes(&mShadowCamera[i]); + } + } + } + } + gGL.flush(); + glLineWidth(1.f);*/ + } + } - if (bridge) - { - gGL.popMatrix(); - } - } + if (mRenderDebugMask & RENDER_DEBUG_WIND_VECTORS) + { + gAgent.getRegion()->mWind.renderVectors(); + } + + if (mRenderDebugMask & RENDER_DEBUG_COMPOSITION) + { + // Debug composition layers + F32 x, y; + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + if (gAgent.getRegion()) + { + gGL.begin(LLRender::POINTS); + // Draw the composition layer for the region that I'm in. + for (x = 0; x <= 260; x++) + { + for (y = 0; y <= 260; y++) + { + if ((x > 255) || (y > 255)) + { + gGL.color4f(1.f, 0.f, 0.f, 1.f); + } + else + { + gGL.color4f(0.f, 0.f, 1.f, 1.f); + } + F32 z = gAgent.getRegion()->getCompositionXY((S32)x, (S32)y); + z *= 5.f; + z += 50.f; + gGL.vertex3f(x, y, z); + } + } + gGL.end(); + } + } - gGL.popMatrix(); - } + if (mRenderDebugMask & LLPipeline::RENDER_DEBUG_BUILD_QUEUE) + { + U32 count = 0; + U32 size = mGroupQ2.size(); + LLColor4 col; + + LLVertexBuffer::unbind(); + LLGLEnable blend(GL_BLEND); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); + + gGL.pushMatrix(); + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); iter != mGroupQ2.end(); ++iter) + { + LLSpatialGroup* group = *iter; + if (group->isDead()) + { + continue; + } + + LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge(); + + if (bridge && (!bridge->mDrawable || bridge->mDrawable->isDead())) + { + continue; + } + + if (bridge) + { + gGL.pushMatrix(); + gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); + } + + F32 alpha = llclamp((F32) (size-count)/size, 0.f, 1.f); + + + LLVector2 c(1.f-alpha, alpha); + c.normVec(); + + + ++count; + col.set(c.mV[0], c.mV[1], 0, alpha*0.5f+0.5f); + group->drawObjectBox(col); + + if (bridge) + { + gGL.popMatrix(); + } + } + + gGL.popMatrix(); + } - gGL.flush(); - if (LLGLSLShader::sNoFixedFunction) - { - gUIProgram.unbind(); - } + gGL.flush(); + if (LLGLSLShader::sNoFixedFunction) + { + gUIProgram.unbind(); + } } static LLTrace::BlockTimerStatHandle FTM_REBUILD_POOLS("Rebuild Pools"); void LLPipeline::rebuildPools() { - LL_RECORD_BLOCK_TIME(FTM_REBUILD_POOLS); + LL_RECORD_BLOCK_TIME(FTM_REBUILD_POOLS); - assertInitialized(); + assertInitialized(); - S32 max_count = mPools.size(); - pool_set_t::iterator iter1 = mPools.upper_bound(mLastRebuildPool); - while(max_count > 0 && mPools.size() > 0) // && num_rebuilds < MAX_REBUILDS) - { - if (iter1 == mPools.end()) - { - iter1 = mPools.begin(); - } - LLDrawPool* poolp = *iter1; - - if (poolp->isDead()) - { - mPools.erase(iter1++); - removeFromQuickLookup( poolp ); - if (poolp == mLastRebuildPool) - { - mLastRebuildPool = NULL; - } - delete poolp; - } - else - { - mLastRebuildPool = poolp; - iter1++; - } - max_count--; - } + S32 max_count = mPools.size(); + pool_set_t::iterator iter1 = mPools.upper_bound(mLastRebuildPool); + while(max_count > 0 && mPools.size() > 0) // && num_rebuilds < MAX_REBUILDS) + { + if (iter1 == mPools.end()) + { + iter1 = mPools.begin(); + } + LLDrawPool* poolp = *iter1; + + if (poolp->isDead()) + { + mPools.erase(iter1++); + removeFromQuickLookup( poolp ); + if (poolp == mLastRebuildPool) + { + mLastRebuildPool = NULL; + } + delete poolp; + } + else + { + mLastRebuildPool = poolp; + iter1++; + } + max_count--; + } } void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) { - assertInitialized(); - - switch( new_poolp->getType() ) - { - case LLDrawPool::POOL_SIMPLE: - if (mSimplePool) - { - llassert(0); - LL_WARNS() << "Ignoring duplicate simple pool." << LL_ENDL; - } - else - { - mSimplePool = (LLRenderPass*) new_poolp; - } - break; - - case LLDrawPool::POOL_ALPHA_MASK: - if (mAlphaMaskPool) - { - llassert(0); - LL_WARNS() << "Ignoring duplicate alpha mask pool." << LL_ENDL; - break; - } - else - { - mAlphaMaskPool = (LLRenderPass*) new_poolp; - } - break; - - case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK: - if (mFullbrightAlphaMaskPool) - { - llassert(0); - LL_WARNS() << "Ignoring duplicate alpha mask pool." << LL_ENDL; - break; - } - else - { - mFullbrightAlphaMaskPool = (LLRenderPass*) new_poolp; - } - break; - - case LLDrawPool::POOL_GRASS: - if (mGrassPool) - { - llassert(0); - LL_WARNS() << "Ignoring duplicate grass pool." << LL_ENDL; - } - else - { - mGrassPool = (LLRenderPass*) new_poolp; - } - break; - - case LLDrawPool::POOL_FULLBRIGHT: - if (mFullbrightPool) - { - llassert(0); - LL_WARNS() << "Ignoring duplicate simple pool." << LL_ENDL; - } - else - { - mFullbrightPool = (LLRenderPass*) new_poolp; - } - break; - - case LLDrawPool::POOL_INVISIBLE: - if (mInvisiblePool) - { - llassert(0); - LL_WARNS() << "Ignoring duplicate simple pool." << LL_ENDL; - } - else - { - mInvisiblePool = (LLRenderPass*) new_poolp; - } - break; + assertInitialized(); - case LLDrawPool::POOL_GLOW: - if (mGlowPool) - { - llassert(0); - LL_WARNS() << "Ignoring duplicate glow pool." << LL_ENDL; - } - else - { - mGlowPool = (LLRenderPass*) new_poolp; - } - break; - - case LLDrawPool::POOL_TREE: - mTreePools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ; - break; + switch( new_poolp->getType() ) + { + case LLDrawPool::POOL_SIMPLE: + if (mSimplePool) + { + llassert(0); + LL_WARNS() << "Ignoring duplicate simple pool." << LL_ENDL; + } + else + { + mSimplePool = (LLRenderPass*) new_poolp; + } + break; + + case LLDrawPool::POOL_ALPHA_MASK: + if (mAlphaMaskPool) + { + llassert(0); + LL_WARNS() << "Ignoring duplicate alpha mask pool." << LL_ENDL; + break; + } + else + { + mAlphaMaskPool = (LLRenderPass*) new_poolp; + } + break; + + case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK: + if (mFullbrightAlphaMaskPool) + { + llassert(0); + LL_WARNS() << "Ignoring duplicate alpha mask pool." << LL_ENDL; + break; + } + else + { + mFullbrightAlphaMaskPool = (LLRenderPass*) new_poolp; + } + break; + + case LLDrawPool::POOL_GRASS: + if (mGrassPool) + { + llassert(0); + LL_WARNS() << "Ignoring duplicate grass pool." << LL_ENDL; + } + else + { + mGrassPool = (LLRenderPass*) new_poolp; + } + break; + + case LLDrawPool::POOL_FULLBRIGHT: + if (mFullbrightPool) + { + llassert(0); + LL_WARNS() << "Ignoring duplicate simple pool." << LL_ENDL; + } + else + { + mFullbrightPool = (LLRenderPass*) new_poolp; + } + break; + + case LLDrawPool::POOL_INVISIBLE: + if (mInvisiblePool) + { + llassert(0); + LL_WARNS() << "Ignoring duplicate simple pool." << LL_ENDL; + } + else + { + mInvisiblePool = (LLRenderPass*) new_poolp; + } + break; + + case LLDrawPool::POOL_GLOW: + if (mGlowPool) + { + llassert(0); + LL_WARNS() << "Ignoring duplicate glow pool." << LL_ENDL; + } + else + { + mGlowPool = (LLRenderPass*) new_poolp; + } + break; + + case LLDrawPool::POOL_TREE: + mTreePools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ; + break; - case LLDrawPool::POOL_TERRAIN: - mTerrainPools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ; - break; - - case LLDrawPool::POOL_BUMP: - if (mBumpPool) - { - llassert(0); - LL_WARNS() << "Ignoring duplicate bump pool." << LL_ENDL; - } - else - { - mBumpPool = new_poolp; - } - break; - case LLDrawPool::POOL_MATERIALS: - if (mMaterialsPool) - { - llassert(0); - LL_WARNS() << "Ignorning duplicate materials pool." << LL_ENDL; - } - else - { - mMaterialsPool = new_poolp; - } - break; - case LLDrawPool::POOL_ALPHA: - if( mAlphaPool ) - { - llassert(0); - LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Alpha pool" << LL_ENDL; - } - else - { - mAlphaPool = (LLDrawPoolAlpha*) new_poolp; - } - break; - - case LLDrawPool::POOL_AVATAR: - break; // Do nothing - - case LLDrawPool::POOL_SKY: - if( mSkyPool ) - { - llassert(0); - LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Sky pool" << LL_ENDL; - } - else - { - mSkyPool = new_poolp; - } - break; - - case LLDrawPool::POOL_WATER: - if( mWaterPool ) - { - llassert(0); - LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Water pool" << LL_ENDL; - } - else - { - mWaterPool = new_poolp; - } - break; - - case LLDrawPool::POOL_GROUND: - if( mGroundPool ) - { - llassert(0); - LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Ground Pool" << LL_ENDL; - } - else - { - mGroundPool = new_poolp; - } - break; - - case LLDrawPool::POOL_WL_SKY: - if( mWLSkyPool ) - { - llassert(0); - LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate WLSky Pool" << LL_ENDL; - } - else - { - mWLSkyPool = new_poolp; - } - break; - - default: - llassert(0); - LL_WARNS() << "Invalid Pool Type in LLPipeline::addPool()" << LL_ENDL; - break; - } + case LLDrawPool::POOL_TERRAIN: + mTerrainPools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ; + break; + + case LLDrawPool::POOL_BUMP: + if (mBumpPool) + { + llassert(0); + LL_WARNS() << "Ignoring duplicate bump pool." << LL_ENDL; + } + else + { + mBumpPool = new_poolp; + } + break; + case LLDrawPool::POOL_MATERIALS: + if (mMaterialsPool) + { + llassert(0); + LL_WARNS() << "Ignorning duplicate materials pool." << LL_ENDL; + } + else + { + mMaterialsPool = new_poolp; + } + break; + case LLDrawPool::POOL_ALPHA: + if( mAlphaPool ) + { + llassert(0); + LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Alpha pool" << LL_ENDL; + } + else + { + mAlphaPool = (LLDrawPoolAlpha*) new_poolp; + } + break; + + case LLDrawPool::POOL_AVATAR: + break; // Do nothing + + case LLDrawPool::POOL_SKY: + if( mSkyPool ) + { + llassert(0); + LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Sky pool" << LL_ENDL; + } + else + { + mSkyPool = new_poolp; + } + break; + + case LLDrawPool::POOL_WATER: + if( mWaterPool ) + { + llassert(0); + LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Water pool" << LL_ENDL; + } + else + { + mWaterPool = new_poolp; + } + break; + + case LLDrawPool::POOL_GROUND: + if( mGroundPool ) + { + llassert(0); + LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Ground Pool" << LL_ENDL; + } + else + { + mGroundPool = new_poolp; + } + break; + + case LLDrawPool::POOL_WL_SKY: + if( mWLSkyPool ) + { + llassert(0); + LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate WLSky Pool" << LL_ENDL; + } + else + { + mWLSkyPool = new_poolp; + } + break; + + default: + llassert(0); + LL_WARNS() << "Invalid Pool Type in LLPipeline::addPool()" << LL_ENDL; + break; + } } void LLPipeline::removePool( LLDrawPool* poolp ) { - assertInitialized(); - removeFromQuickLookup(poolp); - mPools.erase(poolp); - delete poolp; + assertInitialized(); + removeFromQuickLookup(poolp); + mPools.erase(poolp); + delete poolp; } void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) { - assertInitialized(); - switch( poolp->getType() ) - { - case LLDrawPool::POOL_SIMPLE: - llassert(mSimplePool == poolp); - mSimplePool = NULL; - break; - - case LLDrawPool::POOL_ALPHA_MASK: - llassert(mAlphaMaskPool == poolp); - mAlphaMaskPool = NULL; - break; - - case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK: - llassert(mFullbrightAlphaMaskPool == poolp); - mFullbrightAlphaMaskPool = NULL; - break; - - case LLDrawPool::POOL_GRASS: - llassert(mGrassPool == poolp); - mGrassPool = NULL; - break; - - case LLDrawPool::POOL_FULLBRIGHT: - llassert(mFullbrightPool == poolp); - mFullbrightPool = NULL; - break; - - case LLDrawPool::POOL_INVISIBLE: - llassert(mInvisiblePool == poolp); - mInvisiblePool = NULL; - break; - - case LLDrawPool::POOL_WL_SKY: - llassert(mWLSkyPool == poolp); - mWLSkyPool = NULL; - break; - - case LLDrawPool::POOL_GLOW: - llassert(mGlowPool == poolp); - mGlowPool = NULL; - break; - - case LLDrawPool::POOL_TREE: - #ifdef _DEBUG - { - bool found = mTreePools.erase( (uintptr_t)poolp->getTexture() ); - llassert( found ); - } - #else - mTreePools.erase( (uintptr_t)poolp->getTexture() ); - #endif - break; - - case LLDrawPool::POOL_TERRAIN: - #ifdef _DEBUG - { - bool found = mTerrainPools.erase( (uintptr_t)poolp->getTexture() ); - llassert( found ); - } - #else - mTerrainPools.erase( (uintptr_t)poolp->getTexture() ); - #endif - break; - - case LLDrawPool::POOL_BUMP: - 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; - break; - - case LLDrawPool::POOL_AVATAR: - break; // Do nothing - - case LLDrawPool::POOL_SKY: - llassert( poolp == mSkyPool ); - mSkyPool = NULL; - break; - - case LLDrawPool::POOL_WATER: - llassert( poolp == mWaterPool ); - mWaterPool = NULL; - break; - - case LLDrawPool::POOL_GROUND: - llassert( poolp == mGroundPool ); - mGroundPool = NULL; - break; - - default: - llassert(0); - LL_WARNS() << "Invalid Pool Type in LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << LL_ENDL; - break; - } + assertInitialized(); + switch( poolp->getType() ) + { + case LLDrawPool::POOL_SIMPLE: + llassert(mSimplePool == poolp); + mSimplePool = NULL; + break; + + case LLDrawPool::POOL_ALPHA_MASK: + llassert(mAlphaMaskPool == poolp); + mAlphaMaskPool = NULL; + break; + + case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK: + llassert(mFullbrightAlphaMaskPool == poolp); + mFullbrightAlphaMaskPool = NULL; + break; + + case LLDrawPool::POOL_GRASS: + llassert(mGrassPool == poolp); + mGrassPool = NULL; + break; + + case LLDrawPool::POOL_FULLBRIGHT: + llassert(mFullbrightPool == poolp); + mFullbrightPool = NULL; + break; + + case LLDrawPool::POOL_INVISIBLE: + llassert(mInvisiblePool == poolp); + mInvisiblePool = NULL; + break; + + case LLDrawPool::POOL_WL_SKY: + llassert(mWLSkyPool == poolp); + mWLSkyPool = NULL; + break; + + case LLDrawPool::POOL_GLOW: + llassert(mGlowPool == poolp); + mGlowPool = NULL; + break; + + case LLDrawPool::POOL_TREE: + #ifdef _DEBUG + { + bool found = mTreePools.erase( (uintptr_t)poolp->getTexture() ); + llassert( found ); + } + #else + mTreePools.erase( (uintptr_t)poolp->getTexture() ); + #endif + break; + + case LLDrawPool::POOL_TERRAIN: + #ifdef _DEBUG + { + bool found = mTerrainPools.erase( (uintptr_t)poolp->getTexture() ); + llassert( found ); + } + #else + mTerrainPools.erase( (uintptr_t)poolp->getTexture() ); + #endif + break; + + case LLDrawPool::POOL_BUMP: + 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; + break; + + case LLDrawPool::POOL_AVATAR: + break; // Do nothing + + case LLDrawPool::POOL_SKY: + llassert( poolp == mSkyPool ); + mSkyPool = NULL; + break; + + case LLDrawPool::POOL_WATER: + llassert( poolp == mWaterPool ); + mWaterPool = NULL; + break; + + case LLDrawPool::POOL_GROUND: + llassert( poolp == mGroundPool ); + mGroundPool = NULL; + break; + + default: + llassert(0); + LL_WARNS() << "Invalid Pool Type in LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << LL_ENDL; + break; + } } void LLPipeline::resetDrawOrders() { - assertInitialized(); - // Iterate through all of the draw pools and rebuild them. - for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) - { - LLDrawPool *poolp = *iter; - poolp->resetDrawOrders(); - } + assertInitialized(); + // Iterate through all of the draw pools and rebuild them. + for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) + { + LLDrawPool *poolp = *iter; + poolp->resetDrawOrders(); + } } //============================================================================ @@ -5981,166 +5933,153 @@ void LLPipeline::resetDrawOrders() void LLPipeline::setupAvatarLights(bool for_edit) { - assertInitialized(); + assertInitialized(); LLEnvironment& environment = LLEnvironment::instance(); LLSettingsSky::ptr_t psky = environment.getCurrentSky(); bool sun_up = environment.getIsSunUp(); - if (for_edit) - { - LLColor4 diffuse(1.f, 1.f, 1.f, 0.f); - LLVector4 light_pos_cam(-8.f, 0.25f, 10.f, 0.f); // w==0 => directional light - LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview(); - LLMatrix4 camera_rot(camera_mat.getMat3()); - camera_rot.invert(); - LLVector4 light_pos = light_pos_cam * camera_rot; - - light_pos.normalize(); - - LLLightState* light = gGL.getLight(1); - if (LLPipeline::sRenderDeferred) - { - /*diffuse.mV[0] = powf(diffuse.mV[0], 2.2f); - diffuse.mV[1] = powf(diffuse.mV[1], 2.2f); - diffuse.mV[2] = powf(diffuse.mV[2], 2.2f);*/ - } - - mHWLightColors[1] = diffuse; - - light->setDiffuse(diffuse); - light->setAmbient(LLColor4::black); - light->setSpecular(LLColor4::black); - light->setPosition(light_pos); - light->setConstantAttenuation(1.f); - light->setLinearAttenuation(0.f); - light->setQuadraticAttenuation(0.f); - light->setSpotExponent(0.f); - light->setSpotCutoff(180.f); - } + if (for_edit) + { + LLColor4 diffuse(1.f, 1.f, 1.f, 0.f); + LLVector4 light_pos_cam(-8.f, 0.25f, 10.f, 0.f); // w==0 => directional light + LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview(); + LLMatrix4 camera_rot(camera_mat.getMat3()); + camera_rot.invert(); + LLVector4 light_pos = light_pos_cam * camera_rot; + + light_pos.normalize(); + + LLLightState* light = gGL.getLight(1); + + mHWLightColors[1] = diffuse; + + light->setDiffuse(diffuse); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + light->setPosition(light_pos); + light->setConstantAttenuation(1.f); + light->setLinearAttenuation(0.f); + light->setQuadraticAttenuation(0.f); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); + } else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini) - { + { LLVector3 light_dir = sun_up ? LLVector3(mSunDir) : LLVector3(mMoonDir); - LLVector3 opposite_pos = -light_dir; - LLVector3 orthog_light_pos = light_dir % LLVector3::z_axis; - LLVector4 backlight_pos = LLVector4(lerp(opposite_pos, orthog_light_pos, 0.3f), 0.0f); - backlight_pos.normalize(); - - LLColor4 light_diffuse = sun_up ? mSunDiffuse : mMoonDiffuse; - - LLColor4 backlight_diffuse(1.f - light_diffuse.mV[VRED], 1.f - light_diffuse.mV[VGREEN], 1.f - light_diffuse.mV[VBLUE], 1.f); - F32 max_component = 0.001f; - for (S32 i = 0; i < 3; i++) - { - if (backlight_diffuse.mV[i] > max_component) - { - max_component = backlight_diffuse.mV[i]; - } - } - F32 backlight_mag; - if (LLEnvironment::instance().getIsSunUp()) - { - backlight_mag = BACKLIGHT_DAY_MAGNITUDE_OBJECT; - } - else - { - backlight_mag = BACKLIGHT_NIGHT_MAGNITUDE_OBJECT; - } - backlight_diffuse *= backlight_mag / max_component; - - if (LLPipeline::sRenderDeferred) - { - /*backlight_diffuse.mV[0] = powf(backlight_diffuse.mV[0], 2.2f); - backlight_diffuse.mV[1] = powf(backlight_diffuse.mV[1], 2.2f); - backlight_diffuse.mV[2] = powf(backlight_diffuse.mV[2], 2.2f);*/ - } - - mHWLightColors[1] = backlight_diffuse; - - LLLightState* light = gGL.getLight(1); - - light->setPosition(backlight_pos); - light->setDiffuse(backlight_diffuse); - light->setAmbient(LLColor4::black); - light->setSpecular(LLColor4::black); - light->setConstantAttenuation(1.f); - light->setLinearAttenuation(0.f); - light->setQuadraticAttenuation(0.f); - light->setSpotExponent(0.f); - light->setSpotCutoff(180.f); - } - else - { - LLLightState* light = gGL.getLight(1); + LLVector3 opposite_pos = -light_dir; + LLVector3 orthog_light_pos = light_dir % LLVector3::z_axis; + LLVector4 backlight_pos = LLVector4(lerp(opposite_pos, orthog_light_pos, 0.3f), 0.0f); + backlight_pos.normalize(); + + LLColor4 light_diffuse = sun_up ? mSunDiffuse : mMoonDiffuse; + + LLColor4 backlight_diffuse(1.f - light_diffuse.mV[VRED], 1.f - light_diffuse.mV[VGREEN], 1.f - light_diffuse.mV[VBLUE], 1.f); + F32 max_component = 0.001f; + for (S32 i = 0; i < 3; i++) + { + if (backlight_diffuse.mV[i] > max_component) + { + max_component = backlight_diffuse.mV[i]; + } + } + F32 backlight_mag; + if (LLEnvironment::instance().getIsSunUp()) + { + backlight_mag = BACKLIGHT_DAY_MAGNITUDE_OBJECT; + } + else + { + backlight_mag = BACKLIGHT_NIGHT_MAGNITUDE_OBJECT; + } + backlight_diffuse *= backlight_mag / max_component; + + mHWLightColors[1] = backlight_diffuse; + + LLLightState* light = gGL.getLight(1); + + light->setPosition(backlight_pos); + light->setDiffuse(backlight_diffuse); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + light->setConstantAttenuation(1.f); + light->setLinearAttenuation(0.f); + light->setQuadraticAttenuation(0.f); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); + } + else + { + LLLightState* light = gGL.getLight(1); - mHWLightColors[1] = LLColor4::black; + mHWLightColors[1] = LLColor4::black; - light->setDiffuse(LLColor4::black); - light->setAmbient(LLColor4::black); - light->setSpecular(LLColor4::black); - } + light->setDiffuse(LLColor4::black); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + } } static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_dist) { - F32 inten = light->getLightIntensity(); - if (inten < .001f) - { - return max_dist; - } - F32 radius = light->getLightRadius(); - bool selected = light->isSelected(); - LLVector3 dpos = light->getRenderPosition() - cam_pos; - F32 dist2 = dpos.lengthSquared(); - if (!selected && dist2 > (max_dist + radius)*(max_dist + radius)) - { - return max_dist; - } - F32 dist = (F32) sqrt(dist2); - dist *= 1.f / inten; - dist -= radius; - if (selected) - { - dist -= 10000.f; // selected lights get highest priority - } - if (light->mDrawable.notNull() && light->mDrawable->isState(LLDrawable::ACTIVE)) - { - // moving lights get a little higher priority (too much causes artifacts) - dist -= light->getLightRadius()*0.25f; - } - return dist; + F32 inten = light->getLightIntensity(); + if (inten < .001f) + { + return max_dist; + } + F32 radius = light->getLightRadius(); + bool selected = light->isSelected(); + LLVector3 dpos = light->getRenderPosition() - cam_pos; + F32 dist2 = dpos.lengthSquared(); + if (!selected && dist2 > (max_dist + radius)*(max_dist + radius)) + { + return max_dist; + } + F32 dist = (F32) sqrt(dist2); + dist *= 1.f / inten; + dist -= radius; + if (selected) + { + dist -= 10000.f; // selected lights get highest priority + } + if (light->mDrawable.notNull() && light->mDrawable->isState(LLDrawable::ACTIVE)) + { + // moving lights get a little higher priority (too much causes artifacts) + dist -= light->getLightRadius()*0.25f; + } + return dist; } void LLPipeline::calcNearbyLights(LLCamera& camera) { - assertInitialized(); + assertInitialized(); - if (LLPipeline::sReflectionRender) - { - return; - } + if (LLPipeline::sReflectionRender) + { + return; + } - if (mLightingDetail >= 1) - { - // mNearbyLight (and all light_set_t's) are sorted such that - // begin() == the closest light and rbegin() == the farthest light - const S32 MAX_LOCAL_LIGHTS = 6; -// LLVector3 cam_pos = gAgent.getCameraPositionAgent(); - LLVector3 cam_pos = LLViewerJoystick::getInstance()->getOverrideCamera() ? - camera.getOrigin() : - gAgent.getPositionAgent(); - - F32 max_dist = LIGHT_MAX_RADIUS * 4.f; // ignore enitrely lights > 4 * max light rad - - // UPDATE THE EXISTING NEARBY LIGHTS - light_set_t cur_nearby_lights; - for (light_set_t::iterator iter = mNearbyLights.begin(); - iter != mNearbyLights.end(); iter++) - { - const Light* light = &(*iter); - LLDrawable* drawable = light->drawable; + if (mLightingDetail >= 1) + { + // mNearbyLight (and all light_set_t's) are sorted such that + // begin() == the closest light and rbegin() == the farthest light + const S32 MAX_LOCAL_LIGHTS = 6; +// LLVector3 cam_pos = gAgent.getCameraPositionAgent(); + LLVector3 cam_pos = LLViewerJoystick::getInstance()->getOverrideCamera() ? + camera.getOrigin() : + gAgent.getPositionAgent(); + + F32 max_dist = LIGHT_MAX_RADIUS * 4.f; // ignore enitrely lights > 4 * max light rad + + // UPDATE THE EXISTING NEARBY LIGHTS + light_set_t cur_nearby_lights; + for (light_set_t::iterator iter = mNearbyLights.begin(); + iter != mNearbyLights.end(); iter++) + { + const Light* light = &(*iter); + LLDrawable* drawable = light->drawable; const LLViewerObject *vobj = light->drawable->getVObj(); if(vobj && vobj->getAvatar() && (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList()) @@ -6150,107 +6089,115 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) continue; } - LLVOVolume* volight = drawable->getVOVolume(); - if (!volight || !drawable->isState(LLDrawable::LIGHT)) - { - drawable->clearState(LLDrawable::NEARBY_LIGHT); - continue; - } - if (light->fade <= -LIGHT_FADE_TIME) - { - drawable->clearState(LLDrawable::NEARBY_LIGHT); - continue; - } - if (!sRenderAttachedLights && volight && volight->isAttachment()) - { - drawable->clearState(LLDrawable::NEARBY_LIGHT); - continue; - } - - F32 dist = calc_light_dist(volight, cam_pos, max_dist); - cur_nearby_lights.insert(Light(drawable, dist, light->fade)); - } - mNearbyLights = cur_nearby_lights; - - // FIND NEW LIGHTS THAT ARE IN RANGE - light_set_t new_nearby_lights; - for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); - iter != mLights.end(); ++iter) - { - LLDrawable* drawable = *iter; - LLVOVolume* light = drawable->getVOVolume(); - if (!light || drawable->isState(LLDrawable::NEARBY_LIGHT)) - { - continue; - } - if (light->isHUDAttachment()) - { - continue; // no lighting from HUD objects - } - F32 dist = calc_light_dist(light, cam_pos, max_dist); - if (dist >= max_dist) - { - continue; - } - if (!sRenderAttachedLights && light && light->isAttachment()) - { - continue; - } - new_nearby_lights.insert(Light(drawable, dist, 0.f)); - if (new_nearby_lights.size() > (U32)MAX_LOCAL_LIGHTS) - { - new_nearby_lights.erase(--new_nearby_lights.end()); - const Light& last = *new_nearby_lights.rbegin(); - max_dist = last.dist; - } - } - - // INSERT ANY NEW LIGHTS - for (light_set_t::iterator iter = new_nearby_lights.begin(); - iter != new_nearby_lights.end(); iter++) - { - const Light* light = &(*iter); - if (mNearbyLights.size() < (U32)MAX_LOCAL_LIGHTS) - { - mNearbyLights.insert(*light); - ((LLDrawable*) light->drawable)->setState(LLDrawable::NEARBY_LIGHT); - } - else - { - // crazy cast so that we can overwrite the fade value - // even though gcc enforces sets as const - // (fade value doesn't affect sort so this is safe) - Light* farthest_light = (const_cast<Light*>(&(*(mNearbyLights.rbegin())))); - if (light->dist < farthest_light->dist) - { - if (farthest_light->fade >= 0.f) - { - farthest_light->fade = -(gFrameIntervalSeconds.value()); - } - } - else - { - break; // none of the other lights are closer - } - } - } - - //mark nearby lights not-removable. - for (light_set_t::iterator iter = mNearbyLights.begin(); - iter != mNearbyLights.end(); iter++) - { - const Light* light = &(*iter); - ((LLViewerOctreeEntryData*) light->drawable)->setVisible(); - } - } + LLVOVolume* volight = drawable->getVOVolume(); + if (!volight || !drawable->isState(LLDrawable::LIGHT)) + { + drawable->clearState(LLDrawable::NEARBY_LIGHT); + continue; + } + if (light->fade <= -LIGHT_FADE_TIME) + { + drawable->clearState(LLDrawable::NEARBY_LIGHT); + continue; + } + if (!sRenderAttachedLights && volight && volight->isAttachment()) + { + drawable->clearState(LLDrawable::NEARBY_LIGHT); + continue; + } + + F32 dist = calc_light_dist(volight, cam_pos, max_dist); + cur_nearby_lights.insert(Light(drawable, dist, light->fade)); + } + mNearbyLights = cur_nearby_lights; + + // FIND NEW LIGHTS THAT ARE IN RANGE + light_set_t new_nearby_lights; + for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); + iter != mLights.end(); ++iter) + { + LLDrawable* drawable = *iter; + LLVOVolume* light = drawable->getVOVolume(); + if (!light || drawable->isState(LLDrawable::NEARBY_LIGHT)) + { + continue; + } + if (light->isHUDAttachment()) + { + continue; // no lighting from HUD objects + } + F32 dist = calc_light_dist(light, cam_pos, max_dist); + if (dist >= max_dist) + { + continue; + } + if (!sRenderAttachedLights && light && light->isAttachment()) + { + continue; + } + new_nearby_lights.insert(Light(drawable, dist, 0.f)); + if (new_nearby_lights.size() > (U32)MAX_LOCAL_LIGHTS) + { + new_nearby_lights.erase(--new_nearby_lights.end()); + const Light& last = *new_nearby_lights.rbegin(); + max_dist = last.dist; + } + } + + // INSERT ANY NEW LIGHTS + for (light_set_t::iterator iter = new_nearby_lights.begin(); + iter != new_nearby_lights.end(); iter++) + { + const Light* light = &(*iter); + if (mNearbyLights.size() < (U32)MAX_LOCAL_LIGHTS) + { + mNearbyLights.insert(*light); + ((LLDrawable*) light->drawable)->setState(LLDrawable::NEARBY_LIGHT); + } + else + { + // crazy cast so that we can overwrite the fade value + // even though gcc enforces sets as const + // (fade value doesn't affect sort so this is safe) + Light* farthest_light = (const_cast<Light*>(&(*(mNearbyLights.rbegin())))); + if (light->dist < farthest_light->dist) + { + if (farthest_light->fade >= 0.f) + { + farthest_light->fade = -(gFrameIntervalSeconds.value()); + } + } + else + { + break; // none of the other lights are closer + } + } + } + + //mark nearby lights not-removable. + for (light_set_t::iterator iter = mNearbyLights.begin(); + iter != mNearbyLights.end(); iter++) + { + const Light* light = &(*iter); + ((LLViewerOctreeEntryData*) light->drawable)->setVisible(); + } + } } void LLPipeline::setupHWLights(LLDrawPool* pool) { - assertInitialized(); + assertInitialized(); LLEnvironment& environment = LLEnvironment::instance(); LLSettingsSky::ptr_t psky = environment.getCurrentSky(); + + // Ambient + if (!LLGLSLShader::sNoFixedFunction) + { + gGL.syncMatrices(); + LLColor4 ambient = psky->getTotalAmbient(); + gGL.setAmbientLightColor(ambient); + } // Ambient if (!LLGLSLShader::sNoFixedFunction) @@ -6296,353 +6243,354 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) light->setDiffuse(mSunDiffuse); light->setDiffuseB(mMoonDiffuse); light->setAmbient(LLColor4::black); - light->setSpecular(LLColor4::black); - light->setConstantAttenuation(1.f); - light->setLinearAttenuation(0.f); - light->setQuadraticAttenuation(0.f); - light->setSpotExponent(0.f); - light->setSpotCutoff(180.f); - } - - // Light 1 = Backlight (for avatars) - // (set by enableLightsAvatar) - - S32 cur_light = 2; - - // Nearby lights = LIGHT 2-7 - - mLightMovingMask = 0; - - if (mLightingDetail >= 1) - { - for (light_set_t::iterator iter = mNearbyLights.begin(); - iter != mNearbyLights.end(); ++iter) - { - LLDrawable* drawable = iter->drawable; - LLVOVolume* light = drawable->getVOVolume(); - if (!light) - { - continue; - } - if (drawable->isState(LLDrawable::ACTIVE)) - { - mLightMovingMask |= (1<<cur_light); - } - - LLColor4 light_color = light->getLightColor(); - light_color.mV[3] = 0.0f; - - F32 fade = iter->fade; - if (fade < LIGHT_FADE_TIME) - { - // fade in/out light - if (fade >= 0.f) - { - fade = fade / LIGHT_FADE_TIME; - ((Light*) (&(*iter)))->fade += gFrameIntervalSeconds.value(); - } - else - { - fade = 1.f + fade / LIGHT_FADE_TIME; - ((Light*) (&(*iter)))->fade -= gFrameIntervalSeconds.value(); - } - fade = llclamp(fade,0.f,1.f); - light_color *= fade; - } - - LLVector3 light_pos(light->getRenderPosition()); - LLVector4 light_pos_gl(light_pos, 1.0f); - - F32 light_radius = llmax(light->getLightRadius(), 0.001f); - - F32 x = (3.f * (1.f + light->getLightFalloff())); // why this magic? probably trying to match a historic behavior. - float linatten = x / (light_radius); // % of brightness at radius - - mHWLightColors[cur_light] = light_color; - LLLightState* light_state = gGL.getLight(cur_light); - - light_state->setPosition(light_pos_gl); - light_state->setDiffuse(light_color); - light_state->setAmbient(LLColor4::black); - light_state->setConstantAttenuation(0.f); - if (sRenderDeferred) - { - F32 size = light_radius*1.5f; - light_state->setLinearAttenuation(size); - light_state->setQuadraticAttenuation(light->getLightFalloff()*0.5f+1.f); - } - else - { - light_state->setLinearAttenuation(linatten); - light_state->setQuadraticAttenuation(0.f); - } - - - if (light->isLightSpotlight() // directional (spot-)light - && (LLPipeline::sRenderDeferred || RenderSpotLightsInNondeferred)) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on - { - LLQuaternion quat = light->getRenderRotation(); - LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction - at_axis *= quat; - - light_state->setSpotDirection(at_axis); - light_state->setSpotCutoff(90.f); - light_state->setSpotExponent(2.f); - - LLVector3 spotParams = light->getSpotLightParams(); - - const LLColor4 specular(0.f, 0.f, 0.f, spotParams[2]); - light_state->setSpecular(specular); - } - else // omnidirectional (point) light - { - light_state->setSpotExponent(0.f); - light_state->setSpotCutoff(180.f); - - // we use specular.w = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight - const LLColor4 specular(0.f, 0.f, 1.f, 0.f); - light_state->setSpecular(specular); - } - cur_light++; - if (cur_light >= 8) - { - break; // safety - } - } - } - for ( ; cur_light < 8 ; cur_light++) - { - mHWLightColors[cur_light] = LLColor4::black; - LLLightState* light = gGL.getLight(cur_light); - - light->setDiffuse(LLColor4::black); - light->setAmbient(LLColor4::black); - light->setSpecular(LLColor4::black); - } - if (gAgentAvatarp && - gAgentAvatarp->mSpecialRenderMode == 3) - { - LLColor4 light_color = LLColor4::white; - light_color.mV[3] = 0.0f; - - LLVector3 light_pos(LLViewerCamera::getInstance()->getOrigin()); - LLVector4 light_pos_gl(light_pos, 1.0f); - - F32 light_radius = 16.f; - - F32 x = 3.f; - float linatten = x / (light_radius); // % of brightness at radius - - if (LLPipeline::sRenderDeferred) - { - /*light_color.mV[0] = powf(light_color.mV[0], 2.2f); - light_color.mV[1] = powf(light_color.mV[1], 2.2f); - light_color.mV[2] = powf(light_color.mV[2], 2.2f);*/ - } - - mHWLightColors[2] = light_color; - LLLightState* light = gGL.getLight(2); + light->setSpecular(LLColor4::black); + light->setConstantAttenuation(1.f); + light->setLinearAttenuation(0.f); + light->setQuadraticAttenuation(0.f); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); + } + + // Light 1 = Backlight (for avatars) + // (set by enableLightsAvatar) + + S32 cur_light = 2; + + // Nearby lights = LIGHT 2-7 + + mLightMovingMask = 0; + + if (mLightingDetail >= 1) + { + for (light_set_t::iterator iter = mNearbyLights.begin(); + iter != mNearbyLights.end(); ++iter) + { + LLDrawable* drawable = iter->drawable; + LLVOVolume* light = drawable->getVOVolume(); + if (!light) + { + continue; + } + if (drawable->isState(LLDrawable::ACTIVE)) + { + mLightMovingMask |= (1<<cur_light); + } + + LLColor4 light_color = light->getLightColor(); + light_color.mV[3] = 0.0f; + + F32 fade = iter->fade; + if (fade < LIGHT_FADE_TIME) + { + // fade in/out light + if (fade >= 0.f) + { + fade = fade / LIGHT_FADE_TIME; + ((Light*) (&(*iter)))->fade += gFrameIntervalSeconds.value(); + } + else + { + fade = 1.f + fade / LIGHT_FADE_TIME; + ((Light*) (&(*iter)))->fade -= gFrameIntervalSeconds.value(); + } + fade = llclamp(fade,0.f,1.f); + light_color *= fade; + } + + LLVector3 light_pos(light->getRenderPosition()); + LLVector4 light_pos_gl(light_pos, 1.0f); + + F32 light_radius = llmax(light->getLightRadius(), 0.001f); + + F32 x = (3.f * (1.f + light->getLightFalloff())); // why this magic? probably trying to match a historic behavior. + float linatten = x / (light_radius); // % of brightness at radius + + mHWLightColors[cur_light] = light_color; + LLLightState* light_state = gGL.getLight(cur_light); + + light_state->setPosition(light_pos_gl); + light_state->setDiffuse(light_color); + light_state->setAmbient(LLColor4::black); + light_state->setConstantAttenuation(0.f); + if (sRenderDeferred) + { + F32 size = light_radius*1.5f; + light_state->setLinearAttenuation(size); + light_state->setQuadraticAttenuation(light->getLightFalloff()*0.5f+1.f); + } + else + { + light_state->setLinearAttenuation(linatten); + light_state->setQuadraticAttenuation(0.f); + } + + + if (light->isLightSpotlight() // directional (spot-)light + && (LLPipeline::sRenderDeferred || RenderSpotLightsInNondeferred)) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on + { + LLQuaternion quat = light->getRenderRotation(); + LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction + at_axis *= quat; + + light_state->setSpotDirection(at_axis); + light_state->setSpotCutoff(90.f); + light_state->setSpotExponent(2.f); + + LLVector3 spotParams = light->getSpotLightParams(); + + const LLColor4 specular(0.f, 0.f, 0.f, spotParams[2]); + light_state->setSpecular(specular); + } + else // omnidirectional (point) light + { + light_state->setSpotExponent(0.f); + light_state->setSpotCutoff(180.f); + + // we use specular.w = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight + const LLColor4 specular(0.f, 0.f, 1.f, 0.f); + light_state->setSpecular(specular); + } + cur_light++; + if (cur_light >= 8) + { + break; // safety + } + } + } + for ( ; cur_light < 8 ; cur_light++) + { + mHWLightColors[cur_light] = LLColor4::black; + LLLightState* light = gGL.getLight(cur_light); - light->setPosition(light_pos_gl); - light->setDiffuse(light_color); - light->setAmbient(LLColor4::black); - light->setSpecular(LLColor4::black); - light->setQuadraticAttenuation(0.f); - light->setConstantAttenuation(0.f); - light->setLinearAttenuation(linatten); - light->setSpotExponent(0.f); - light->setSpotCutoff(180.f); - } + light->setDiffuse(LLColor4::black); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + } + if (gAgentAvatarp && + gAgentAvatarp->mSpecialRenderMode == 3) + { + LLColor4 light_color = LLColor4::white; + light_color.mV[3] = 0.0f; + + LLVector3 light_pos(LLViewerCamera::getInstance()->getOrigin()); + LLVector4 light_pos_gl(light_pos, 1.0f); + + F32 light_radius = 16.f; + + F32 x = 3.f; + float linatten = x / (light_radius); // % of brightness at radius + + if (LLPipeline::sRenderDeferred) + { + /*light_color.mV[0] = powf(light_color.mV[0], 2.2f); + light_color.mV[1] = powf(light_color.mV[1], 2.2f); + light_color.mV[2] = powf(light_color.mV[2], 2.2f);*/ + } + + mHWLightColors[2] = light_color; + LLLightState* light = gGL.getLight(2); + + light->setPosition(light_pos_gl); + light->setDiffuse(light_color); + light->setDiffuseB(light_color * 0.25f); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + light->setQuadraticAttenuation(0.f); + light->setConstantAttenuation(0.f); + light->setLinearAttenuation(linatten); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); + } - // Init GL state - if (!LLGLSLShader::sNoFixedFunction) - { - glDisable(GL_LIGHTING); - } + // Init GL state + if (!LLGLSLShader::sNoFixedFunction) + { + glDisable(GL_LIGHTING); + } - for (S32 i = 0; i < 8; ++i) - { - gGL.getLight(i)->disable(); - } - mLightMask = 0; + for (S32 i = 0; i < 8; ++i) + { + gGL.getLight(i)->disable(); + } + mLightMask = 0; } void LLPipeline::enableLights(U32 mask) { - assertInitialized(); - - if (mLightingDetail == 0) - { - mask &= 0xf003; // sun and backlight only (and fullbright bit) - } - if (mLightMask != mask) - { - stop_glerror(); - if (!mLightMask) - { - if (!LLGLSLShader::sNoFixedFunction) - { - glEnable(GL_LIGHTING); - } - } - if (mask) - { - stop_glerror(); - for (S32 i=0; i<8; i++) - { - LLLightState* light = gGL.getLight(i); - if (mask & (1<<i)) - { - light->enable(); - light->setDiffuse(mHWLightColors[i]); - } - else - { - light->disable(); - light->setDiffuse(LLColor4::black); - } - } - stop_glerror(); - } - else - { - if (!LLGLSLShader::sNoFixedFunction) - { - glDisable(GL_LIGHTING); - } - } - mLightMask = mask; - stop_glerror(); + assertInitialized(); - LLColor4 ambient = LLEnvironment::instance().getCurrentSky()->getTotalAmbient(); - gGL.setAmbientLightColor(ambient); - } + if (mLightingDetail == 0) + { + mask &= 0xf003; // sun and backlight only (and fullbright bit) + } + if (mLightMask != mask) + { + stop_glerror(); + if (!mLightMask) + { + if (!LLGLSLShader::sNoFixedFunction) + { + glEnable(GL_LIGHTING); + } + } + if (mask) + { + stop_glerror(); + for (S32 i=0; i<8; i++) + { + LLLightState* light = gGL.getLight(i); + if (mask & (1<<i)) + { + light->enable(); + light->setDiffuse(mHWLightColors[i]); + } + else + { + light->disable(); + light->setDiffuse(LLColor4::black); + } + } + stop_glerror(); + } + else + { + if (!LLGLSLShader::sNoFixedFunction) + { + glDisable(GL_LIGHTING); + } + } + mLightMask = mask; + stop_glerror(); + + LLColor4 ambient = LLEnvironment::instance().getCurrentSky()->getTotalAmbient(); + gGL.setAmbientLightColor(ambient); + } } void LLPipeline::enableLightsStatic() { - assertInitialized(); - U32 mask = 0x01; // Sun - if (mLightingDetail >= 2) - { - mask |= mLightMovingMask; // Hardware moving lights - } - else - { - mask |= 0xff & (~2); // Hardware local lights - } - enableLights(mask); + assertInitialized(); + U32 mask = 0x01; // Sun + if (mLightingDetail >= 2) + { + mask |= mLightMovingMask; // Hardware moving lights + } + else + { + mask |= 0xff & (~2); // Hardware local lights + } + enableLights(mask); } void LLPipeline::enableLightsDynamic() { - assertInitialized(); - U32 mask = 0xff & (~2); // Local lights - enableLights(mask); - - if (isAgentAvatarValid() && getLightingDetail() <= 0) - { - if (gAgentAvatarp->mSpecialRenderMode == 0) // normal - { - gPipeline.enableLightsAvatar(); - } - else if (gAgentAvatarp->mSpecialRenderMode >= 1) // anim preview - { - gPipeline.enableLightsAvatarEdit(LLColor4(0.7f, 0.6f, 0.3f, 1.f)); - } - } + assertInitialized(); + U32 mask = 0xff & (~2); // Local lights + enableLights(mask); + + if (isAgentAvatarValid() && getLightingDetail() <= 0) + { + if (gAgentAvatarp->mSpecialRenderMode == 0) // normal + { + gPipeline.enableLightsAvatar(); + } + else if (gAgentAvatarp->mSpecialRenderMode >= 1) // anim preview + { + gPipeline.enableLightsAvatarEdit(LLColor4(0.7f, 0.6f, 0.3f, 1.f)); + } + } } void LLPipeline::enableLightsAvatar() { - U32 mask = 0xff; // All lights - setupAvatarLights(FALSE); - enableLights(mask); + U32 mask = 0xff; // All lights + setupAvatarLights(FALSE); + enableLights(mask); } void LLPipeline::enableLightsPreview() { - disableLights(); + disableLights(); - if (!LLGLSLShader::sNoFixedFunction) - { - glEnable(GL_LIGHTING); - } - - LLColor4 ambient = PreviewAmbientColor; - gGL.setAmbientLightColor(ambient); - - LLColor4 diffuse0 = PreviewDiffuse0; - LLColor4 specular0 = PreviewSpecular0; - LLColor4 diffuse1 = PreviewDiffuse1; - LLColor4 specular1 = PreviewSpecular1; - LLColor4 diffuse2 = PreviewDiffuse2; - LLColor4 specular2 = PreviewSpecular2; - - LLVector3 dir0 = PreviewDirection0; - LLVector3 dir1 = PreviewDirection1; - LLVector3 dir2 = PreviewDirection2; - - dir0.normVec(); - dir1.normVec(); - dir2.normVec(); - - LLVector4 light_pos(dir0, 0.0f); - - LLLightState* light = gGL.getLight(1); - - light->enable(); - light->setPosition(light_pos); - light->setDiffuse(diffuse0); - light->setAmbient(LLColor4::black); - light->setSpecular(specular0); - light->setSpotExponent(0.f); - light->setSpotCutoff(180.f); - - light_pos = LLVector4(dir1, 0.f); - - light = gGL.getLight(2); - light->enable(); - light->setPosition(light_pos); - light->setDiffuse(diffuse1); - light->setAmbient(LLColor4::black); - light->setSpecular(specular1); - light->setSpotExponent(0.f); - light->setSpotCutoff(180.f); + if (!LLGLSLShader::sNoFixedFunction) + { + glEnable(GL_LIGHTING); + } - light_pos = LLVector4(dir2, 0.f); - light = gGL.getLight(3); - light->enable(); - light->setPosition(light_pos); - light->setDiffuse(diffuse2); - light->setAmbient(LLColor4::black); - light->setSpecular(specular2); - light->setSpotExponent(0.f); - light->setSpotCutoff(180.f); + LLColor4 ambient = PreviewAmbientColor; + gGL.setAmbientLightColor(ambient); + + LLColor4 diffuse0 = PreviewDiffuse0; + LLColor4 specular0 = PreviewSpecular0; + LLColor4 diffuse1 = PreviewDiffuse1; + LLColor4 specular1 = PreviewSpecular1; + LLColor4 diffuse2 = PreviewDiffuse2; + LLColor4 specular2 = PreviewSpecular2; + + LLVector3 dir0 = PreviewDirection0; + LLVector3 dir1 = PreviewDirection1; + LLVector3 dir2 = PreviewDirection2; + + dir0.normVec(); + dir1.normVec(); + dir2.normVec(); + + LLVector4 light_pos(dir0, 0.0f); + + LLLightState* light = gGL.getLight(1); + + light->enable(); + light->setPosition(light_pos); + light->setDiffuse(diffuse0); + light->setAmbient(LLColor4::black); + light->setSpecular(specular0); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); + + light_pos = LLVector4(dir1, 0.f); + + light = gGL.getLight(2); + light->enable(); + light->setPosition(light_pos); + light->setDiffuse(diffuse1); + light->setAmbient(LLColor4::black); + light->setSpecular(specular1); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); + + light_pos = LLVector4(dir2, 0.f); + light = gGL.getLight(3); + light->enable(); + light->setPosition(light_pos); + light->setDiffuse(diffuse2); + light->setAmbient(LLColor4::black); + light->setSpecular(specular2); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); } void LLPipeline::enableLightsAvatarEdit(const LLColor4& color) { - U32 mask = 0x2002; // Avatar backlight only, set ambient - setupAvatarLights(TRUE); - enableLights(mask); + U32 mask = 0x2002; // Avatar backlight only, set ambient + setupAvatarLights(TRUE); + enableLights(mask); - gGL.setAmbientLightColor(color); + gGL.setAmbientLightColor(color); } void LLPipeline::enableLightsFullbright(const LLColor4& color) { - assertInitialized(); - U32 mask = 0x1000; // Non-0 mask, set ambient - enableLights(mask); + assertInitialized(); + U32 mask = 0x1000; // Non-0 mask, set ambient + enableLights(mask); - gGL.setAmbientLightColor(color); + gGL.setAmbientLightColor(color); } void LLPipeline::disableLights() { - enableLights(0); // no lighting (full bright) + enableLights(0); // no lighting (full bright) } //============================================================================ @@ -6655,62 +6603,62 @@ class LLVOLeaf; void LLPipeline::findReferences(LLDrawable *drawablep) { - assertInitialized(); - if (mLights.find(drawablep) != mLights.end()) - { - LL_INFOS() << "In mLights" << LL_ENDL; - } - if (std::find(mMovedList.begin(), mMovedList.end(), drawablep) != mMovedList.end()) - { - LL_INFOS() << "In mMovedList" << LL_ENDL; - } - if (std::find(mShiftList.begin(), mShiftList.end(), drawablep) != mShiftList.end()) - { - LL_INFOS() << "In mShiftList" << LL_ENDL; - } - if (mRetexturedList.find(drawablep) != mRetexturedList.end()) - { - LL_INFOS() << "In mRetexturedList" << LL_ENDL; - } - - if (std::find(mBuildQ1.begin(), mBuildQ1.end(), drawablep) != mBuildQ1.end()) - { - LL_INFOS() << "In mBuildQ1" << LL_ENDL; - } - if (std::find(mBuildQ2.begin(), mBuildQ2.end(), drawablep) != mBuildQ2.end()) - { - LL_INFOS() << "In mBuildQ2" << LL_ENDL; - } + assertInitialized(); + if (mLights.find(drawablep) != mLights.end()) + { + LL_INFOS() << "In mLights" << LL_ENDL; + } + if (std::find(mMovedList.begin(), mMovedList.end(), drawablep) != mMovedList.end()) + { + LL_INFOS() << "In mMovedList" << LL_ENDL; + } + if (std::find(mShiftList.begin(), mShiftList.end(), drawablep) != mShiftList.end()) + { + LL_INFOS() << "In mShiftList" << LL_ENDL; + } + if (mRetexturedList.find(drawablep) != mRetexturedList.end()) + { + LL_INFOS() << "In mRetexturedList" << LL_ENDL; + } + + if (std::find(mBuildQ1.begin(), mBuildQ1.end(), drawablep) != mBuildQ1.end()) + { + LL_INFOS() << "In mBuildQ1" << LL_ENDL; + } + if (std::find(mBuildQ2.begin(), mBuildQ2.end(), drawablep) != mBuildQ2.end()) + { + LL_INFOS() << "In mBuildQ2" << LL_ENDL; + } - S32 count; - - count = gObjectList.findReferences(drawablep); - if (count) - { - LL_INFOS() << "In other drawables: " << count << " references" << LL_ENDL; - } + S32 count; + + count = gObjectList.findReferences(drawablep); + if (count) + { + LL_INFOS() << "In other drawables: " << count << " references" << LL_ENDL; + } } bool LLPipeline::verify() { - bool ok = assertInitialized(); - if (ok) - { - for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) - { - LLDrawPool *poolp = *iter; - if (!poolp->verify()) - { - ok = false; - } - } - } + bool ok = assertInitialized(); + if (ok) + { + for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) + { + LLDrawPool *poolp = *iter; + if (!poolp->verify()) + { + ok = false; + } + } + } - if (!ok) - { - LL_WARNS() << "Pipeline verify failed!" << LL_ENDL; - } - return ok; + if (!ok) + { + LL_WARNS() << "Pipeline verify failed!" << LL_ENDL; + } + return ok; } ////////////////////////////// @@ -6721,89 +6669,89 @@ bool LLPipeline::verify() /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** - * A method to compute a ray-AABB intersection. - * Original code by Andrew Woo, from "Graphics Gems", Academic Press, 1990 - * Optimized code by Pierre Terdiman, 2000 (~20-30% faster on my Celeron 500) - * Epsilon value added by Klaus Hartmann. (discarding it saves a few cycles only) + * A method to compute a ray-AABB intersection. + * Original code by Andrew Woo, from "Graphics Gems", Academic Press, 1990 + * Optimized code by Pierre Terdiman, 2000 (~20-30% faster on my Celeron 500) + * Epsilon value added by Klaus Hartmann. (discarding it saves a few cycles only) * - * Hence this version is faster as well as more robust than the original one. + * Hence this version is faster as well as more robust than the original one. * - * Should work provided: - * 1) the integer representation of 0.0f is 0x00000000 - * 2) the sign bit of the float is the most significant one + * Should work provided: + * 1) the integer representation of 0.0f is 0x00000000 + * 2) the sign bit of the float is the most significant one * - * Report bugs: p.terdiman@codercorner.com + * Report bugs: p.terdiman@codercorner.com * - * \param aabb [in] the axis-aligned bounding box - * \param origin [in] ray origin - * \param dir [in] ray direction - * \param coord [out] impact coordinates - * \return true if ray intersects AABB + * \param aabb [in] the axis-aligned bounding box + * \param origin [in] ray origin + * \param dir [in] ray direction + * \param coord [out] impact coordinates + * \return true if ray intersects AABB */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //#define RAYAABB_EPSILON 0.00001f -#define IR(x) ((U32&)x) +#define IR(x) ((U32&)x) bool LLRayAABB(const LLVector3 ¢er, const LLVector3 &size, const LLVector3& origin, const LLVector3& dir, LLVector3 &coord, F32 epsilon) { - bool Inside = true; - LLVector3 MinB = center - size; - LLVector3 MaxB = center + size; - LLVector3 MaxT; - MaxT.mV[VX]=MaxT.mV[VY]=MaxT.mV[VZ]=-1.0f; + bool Inside = true; + LLVector3 MinB = center - size; + LLVector3 MaxB = center + size; + LLVector3 MaxT; + MaxT.mV[VX]=MaxT.mV[VY]=MaxT.mV[VZ]=-1.0f; - // Find candidate planes. - for(U32 i=0;i<3;i++) - { - if(origin.mV[i] < MinB.mV[i]) - { - coord.mV[i] = MinB.mV[i]; - Inside = false; - - // Calculate T distances to candidate planes - if(IR(dir.mV[i])) MaxT.mV[i] = (MinB.mV[i] - origin.mV[i]) / dir.mV[i]; - } - else if(origin.mV[i] > MaxB.mV[i]) - { - coord.mV[i] = MaxB.mV[i]; - Inside = false; - - // Calculate T distances to candidate planes - if(IR(dir.mV[i])) MaxT.mV[i] = (MaxB.mV[i] - origin.mV[i]) / dir.mV[i]; - } - } + // Find candidate planes. + for(U32 i=0;i<3;i++) + { + if(origin.mV[i] < MinB.mV[i]) + { + coord.mV[i] = MinB.mV[i]; + Inside = false; + + // Calculate T distances to candidate planes + if(IR(dir.mV[i])) MaxT.mV[i] = (MinB.mV[i] - origin.mV[i]) / dir.mV[i]; + } + else if(origin.mV[i] > MaxB.mV[i]) + { + coord.mV[i] = MaxB.mV[i]; + Inside = false; + + // Calculate T distances to candidate planes + if(IR(dir.mV[i])) MaxT.mV[i] = (MaxB.mV[i] - origin.mV[i]) / dir.mV[i]; + } + } - // Ray origin inside bounding box - if(Inside) - { - coord = origin; - return true; - } + // Ray origin inside bounding box + if(Inside) + { + coord = origin; + return true; + } - // Get largest of the maxT's for final choice of intersection - U32 WhichPlane = 0; - if(MaxT.mV[1] > MaxT.mV[WhichPlane]) WhichPlane = 1; - if(MaxT.mV[2] > MaxT.mV[WhichPlane]) WhichPlane = 2; + // Get largest of the maxT's for final choice of intersection + U32 WhichPlane = 0; + if(MaxT.mV[1] > MaxT.mV[WhichPlane]) WhichPlane = 1; + if(MaxT.mV[2] > MaxT.mV[WhichPlane]) WhichPlane = 2; - // Check final candidate actually inside box - if(IR(MaxT.mV[WhichPlane])&0x80000000) return false; + // Check final candidate actually inside box + if(IR(MaxT.mV[WhichPlane])&0x80000000) return false; - for(U32 i=0;i<3;i++) - { - if(i!=WhichPlane) - { - coord.mV[i] = origin.mV[i] + MaxT.mV[WhichPlane] * dir.mV[i]; - if (epsilon > 0) - { - if(coord.mV[i] < MinB.mV[i] - epsilon || coord.mV[i] > MaxB.mV[i] + epsilon) return false; - } - else - { - if(coord.mV[i] < MinB.mV[i] || coord.mV[i] > MaxB.mV[i]) return false; - } - } - } - return true; // ray hits box + for(U32 i=0;i<3;i++) + { + if(i!=WhichPlane) + { + coord.mV[i] = origin.mV[i] + MaxT.mV[WhichPlane] * dir.mV[i]; + if (epsilon > 0) + { + if(coord.mV[i] < MinB.mV[i] - epsilon || coord.mV[i] > MaxB.mV[i] + epsilon) return false; + } + else + { + if(coord.mV[i] < MinB.mV[i] || coord.mV[i] > MaxB.mV[i]) return false; + } + } + } + return true; // ray hits box } ////////////////////////////// @@ -6814,1370 +6762,1368 @@ bool LLRayAABB(const LLVector3 ¢er, const LLVector3 &size, const LLVector3& void LLPipeline::setLight(LLDrawable *drawablep, bool is_light) { - if (drawablep && assertInitialized()) - { - if (is_light) - { - mLights.insert(drawablep); - drawablep->setState(LLDrawable::LIGHT); - } - else - { - drawablep->clearState(LLDrawable::LIGHT); - mLights.erase(drawablep); - } - } + if (drawablep && assertInitialized()) + { + if (is_light) + { + mLights.insert(drawablep); + drawablep->setState(LLDrawable::LIGHT); + } + else + { + drawablep->clearState(LLDrawable::LIGHT); + mLights.erase(drawablep); + } + } } //static void LLPipeline::toggleRenderType(U32 type) { - gPipeline.mRenderTypeEnabled[type] = !gPipeline.mRenderTypeEnabled[type]; - if (type == LLPipeline::RENDER_TYPE_WATER) - { - gPipeline.mRenderTypeEnabled[LLPipeline::RENDER_TYPE_VOIDWATER] = !gPipeline.mRenderTypeEnabled[LLPipeline::RENDER_TYPE_VOIDWATER]; - } + gPipeline.mRenderTypeEnabled[type] = !gPipeline.mRenderTypeEnabled[type]; + if (type == LLPipeline::RENDER_TYPE_WATER) + { + gPipeline.mRenderTypeEnabled[LLPipeline::RENDER_TYPE_VOIDWATER] = !gPipeline.mRenderTypeEnabled[LLPipeline::RENDER_TYPE_VOIDWATER]; + } } //static void LLPipeline::toggleRenderTypeControl(U32 type) { - U32 bit = (1<<type); - if (gPipeline.hasRenderType(type)) - { - LL_INFOS() << "Toggling render type mask " << std::hex << bit << " off" << std::dec << LL_ENDL; - } - else - { - LL_INFOS() << "Toggling render type mask " << std::hex << bit << " on" << std::dec << LL_ENDL; - } - gPipeline.toggleRenderType(type); + U32 bit = (1<<type); + if (gPipeline.hasRenderType(type)) + { + LL_INFOS() << "Toggling render type mask " << std::hex << bit << " off" << std::dec << LL_ENDL; + } + else + { + LL_INFOS() << "Toggling render type mask " << std::hex << bit << " on" << std::dec << LL_ENDL; + } + gPipeline.toggleRenderType(type); } //static bool LLPipeline::hasRenderTypeControl(U32 type) { - return gPipeline.hasRenderType(type); + return gPipeline.hasRenderType(type); } // Allows UI items labeled "Hide foo" instead of "Show foo" //static bool LLPipeline::toggleRenderTypeControlNegated(S32 type) { - return !gPipeline.hasRenderType(type); + return !gPipeline.hasRenderType(type); } //static void LLPipeline::toggleRenderDebug(U64 bit) { - if (gPipeline.hasRenderDebugMask(bit)) - { - LL_INFOS() << "Toggling render debug mask " << std::hex << bit << " off" << std::dec << LL_ENDL; - } - else - { - LL_INFOS() << "Toggling render debug mask " << std::hex << bit << " on" << std::dec << LL_ENDL; - } - gPipeline.mRenderDebugMask ^= bit; + if (gPipeline.hasRenderDebugMask(bit)) + { + LL_INFOS() << "Toggling render debug mask " << std::hex << bit << " off" << std::dec << LL_ENDL; + } + else + { + LL_INFOS() << "Toggling render debug mask " << std::hex << bit << " on" << std::dec << LL_ENDL; + } + gPipeline.mRenderDebugMask ^= bit; } //static bool LLPipeline::toggleRenderDebugControl(U64 bit) { - return gPipeline.hasRenderDebugMask(bit); + return gPipeline.hasRenderDebugMask(bit); } //static void LLPipeline::toggleRenderDebugFeature(U32 bit) { - gPipeline.mRenderDebugFeatureMask ^= bit; + gPipeline.mRenderDebugFeatureMask ^= bit; } //static bool LLPipeline::toggleRenderDebugFeatureControl(U32 bit) { - return gPipeline.hasRenderDebugFeatureMask(bit); + return gPipeline.hasRenderDebugFeatureMask(bit); } void LLPipeline::setRenderDebugFeatureControl(U32 bit, bool value) { - if (value) - { - gPipeline.mRenderDebugFeatureMask |= bit; - } - else - { - gPipeline.mRenderDebugFeatureMask &= !bit; - } + if (value) + { + gPipeline.mRenderDebugFeatureMask |= bit; + } + else + { + gPipeline.mRenderDebugFeatureMask &= !bit; + } } void LLPipeline::pushRenderDebugFeatureMask() { - mRenderDebugFeatureStack.push(mRenderDebugFeatureMask); + mRenderDebugFeatureStack.push(mRenderDebugFeatureMask); } void LLPipeline::popRenderDebugFeatureMask() { - if (mRenderDebugFeatureStack.empty()) - { - LL_ERRS() << "Depleted render feature stack." << LL_ENDL; - } + if (mRenderDebugFeatureStack.empty()) + { + LL_ERRS() << "Depleted render feature stack." << LL_ENDL; + } - mRenderDebugFeatureMask = mRenderDebugFeatureStack.top(); - mRenderDebugFeatureStack.pop(); + mRenderDebugFeatureMask = mRenderDebugFeatureStack.top(); + mRenderDebugFeatureStack.pop(); } // static void LLPipeline::setRenderScriptedBeacons(bool val) { - sRenderScriptedBeacons = val; + sRenderScriptedBeacons = val; } // static void LLPipeline::toggleRenderScriptedBeacons() { - sRenderScriptedBeacons = !sRenderScriptedBeacons; + sRenderScriptedBeacons = !sRenderScriptedBeacons; } // static bool LLPipeline::getRenderScriptedBeacons() { - return sRenderScriptedBeacons; + return sRenderScriptedBeacons; } // static void LLPipeline::setRenderScriptedTouchBeacons(bool val) { - sRenderScriptedTouchBeacons = val; + sRenderScriptedTouchBeacons = val; } // static void LLPipeline::toggleRenderScriptedTouchBeacons() { - sRenderScriptedTouchBeacons = !sRenderScriptedTouchBeacons; + sRenderScriptedTouchBeacons = !sRenderScriptedTouchBeacons; } // static bool LLPipeline::getRenderScriptedTouchBeacons() { - return sRenderScriptedTouchBeacons; + return sRenderScriptedTouchBeacons; } // static void LLPipeline::setRenderMOAPBeacons(bool val) { - sRenderMOAPBeacons = val; + sRenderMOAPBeacons = val; } // static void LLPipeline::toggleRenderMOAPBeacons() { - sRenderMOAPBeacons = !sRenderMOAPBeacons; + sRenderMOAPBeacons = !sRenderMOAPBeacons; } // static bool LLPipeline::getRenderMOAPBeacons() { - return sRenderMOAPBeacons; + return sRenderMOAPBeacons; } // static void LLPipeline::setRenderPhysicalBeacons(bool val) { - sRenderPhysicalBeacons = val; + sRenderPhysicalBeacons = val; } // static void LLPipeline::toggleRenderPhysicalBeacons() { - sRenderPhysicalBeacons = !sRenderPhysicalBeacons; + sRenderPhysicalBeacons = !sRenderPhysicalBeacons; } // static bool LLPipeline::getRenderPhysicalBeacons() { - return sRenderPhysicalBeacons; + return sRenderPhysicalBeacons; } // static void LLPipeline::setRenderParticleBeacons(bool val) { - sRenderParticleBeacons = val; + sRenderParticleBeacons = val; } // static void LLPipeline::toggleRenderParticleBeacons() { - sRenderParticleBeacons = !sRenderParticleBeacons; + sRenderParticleBeacons = !sRenderParticleBeacons; } // static bool LLPipeline::getRenderParticleBeacons() { - return sRenderParticleBeacons; + return sRenderParticleBeacons; } // static void LLPipeline::setRenderSoundBeacons(bool val) { - sRenderSoundBeacons = val; + sRenderSoundBeacons = val; } // static void LLPipeline::toggleRenderSoundBeacons() { - sRenderSoundBeacons = !sRenderSoundBeacons; + sRenderSoundBeacons = !sRenderSoundBeacons; } // static bool LLPipeline::getRenderSoundBeacons() { - return sRenderSoundBeacons; + return sRenderSoundBeacons; } // static void LLPipeline::setRenderBeacons(bool val) { - sRenderBeacons = val; + sRenderBeacons = val; } // static void LLPipeline::toggleRenderBeacons() { - sRenderBeacons = !sRenderBeacons; + sRenderBeacons = !sRenderBeacons; } // static bool LLPipeline::getRenderBeacons() { - return sRenderBeacons; + return sRenderBeacons; } // static void LLPipeline::setRenderHighlights(bool val) { - sRenderHighlight = val; + sRenderHighlight = val; } // static void LLPipeline::toggleRenderHighlights() { - sRenderHighlight = !sRenderHighlight; + sRenderHighlight = !sRenderHighlight; } // static bool LLPipeline::getRenderHighlights() { - return sRenderHighlight; + return sRenderHighlight; } // static void LLPipeline::setRenderHighlightTextureChannel(LLRender::eTexIndex channel) { - sRenderHighlightTextureChannel = channel; + sRenderHighlightTextureChannel = channel; } LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection, - S32* face_hit) + S32* face_hit) { - LLVector4a local_end = end; + LLVector4a local_end = end; - LLVector4a position; + LLVector4a position; - LLDrawable* drawable = NULL; - - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; + LLDrawable* drawable = NULL; - LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_PARTICLE); - if (part && hasRenderType(part->mDrawableType)) - { - LLDrawable* hit = part->lineSegmentIntersect(start, local_end, TRUE, FALSE, face_hit, &position, NULL, NULL, NULL); - if (hit) - { - drawable = hit; - local_end = position; - } - } - } + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + + LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_PARTICLE); + if (part && hasRenderType(part->mDrawableType)) + { + LLDrawable* hit = part->lineSegmentIntersect(start, local_end, TRUE, FALSE, face_hit, &position, NULL, NULL, NULL); + if (hit) + { + drawable = hit; + local_end = position; + } + } + } - LLVOPartGroup* ret = NULL; - if (drawable) - { - //make sure we're returning an LLVOPartGroup - llassert(drawable->getVObj()->getPCode() == LLViewerObject::LL_VO_PART_GROUP); - ret = (LLVOPartGroup*) drawable->getVObj().get(); - } - - if (intersection) - { - *intersection = position; - } + LLVOPartGroup* ret = NULL; + if (drawable) + { + //make sure we're returning an LLVOPartGroup + llassert(drawable->getVObj()->getPCode() == LLViewerObject::LL_VO_PART_GROUP); + ret = (LLVOPartGroup*) drawable->getVObj().get(); + } + + if (intersection) + { + *intersection = position; + } - return ret; + return ret; } LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end, - bool pick_transparent, - bool pick_rigged, - S32* face_hit, - LLVector4a* intersection, // return the intersection point - LLVector2* tex_coord, // return the texture coordinates of the intersection point - LLVector4a* normal, // return the surface normal at the intersection point - LLVector4a* tangent // return the surface tangent at the intersection point - ) + bool pick_transparent, + bool pick_rigged, + S32* face_hit, + LLVector4a* intersection, // return the intersection point + LLVector2* tex_coord, // return the texture coordinates of the intersection point + LLVector4a* normal, // return the surface normal at the intersection point + LLVector4a* tangent // return the surface tangent at the intersection point + ) { - LLDrawable* drawable = NULL; - - LLVector4a local_end = end; - - LLVector4a position; - - sPickAvatar = false; //! LLToolMgr::getInstance()->inBuildMode(); - - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - - for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++) - { - if ((j == LLViewerRegion::PARTITION_VOLUME) || - (j == LLViewerRegion::PARTITION_BRIDGE) || - (j == LLViewerRegion::PARTITION_TERRAIN) || - (j == LLViewerRegion::PARTITION_TREE) || - (j == LLViewerRegion::PARTITION_GRASS)) // only check these partitions for now - { - LLSpatialPartition* part = region->getSpatialPartition(j); - if (part && hasRenderType(part->mDrawableType)) - { - LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, face_hit, &position, tex_coord, normal, tangent); - if (hit) - { - drawable = hit; - local_end = position; - } - } - } - } - } - - if (!sPickAvatar) - { - //save hit info in case we need to restore - //due to attachment override - LLVector4a local_normal; - LLVector4a local_tangent; - LLVector2 local_texcoord; - S32 local_face_hit = -1; - - if (face_hit) - { - local_face_hit = *face_hit; - } - if (tex_coord) - { - local_texcoord = *tex_coord; - } - if (tangent) - { - local_tangent = *tangent; - } - else - { - local_tangent.clear(); - } - if (normal) - { - local_normal = *normal; - } - else - { - local_normal.clear(); - } - - const F32 ATTACHMENT_OVERRIDE_DIST = 0.1f; + LLDrawable* drawable = NULL; - //check against avatars - sPickAvatar = true; - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; + LLVector4a local_end = end; - LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE); - if (part && hasRenderType(part->mDrawableType)) - { - LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, face_hit, &position, tex_coord, normal, tangent); - if (hit) - { - LLVector4a delta; - delta.setSub(position, local_end); - - if (!drawable || - !drawable->getVObj()->isAttachment() || - delta.getLength3().getF32() > ATTACHMENT_OVERRIDE_DIST) - { //avatar overrides if previously hit drawable is not an attachment or - //attachment is far enough away from detected intersection - drawable = hit; - local_end = position; - } - else - { //prioritize attachments over avatars - position = local_end; + LLVector4a position; - if (face_hit) - { - *face_hit = local_face_hit; - } - if (tex_coord) - { - *tex_coord = local_texcoord; - } - if (tangent) - { - *tangent = local_tangent; - } - if (normal) - { - *normal = local_normal; - } - } - } - } - } - } + sPickAvatar = false; //! LLToolMgr::getInstance()->inBuildMode(); + + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + + for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++) + { + if ((j == LLViewerRegion::PARTITION_VOLUME) || + (j == LLViewerRegion::PARTITION_BRIDGE) || + (j == LLViewerRegion::PARTITION_TERRAIN) || + (j == LLViewerRegion::PARTITION_TREE) || + (j == LLViewerRegion::PARTITION_GRASS)) // only check these partitions for now + { + LLSpatialPartition* part = region->getSpatialPartition(j); + if (part && hasRenderType(part->mDrawableType)) + { + LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, face_hit, &position, tex_coord, normal, tangent); + if (hit) + { + drawable = hit; + local_end = position; + } + } + } + } + } + + if (!sPickAvatar) + { + //save hit info in case we need to restore + //due to attachment override + LLVector4a local_normal; + LLVector4a local_tangent; + LLVector2 local_texcoord; + S32 local_face_hit = -1; + + if (face_hit) + { + local_face_hit = *face_hit; + } + if (tex_coord) + { + local_texcoord = *tex_coord; + } + if (tangent) + { + local_tangent = *tangent; + } + else + { + local_tangent.clear(); + } + if (normal) + { + local_normal = *normal; + } + else + { + local_normal.clear(); + } + + const F32 ATTACHMENT_OVERRIDE_DIST = 0.1f; + + //check against avatars + sPickAvatar = true; + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + + LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE); + if (part && hasRenderType(part->mDrawableType)) + { + LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, face_hit, &position, tex_coord, normal, tangent); + if (hit) + { + LLVector4a delta; + delta.setSub(position, local_end); + + if (!drawable || + !drawable->getVObj()->isAttachment() || + delta.getLength3().getF32() > ATTACHMENT_OVERRIDE_DIST) + { //avatar overrides if previously hit drawable is not an attachment or + //attachment is far enough away from detected intersection + drawable = hit; + local_end = position; + } + else + { //prioritize attachments over avatars + position = local_end; + + if (face_hit) + { + *face_hit = local_face_hit; + } + if (tex_coord) + { + *tex_coord = local_texcoord; + } + if (tangent) + { + *tangent = local_tangent; + } + if (normal) + { + *normal = local_normal; + } + } + } + } + } + } - //check all avatar nametags (silly, isn't it?) - for (std::vector< LLCharacter* >::iterator iter = LLCharacter::sInstances.begin(); - iter != LLCharacter::sInstances.end(); - ++iter) - { - LLVOAvatar* av = (LLVOAvatar*) *iter; - if (av->mNameText.notNull() - && av->mNameText->lineSegmentIntersect(start, local_end, position)) - { - drawable = av->mDrawable; - local_end = position; - } - } + //check all avatar nametags (silly, isn't it?) + for (std::vector< LLCharacter* >::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); + ++iter) + { + LLVOAvatar* av = (LLVOAvatar*) *iter; + if (av->mNameText.notNull() + && av->mNameText->lineSegmentIntersect(start, local_end, position)) + { + drawable = av->mDrawable; + local_end = position; + } + } - if (intersection) - { - *intersection = position; - } + if (intersection) + { + *intersection = position; + } - return drawable ? drawable->getVObj().get() : NULL; + return drawable ? drawable->getVObj().get() : NULL; } LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end, - bool pick_transparent, - S32* face_hit, - LLVector4a* intersection, // return the intersection point - LLVector2* tex_coord, // return the texture coordinates of the intersection point - LLVector4a* normal, // return the surface normal at the intersection point - LLVector4a* tangent // return the surface tangent at the intersection point - ) -{ - LLDrawable* drawable = NULL; - - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - - bool toggle = false; - if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD)) - { - toggleRenderType(LLPipeline::RENDER_TYPE_HUD); - toggle = true; - } - - LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD); - if (part) - { - LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, FALSE, face_hit, intersection, tex_coord, normal, tangent); - if (hit) - { - drawable = hit; - } - } - - if (toggle) - { - toggleRenderType(LLPipeline::RENDER_TYPE_HUD); - } - } - return drawable ? drawable->getVObj().get() : NULL; + bool pick_transparent, + S32* face_hit, + LLVector4a* intersection, // return the intersection point + LLVector2* tex_coord, // return the texture coordinates of the intersection point + LLVector4a* normal, // return the surface normal at the intersection point + LLVector4a* tangent // return the surface tangent at the intersection point + ) +{ + LLDrawable* drawable = NULL; + + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + + bool toggle = false; + if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD)) + { + toggleRenderType(LLPipeline::RENDER_TYPE_HUD); + toggle = true; + } + + LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD); + if (part) + { + LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, FALSE, face_hit, intersection, tex_coord, normal, tangent); + if (hit) + { + drawable = hit; + } + } + + if (toggle) + { + toggleRenderType(LLPipeline::RENDER_TYPE_HUD); + } + } + return drawable ? drawable->getVObj().get() : NULL; } LLSpatialPartition* LLPipeline::getSpatialPartition(LLViewerObject* vobj) { - if (vobj) - { - LLViewerRegion* region = vobj->getRegion(); - if (region) - { - return region->getSpatialPartition(vobj->getPartitionType()); - } - } - return NULL; + if (vobj) + { + LLViewerRegion* region = vobj->getRegion(); + if (region) + { + return region->getSpatialPartition(vobj->getPartitionType()); + } + } + return NULL; } void LLPipeline::resetVertexBuffers(LLDrawable* drawable) { - if (!drawable) - { - return; - } + if (!drawable) + { + return; + } - for (S32 i = 0; i < drawable->getNumFaces(); i++) - { - LLFace* facep = drawable->getFace(i); - if (facep) - { - facep->clearVertexBuffer(); - } - } + for (S32 i = 0; i < drawable->getNumFaces(); i++) + { + LLFace* facep = drawable->getFace(i); + if (facep) + { + facep->clearVertexBuffer(); + } + } } void LLPipeline::resetVertexBuffers() -{ - mResetVertexBuffers = true; +{ + mResetVertexBuffers = true; } static LLTrace::BlockTimerStatHandle FTM_RESET_VB("Reset VB"); void LLPipeline::doResetVertexBuffers(bool forced) { - if (!mResetVertexBuffers) - { - return; - } - if(!forced && LLSpatialPartition::sTeleportRequested) - { - if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) - { - return; //wait for teleporting to finish - } - else - { - //teleporting aborted - LLSpatialPartition::sTeleportRequested = FALSE; - mResetVertexBuffers = false; - return; - } - } + if (!mResetVertexBuffers) + { + return; + } + if(!forced && LLSpatialPartition::sTeleportRequested) + { + if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) + { + return; //wait for teleporting to finish + } + else + { + //teleporting aborted + LLSpatialPartition::sTeleportRequested = FALSE; + mResetVertexBuffers = false; + return; + } + } - LL_RECORD_BLOCK_TIME(FTM_RESET_VB); - mResetVertexBuffers = false; + LL_RECORD_BLOCK_TIME(FTM_RESET_VB); + mResetVertexBuffers = false; - mCubeVB = NULL; + mCubeVB = NULL; - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) - { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) - { - part->resetVertexBuffers(); - } - } - } - if(LLSpatialPartition::sTeleportRequested) - { - LLSpatialPartition::sTeleportRequested = FALSE; + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + part->resetVertexBuffers(); + } + } + } + if(LLSpatialPartition::sTeleportRequested) + { + LLSpatialPartition::sTeleportRequested = FALSE; - LLWorld::getInstance()->clearAllVisibleObjects(); - clearRebuildDrawables(); - } + LLWorld::getInstance()->clearAllVisibleObjects(); + clearRebuildDrawables(); + } - resetDrawOrders(); + resetDrawOrders(); - gSky.resetVertexBuffers(); + gSky.resetVertexBuffers(); - LLVOPartGroup::destroyGL(); + LLVOPartGroup::destroyGL(); - if ( LLPathingLib::getInstance() ) - { - LLPathingLib::getInstance()->cleanupVBOManager(); - } - LLVOPartGroup::destroyGL(); + if ( LLPathingLib::getInstance() ) + { + LLPathingLib::getInstance()->cleanupVBOManager(); + } + LLVOPartGroup::destroyGL(); - SUBSYSTEM_CLEANUP(LLVertexBuffer); - - //delete all name pool caches - LLGLNamePool::cleanupPools(); + SUBSYSTEM_CLEANUP(LLVertexBuffer); + + //delete all name pool caches + LLGLNamePool::cleanupPools(); - + - if (LLVertexBuffer::sGLCount > 0) - { - LL_WARNS() << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << LL_ENDL; - } + if (LLVertexBuffer::sGLCount > 0) + { + LL_WARNS() << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << LL_ENDL; + } - LLVertexBuffer::unbind(); - - updateRenderBump(); - updateRenderDeferred(); + LLVertexBuffer::unbind(); + + updateRenderBump(); + updateRenderDeferred(); - sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); - LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO"); - LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO"); - LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw"); - LLVertexBuffer::sEnableVBOs = gSavedSettings.getBOOL("RenderVBOEnable"); - LLVertexBuffer::sDisableVBOMapping = LLVertexBuffer::sEnableVBOs && gSavedSettings.getBOOL("RenderVBOMappingDisable") ; - sBakeSunlight = gSavedSettings.getBOOL("RenderBakeSunlight"); - sNoAlpha = gSavedSettings.getBOOL("RenderNoAlpha"); - LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind"); + sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); + LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO"); + LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO"); + LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw"); + LLVertexBuffer::sEnableVBOs = gSavedSettings.getBOOL("RenderVBOEnable"); + LLVertexBuffer::sDisableVBOMapping = LLVertexBuffer::sEnableVBOs && gSavedSettings.getBOOL("RenderVBOMappingDisable") ; + sBakeSunlight = gSavedSettings.getBOOL("RenderBakeSunlight"); + sNoAlpha = gSavedSettings.getBOOL("RenderNoAlpha"); + LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind"); - LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping); + LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping); - LLVOPartGroup::restoreGL(); + LLVOPartGroup::restoreGL(); } void LLPipeline::renderObjects(U32 type, U32 mask, bool texture, bool batch_texture) { - assertInitialized(); - gGL.loadMatrix(gGLModelView); - gGLLastMatrix = NULL; - mSimplePool->pushBatches(type, mask, texture, batch_texture); - gGL.loadMatrix(gGLModelView); - gGLLastMatrix = NULL; + assertInitialized(); + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + mSimplePool->pushBatches(type, mask, texture, batch_texture); + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; } void LLPipeline::renderMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture) { - assertInitialized(); - gGL.loadMatrix(gGLModelView); - gGLLastMatrix = NULL; - mAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture); - gGL.loadMatrix(gGLModelView); - gGLLastMatrix = NULL; + assertInitialized(); + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + mAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture); + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; } void apply_cube_face_rotation(U32 face) { - switch (face) - { - case 0: - gGL.rotatef(90.f, 0, 1, 0); - gGL.rotatef(180.f, 1, 0, 0); - break; - case 2: - gGL.rotatef(-90.f, 1, 0, 0); - break; - case 4: - gGL.rotatef(180.f, 0, 1, 0); - gGL.rotatef(180.f, 0, 0, 1); - break; - case 1: - gGL.rotatef(-90.f, 0, 1, 0); - gGL.rotatef(180.f, 1, 0, 0); - break; - case 3: - gGL.rotatef(90, 1, 0, 0); - break; - case 5: - gGL.rotatef(180, 0, 0, 1); - break; - } + switch (face) + { + case 0: + gGL.rotatef(90.f, 0, 1, 0); + gGL.rotatef(180.f, 1, 0, 0); + break; + case 2: + gGL.rotatef(-90.f, 1, 0, 0); + break; + case 4: + gGL.rotatef(180.f, 0, 1, 0); + gGL.rotatef(180.f, 0, 0, 1); + break; + case 1: + gGL.rotatef(-90.f, 0, 1, 0); + gGL.rotatef(180.f, 1, 0, 0); + break; + case 3: + gGL.rotatef(90, 1, 0, 0); + break; + case 5: + gGL.rotatef(180, 0, 0, 1); + break; + } } void validate_framebuffer_object() { - GLenum status; - status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT); - switch(status) - { - case GL_FRAMEBUFFER_COMPLETE: - //framebuffer OK, no error. - break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - // frame buffer not OK: probably means unsupported depth buffer format - LL_ERRS() << "Framebuffer Incomplete Missing Attachment." << LL_ENDL; - break; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - // frame buffer not OK: probably means unsupported depth buffer format - LL_ERRS() << "Framebuffer Incomplete Attachment." << LL_ENDL; - break; - case GL_FRAMEBUFFER_UNSUPPORTED: - /* choose different formats */ - LL_ERRS() << "Framebuffer unsupported." << LL_ENDL; - break; - default: - LL_ERRS() << "Unknown framebuffer status." << LL_ENDL; - break; - } + GLenum status; + status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT); + switch(status) + { + case GL_FRAMEBUFFER_COMPLETE: + //framebuffer OK, no error. + break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + // frame buffer not OK: probably means unsupported depth buffer format + LL_ERRS() << "Framebuffer Incomplete Missing Attachment." << LL_ENDL; + break; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + // frame buffer not OK: probably means unsupported depth buffer format + LL_ERRS() << "Framebuffer Incomplete Attachment." << LL_ENDL; + break; + case GL_FRAMEBUFFER_UNSUPPORTED: + /* choose different formats */ + LL_ERRS() << "Framebuffer unsupported." << LL_ENDL; + break; + default: + LL_ERRS() << "Unknown framebuffer status." << LL_ENDL; + break; + } } void LLPipeline::bindScreenToTexture() { - + } static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom"); void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield) { - LLRenderTarget* deferred_light_target = &mDeferredLight; - - if (!(gPipeline.canUseVertexShaders() && - sRenderGlow)) - { - return; - } - - LLVertexBuffer::unbind(); - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - - assertInitialized(); - - if (gUseWireframe) - { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } - - LLVector2 tc1(0,0); - LLVector2 tc2((F32) mScreen.getWidth()*2, - (F32) mScreen.getHeight()*2); - - LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM); - gGL.color4f(1,1,1,1); - LLGLDepthTest depth(GL_FALSE); - LLGLDisable blend(GL_BLEND); - LLGLDisable cull(GL_CULL_FACE); - - enableLightsFullbright(LLColor4(1,1,1,1)); - - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - gGL.loadIdentity(); - - LLGLDisable test(GL_ALPHA_TEST); - - gGL.setColorMask(true, true); - glClearColor(0,0,0,0); - - { - { - LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); - mGlow[2].bindTarget(); - mGlow[2].clear(); - } - - gGlowExtractProgram.bind(); - F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f); - F32 maxAlpha = RenderGlowMaxExtractAlpha; - F32 warmthAmount = RenderGlowWarmthAmount; - LLVector3 lumWeights = RenderGlowLumWeights; - LLVector3 warmthWeights = RenderGlowWarmthWeights; - - - gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum); - gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha); - gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1], lumWeights.mV[2]); - gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1], warmthWeights.mV[2]); - gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount); - LLGLEnable blend_on(GL_BLEND); - LLGLEnable test(GL_ALPHA_TEST); - - gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); - - mScreen.bindTexture(0, 0); - - gGL.color4f(1,1,1,1); - gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(3,-1); - - gGL.end(); - - gGL.getTexUnit(0)->unbind(mScreen.getUsage()); - - mGlow[2].flush(); - } - - tc1.setVec(0,0); - tc2.setVec(2,2); - - // power of two between 1 and 1024 - U32 glowResPow = RenderGlowResolutionPow; - const U32 glow_res = llmax(1, - llmin(1024, 1 << glowResPow)); - - S32 kernel = RenderGlowIterations*2; - F32 delta = RenderGlowWidth / glow_res; - // Use half the glow width if we have the res set to less than 9 so that it looks - // almost the same in either case. - if (glowResPow < 9) - { - delta *= 0.5f; - } - F32 strength = RenderGlowStrength; - - gGlowProgram.bind(); - gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength); - - for (S32 i = 0; i < kernel; i++) - { - { - LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); - mGlow[i%2].bindTarget(); - mGlow[i%2].clear(); - } - - if (i == 0) - { - gGL.getTexUnit(0)->bind(&mGlow[2]); - } - else - { - gGL.getTexUnit(0)->bind(&mGlow[(i-1)%2]); - } - - if (i%2 == 0) - { - gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0); - } - else - { - gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta); - } - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(3,-1); - - gGL.end(); - - mGlow[i%2].flush(); - } - - gGlowProgram.unbind(); - - /*if (LLRenderTarget::sUseFBO) - { - LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - }*/ - - gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; - gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; - gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); - gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); - glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - - tc2.setVec((F32) mScreen.getWidth(), - (F32) mScreen.getHeight()); - - gGL.flush(); - - LLVertexBuffer::unbind(); - - if (LLPipeline::sRenderDeferred) - { - - bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() && - (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && - RenderDepthOfField; - - - bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete(); - - gViewerWindow->setup3DViewport(); - - if (dof_enabled) - { - LLGLSLShader* shader = &gDeferredPostProgram; - LLGLDisable blend(GL_BLEND); - - //depth of field focal plane calculations - static F32 current_distance = 16.f; - static F32 start_distance = 16.f; - static F32 transition_time = 1.f; - - LLVector3 focus_point; - - LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); - if (obj && obj->mDrawable && obj->isSelected()) - { //focus on selected media object - S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); - if (obj && obj->mDrawable) - { - LLFace* face = obj->mDrawable->getFace(face_idx); - if (face) - { - focus_point = face->getPositionAgent(); - } - } - } - - if (focus_point.isExactlyZero()) - { - if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { //focus on point under cursor - focus_point.set(gDebugRaycastIntersection.getF32ptr()); - } - else if (gAgentCamera.cameraMouselook()) - { //focus on point under mouselook crosshairs - LLVector4a result; - result.clear(); - - gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, - NULL, - &result); - - focus_point.set(result.getF32ptr()); - } - else - { - //focus on alt-zoom target - LLViewerRegion* region = gAgent.getRegion(); - if (region) - { - focus_point = LLVector3(gAgentCamera.getFocusGlobal()-region->getOriginGlobal()); - } - } - } - - LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); - F32 target_distance = 16.f; - if (!focus_point.isExactlyZero()) - { - target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point-eye); - } - - if (transition_time >= 1.f && - fabsf(current_distance-target_distance)/current_distance > 0.01f) - { //large shift happened, interpolate smoothly to new target distance - transition_time = 0.f; - start_distance = current_distance; - } - else if (transition_time < 1.f) - { //currently in a transition, continue interpolating - transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds.value(); - transition_time = llmin(transition_time, 1.f); - - F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f; - current_distance = start_distance + (target_distance-start_distance)*t; - } - else - { //small or no change, just snap to target distance - current_distance = target_distance; - } - - //convert to mm - F32 subject_distance = current_distance*1000.f; - F32 fnumber = CameraFNumber; - F32 default_focal_length = CameraFocalLength; - - F32 fov = LLViewerCamera::getInstance()->getView(); - - const F32 default_fov = CameraFieldOfView * F_PI/180.f; - - //F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight(); - - F32 dv = 2.f*default_focal_length * tanf(default_fov/2.f); - - F32 focal_length = dv/(2*tanf(fov/2.f)); - - //F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); - - // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) - // where N = fnumber - // s2 = dot distance - // s1 = subject distance - // f = focal length - // - - F32 blur_constant = focal_length*focal_length/(fnumber*(subject_distance-focal_length)); - blur_constant /= 1000.f; //convert to meters for shader - F32 magnification = focal_length/(subject_distance-focal_length); - - { //build diffuse+bloom+CoF - deferred_light_target->bindTarget(); - shader = &gDeferredCoFProgram; - - bindDeferredShader(*shader); - - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); - if (channel > -1) - { - mScreen.bindTexture(0, channel); - } - - shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance/1000.f); - shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); - shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f/LLDrawable::sCurPixelAngle)); - shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); - shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); - shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(3,-1); - - gGL.end(); - - unbindDeferredShader(*shader); - deferred_light_target->flush(); - } - - U32 dof_width = (U32) (mScreen.getWidth()*CameraDoFResScale); - U32 dof_height = (U32) (mScreen.getHeight()*CameraDoFResScale); - - { //perform DoF sampling at half-res (preserve alpha channel) - mScreen.bindTarget(); - glViewport(0,0, dof_width, dof_height); - gGL.setColorMask(true, false); - - shader = &gDeferredPostProgram; - bindDeferredShader(*shader); - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_light_target->getUsage()); - if (channel > -1) - { - deferred_light_target->bindTexture(0, channel); - } - - shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); - shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(3,-1); - - gGL.end(); - - unbindDeferredShader(*shader); - mScreen.flush(); - gGL.setColorMask(true, true); - } - - { //combine result based on alpha - if (multisample) - { - deferred_light_target->bindTarget(); - glViewport(0, 0, deferred_light_target->getWidth(), deferred_light_target->getHeight()); - } - else - { - gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; - gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; - gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); - gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); - glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - } - - shader = &gDeferredDoFCombineProgram; - bindDeferredShader(*shader); - - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); - if (channel > -1) - { - mScreen.bindTexture(0, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - if (!LLViewerCamera::getInstance()->cameraUnderWater()) - { - shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2); - } else { - shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0); - } - - shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); - shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width-1); - shader->uniform1f(LLShaderMgr::DOF_HEIGHT, dof_height-1); - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(3,-1); - - gGL.end(); - - unbindDeferredShader(*shader); - - if (multisample) - { - deferred_light_target->flush(); - } - } - } - else - { - if (multisample) - { - deferred_light_target->bindTarget(); - } - LLGLSLShader* shader = &gDeferredPostNoDoFProgram; - - bindDeferredShader(*shader); - - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); - if (channel > -1) - { - mScreen.bindTexture(0, channel); - } - - if (!LLViewerCamera::getInstance()->cameraUnderWater()) - { - shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2); - } else { - shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0); - } - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(3,-1); - - gGL.end(); - - unbindDeferredShader(*shader); - - if (multisample) - { - deferred_light_target->flush(); - } - } - - if (multisample) - { - //bake out texture2D with RGBL for FXAA shader - mFXAABuffer.bindTarget(); - - S32 width = mScreen.getWidth(); - S32 height = mScreen.getHeight(); - glViewport(0, 0, width, height); - - LLGLSLShader* shader = &gGlowCombineFXAAProgram; - - shader->bind(); - shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); + if (!(gPipeline.canUseVertexShaders() && + sRenderGlow)) + { + return; + } - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_light_target->getUsage()); - if (channel > -1) - { - deferred_light_target->bindTexture(0, channel); - } - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex2f(-1,-1); - gGL.vertex2f(-1,3); - gGL.vertex2f(3,-1); - gGL.end(); + LLVertexBuffer::unbind(); + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); - gGL.flush(); + assertInitialized(); - shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_light_target->getUsage()); - shader->unbind(); - - mFXAABuffer.flush(); + if (gUseWireframe) + { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } - shader = &gFXAAProgram; - shader->bind(); + LLVector2 tc1(0,0); + LLVector2 tc2((F32) mScreen.getWidth()*2, + (F32) mScreen.getHeight()*2); + + LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM); + gGL.color4f(1,1,1,1); + LLGLDepthTest depth(GL_FALSE); + LLGLDisable blend(GL_BLEND); + LLGLDisable cull(GL_CULL_FACE); + + enableLightsFullbright(LLColor4(1,1,1,1)); + + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + gGL.loadIdentity(); + + LLGLDisable test(GL_ALPHA_TEST); + + gGL.setColorMask(true, true); + glClearColor(0,0,0,0); + + { + { + LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); + mGlow[2].bindTarget(); + mGlow[2].clear(); + } + + gGlowExtractProgram.bind(); + F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f); + F32 maxAlpha = RenderGlowMaxExtractAlpha; + F32 warmthAmount = RenderGlowWarmthAmount; + LLVector3 lumWeights = RenderGlowLumWeights; + LLVector3 warmthWeights = RenderGlowWarmthWeights; + + + gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum); + gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha); + gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1], lumWeights.mV[2]); + gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1], warmthWeights.mV[2]); + gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount); + LLGLEnable blend_on(GL_BLEND); + LLGLEnable test(GL_ALPHA_TEST); + + gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); + + mScreen.bindTexture(0, 0); + + gGL.color4f(1,1,1,1); + gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1,-1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1,3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3,-1); + + gGL.end(); + + gGL.getTexUnit(0)->unbind(mScreen.getUsage()); + + mGlow[2].flush(); + } - channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage()); - if (channel > -1) - { - mFXAABuffer.bindTexture(0, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; - gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; - gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); - gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); - glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - - F32 scale_x = (F32) width/mFXAABuffer.getWidth(); - F32 scale_y = (F32) height/mFXAABuffer.getHeight(); - shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); - shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f/width*scale_x, 1.f/height*scale_y); - shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f/width*scale_x, -0.5f/height*scale_y, 0.5f/width*scale_x, 0.5f/height*scale_y); - shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f/width*scale_x, -2.f/height*scale_y, 2.f/width*scale_x, 2.f/height*scale_y); - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex2f(-1,-1); - gGL.vertex2f(-1,3); - gGL.vertex2f(3,-1); - gGL.end(); - - gGL.flush(); - shader->unbind(); - } - } - else - { - U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1; - LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0); - buff->allocateBuffer(3,0,TRUE); + tc1.setVec(0,0); + tc2.setVec(2,2); - LLStrider<LLVector3> v; - LLStrider<LLVector2> uv1; - LLStrider<LLVector2> uv2; + // power of two between 1 and 1024 + U32 glowResPow = RenderGlowResolutionPow; + const U32 glow_res = llmax(1, + llmin(1024, 1 << glowResPow)); - buff->getVertexStrider(v); - buff->getTexCoord0Strider(uv1); - buff->getTexCoord1Strider(uv2); - - uv1[0] = LLVector2(0, 0); - uv1[1] = LLVector2(0, 2); - uv1[2] = LLVector2(2, 0); - - uv2[0] = LLVector2(0, 0); - uv2[1] = LLVector2(0, tc2.mV[1]*2.f); - uv2[2] = LLVector2(tc2.mV[0]*2.f, 0); - - v[0] = LLVector3(-1,-1,0); - v[1] = LLVector3(-1,3,0); - v[2] = LLVector3(3,-1,0); - - buff->flush(); + S32 kernel = RenderGlowIterations*2; + F32 delta = RenderGlowWidth / glow_res; + // Use half the glow width if we have the res set to less than 9 so that it looks + // almost the same in either case. + if (glowResPow < 9) + { + delta *= 0.5f; + } + F32 strength = RenderGlowStrength; - LLGLDisable blend(GL_BLEND); + gGlowProgram.bind(); + gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength); - if (LLGLSLShader::sNoFixedFunction) - { - gGlowCombineProgram.bind(); - } - else - { - //tex unit 0 - gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR); - //tex unit 1 - gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); - } - - gGL.getTexUnit(0)->bind(&mGlow[1]); - gGL.getTexUnit(1)->bind(&mScreen); - - LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); - - buff->setBuffer(mask); - buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3); - - if (LLGLSLShader::sNoFixedFunction) - { - gGlowCombineProgram.unbind(); - } - else - { - gGL.getTexUnit(1)->disable(); - gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT); + for (S32 i = 0; i < kernel; i++) + { + { + LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); + mGlow[i%2].bindTarget(); + mGlow[i%2].clear(); + } + + if (i == 0) + { + gGL.getTexUnit(0)->bind(&mGlow[2]); + } + else + { + gGL.getTexUnit(0)->bind(&mGlow[(i-1)%2]); + } + + if (i%2 == 0) + { + gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0); + } + else + { + gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta); + } + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1,-1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1,3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3,-1); + + gGL.end(); + + mGlow[i%2].flush(); + } - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); - } - - } + gGlowProgram.unbind(); - gGL.setSceneBlendType(LLRender::BT_ALPHA); + /*if (LLRenderTarget::sUseFBO) + { + LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + }*/ - if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) - { - if (LLGLSLShader::sNoFixedFunction) - { - gSplatTextureRectProgram.bind(); - } + gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - gGL.setColorMask(true, false); + tc2.setVec((F32) mScreen.getWidth(), + (F32) mScreen.getHeight()); - LLVector2 tc1(0,0); - LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw()*2, - (F32) gViewerWindow->getWorldViewHeightRaw()*2); + gGL.flush(); + + LLVertexBuffer::unbind(); - LLGLEnable blend(GL_BLEND); - gGL.color4f(1,1,1,0.75f); + if (LLPipeline::sRenderDeferred) + { - gGL.getTexUnit(0)->bind(&mPhysicsDisplay); + bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() && + (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && + RenderDepthOfField; + + + bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete(); + + gViewerWindow->setup3DViewport(); + + if (dof_enabled) + { + LLGLSLShader* shader = &gDeferredPostProgram; + LLGLDisable blend(GL_BLEND); + + //depth of field focal plane calculations + static F32 current_distance = 16.f; + static F32 start_distance = 16.f; + static F32 transition_time = 1.f; + + LLVector3 focus_point; + + LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); + if (obj && obj->mDrawable && obj->isSelected()) + { //focus on selected media object + S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); + if (obj && obj->mDrawable) + { + LLFace* face = obj->mDrawable->getFace(face_idx); + if (face) + { + focus_point = face->getPositionAgent(); + } + } + } + + if (focus_point.isExactlyZero()) + { + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { //focus on point under cursor + focus_point.set(gDebugRaycastIntersection.getF32ptr()); + } + else if (gAgentCamera.cameraMouselook()) + { //focus on point under mouselook crosshairs + LLVector4a result; + result.clear(); + + gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, + NULL, + &result); + + focus_point.set(result.getF32ptr()); + } + else + { + //focus on alt-zoom target + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + focus_point = LLVector3(gAgentCamera.getFocusGlobal()-region->getOriginGlobal()); + } + } + } + + LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); + F32 target_distance = 16.f; + if (!focus_point.isExactlyZero()) + { + target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point-eye); + } + + if (transition_time >= 1.f && + fabsf(current_distance-target_distance)/current_distance > 0.01f) + { //large shift happened, interpolate smoothly to new target distance + transition_time = 0.f; + start_distance = current_distance; + } + else if (transition_time < 1.f) + { //currently in a transition, continue interpolating + transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds.value(); + transition_time = llmin(transition_time, 1.f); + + F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f; + current_distance = start_distance + (target_distance-start_distance)*t; + } + else + { //small or no change, just snap to target distance + current_distance = target_distance; + } + + //convert to mm + F32 subject_distance = current_distance*1000.f; + F32 fnumber = CameraFNumber; + F32 default_focal_length = CameraFocalLength; + + F32 fov = LLViewerCamera::getInstance()->getView(); + + const F32 default_fov = CameraFieldOfView * F_PI/180.f; + + //F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight(); + + F32 dv = 2.f*default_focal_length * tanf(default_fov/2.f); + + F32 focal_length = dv/(2*tanf(fov/2.f)); + + //F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); + + // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) + // where N = fnumber + // s2 = dot distance + // s1 = subject distance + // f = focal length + // + + F32 blur_constant = focal_length*focal_length/(fnumber*(subject_distance-focal_length)); + blur_constant /= 1000.f; //convert to meters for shader + F32 magnification = focal_length/(subject_distance-focal_length); + + { //build diffuse+bloom+CoF + mDeferredLight.bindTarget(); + shader = &gDeferredCoFProgram; + + bindDeferredShader(*shader); + + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); + if (channel > -1) + { + mScreen.bindTexture(0, channel); + } + + shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance/1000.f); + shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); + shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f/LLDrawable::sCurPixelAngle)); + shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); + shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1,-1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1,3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3,-1); + + gGL.end(); + + unbindDeferredShader(*shader); + mDeferredLight.flush(); + } + + U32 dof_width = (U32) (mScreen.getWidth()*CameraDoFResScale); + U32 dof_height = (U32) (mScreen.getHeight()*CameraDoFResScale); + + { //perform DoF sampling at half-res (preserve alpha channel) + mScreen.bindTarget(); + glViewport(0,0, dof_width, dof_height); + gGL.setColorMask(true, false); + + shader = &gDeferredPostProgram; + bindDeferredShader(*shader); + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); + if (channel > -1) + { + mDeferredLight.bindTexture(0, channel); + } + + shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1,-1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1,3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3,-1); + + gGL.end(); + + unbindDeferredShader(*shader); + mScreen.flush(); + gGL.setColorMask(true, true); + } + + { //combine result based on alpha + if (multisample) + { + mDeferredLight.bindTarget(); + glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); + } + else + { + gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + } + + shader = &gDeferredDoFCombineProgram; + bindDeferredShader(*shader); + + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); + if (channel > -1) + { + mScreen.bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + if (!LLViewerCamera::getInstance()->cameraUnderWater()) + { + shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2); + } else { + shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0); + } + + shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width-1); + shader->uniform1f(LLShaderMgr::DOF_HEIGHT, dof_height-1); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1,-1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1,3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3,-1); + + gGL.end(); + + unbindDeferredShader(*shader); + + if (multisample) + { + mDeferredLight.flush(); + } + } + } + else + { + if (multisample) + { + mDeferredLight.bindTarget(); + } + LLGLSLShader* shader = &gDeferredPostNoDoFProgram; + + bindDeferredShader(*shader); + + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); + if (channel > -1) + { + mScreen.bindTexture(0, channel); + } + + if (!LLViewerCamera::getInstance()->cameraUnderWater()) + { + shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2); + } else { + shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0); + } + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1,-1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1,3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3,-1); + + gGL.end(); + + unbindDeferredShader(*shader); + + if (multisample) + { + mDeferredLight.flush(); + } + } + + if (multisample) + { + //bake out texture2D with RGBL for FXAA shader + mFXAABuffer.bindTarget(); + + S32 width = mScreen.getWidth(); + S32 height = mScreen.getHeight(); + glViewport(0, 0, width, height); + + LLGLSLShader* shader = &gGlowCombineFXAAProgram; + + shader->bind(); + shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); + + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); + if (channel > -1) + { + mDeferredLight.bindTexture(0, channel); + } + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex2f(-1,-1); + gGL.vertex2f(-1,3); + gGL.vertex2f(3,-1); + gGL.end(); + + gGL.flush(); + + shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); + shader->unbind(); + + mFXAABuffer.flush(); + + shader = &gFXAAProgram; + shader->bind(); + + channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage()); + if (channel > -1) + { + mFXAABuffer.bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + + F32 scale_x = (F32) width/mFXAABuffer.getWidth(); + F32 scale_y = (F32) height/mFXAABuffer.getHeight(); + shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); + shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f/width*scale_x, 1.f/height*scale_y); + shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f/width*scale_x, -0.5f/height*scale_y, 0.5f/width*scale_x, 0.5f/height*scale_y); + shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f/width*scale_x, -2.f/height*scale_y, 2.f/width*scale_x, 2.f/height*scale_y); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex2f(-1,-1); + gGL.vertex2f(-1,3); + gGL.vertex2f(3,-1); + gGL.end(); + + gGL.flush(); + shader->unbind(); + } + } + else + { + U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1; + LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0); + buff->allocateBuffer(3,0,TRUE); + + LLStrider<LLVector3> v; + LLStrider<LLVector2> uv1; + LLStrider<LLVector2> uv2; + + buff->getVertexStrider(v); + buff->getTexCoord0Strider(uv1); + buff->getTexCoord1Strider(uv2); + + uv1[0] = LLVector2(0, 0); + uv1[1] = LLVector2(0, 2); + uv1[2] = LLVector2(2, 0); + + uv2[0] = LLVector2(0, 0); + uv2[1] = LLVector2(0, tc2.mV[1]*2.f); + uv2[2] = LLVector2(tc2.mV[0]*2.f, 0); + + v[0] = LLVector3(-1,-1,0); + v[1] = LLVector3(-1,3,0); + v[2] = LLVector3(3,-1,0); + + buff->flush(); + + LLGLDisable blend(GL_BLEND); + + if (LLGLSLShader::sNoFixedFunction) + { + gGlowCombineProgram.bind(); + } + else + { + //tex unit 0 + gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR); + //tex unit 1 + gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); + } + + gGL.getTexUnit(0)->bind(&mGlow[1]); + gGL.getTexUnit(1)->bind(&mScreen); + + LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); + + buff->setBuffer(mask); + buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3); + + if (LLGLSLShader::sNoFixedFunction) + { + gGlowCombineProgram.unbind(); + } + else + { + gGL.getTexUnit(1)->disable(); + gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT); + + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + } + + } - gGL.begin(LLRender::TRIANGLES); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(3,-1); - - gGL.end(); - gGL.flush(); + gGL.setSceneBlendType(LLRender::BT_ALPHA); - if (LLGLSLShader::sNoFixedFunction) - { - gSplatTextureRectProgram.unbind(); - } - } + if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) + { + if (LLGLSLShader::sNoFixedFunction) + { + gSplatTextureRectProgram.bind(); + } + + gGL.setColorMask(true, false); + + LLVector2 tc1(0,0); + LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw()*2, + (F32) gViewerWindow->getWorldViewHeightRaw()*2); + + LLGLEnable blend(GL_BLEND); + gGL.color4f(1,1,1,0.75f); + + gGL.getTexUnit(0)->bind(&mPhysicsDisplay); + + gGL.begin(LLRender::TRIANGLES); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1,-1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1,3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3,-1); + + gGL.end(); + gGL.flush(); + + if (LLGLSLShader::sNoFixedFunction) + { + gSplatTextureRectProgram.unbind(); + } + } - - if (LLRenderTarget::sUseFBO) - { //copy depth buffer from mScreen to framebuffer - LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), - 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); - } - + + if (LLRenderTarget::sUseFBO) + { //copy depth buffer from mScreen to framebuffer + LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), + 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); + } + - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); - LLVertexBuffer::unbind(); + LLVertexBuffer::unbind(); - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); } @@ -8185,7 +8131,7 @@ static LLTrace::BlockTimerStatHandle FTM_BIND_DEFERRED("Bind Deferred"); void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target) { - LL_RECORD_BLOCK_TIME(FTM_BIND_DEFERRED); + LL_RECORD_BLOCK_TIME(FTM_BIND_DEFERRED); LLRenderTarget* deferred_target = &mDeferredScreen; LLRenderTarget* deferred_depth_target = &mDeferredDepth; @@ -8295,60 +8241,62 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ } } - for (U32 i = 4; i < 6; i++) - { - channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i); - stop_glerror(); - if (channel > -1) - { - stop_glerror(); - LLRenderTarget* shadow_target = getShadowTarget(i); - if (shadow_target) - { - gGL.getTexUnit(channel)->bind(shadow_target, TRUE); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - stop_glerror(); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); - stop_glerror(); - } - } - } + for (U32 i = 4; i < 6; i++) + { + channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i); + stop_glerror(); + if (channel > -1) + { + stop_glerror(); + LLRenderTarget* shadow_target = getShadowTarget(i); + if (shadow_target) + { + gGL.getTexUnit(channel)->bind(shadow_target, TRUE); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + stop_glerror(); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); + stop_glerror(); + } + } + } - F32 mat[16*6]; - for (U32 i = 0; i < 16; i++) - { - mat[i] = mSunShadowMatrix[0].m[i]; - mat[i+16] = mSunShadowMatrix[1].m[i]; - mat[i+32] = mSunShadowMatrix[2].m[i]; - mat[i+48] = mSunShadowMatrix[3].m[i]; - mat[i+64] = mSunShadowMatrix[4].m[i]; - mat[i+80] = mSunShadowMatrix[5].m[i]; - } + stop_glerror(); - shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_SHADOW_MATRIX, 6, FALSE, mat); + F32 mat[16*6]; + for (U32 i = 0; i < 16; i++) + { + mat[i] = mSunShadowMatrix[0].m[i]; + mat[i+16] = mSunShadowMatrix[1].m[i]; + mat[i+32] = mSunShadowMatrix[2].m[i]; + mat[i+48] = mSunShadowMatrix[3].m[i]; + mat[i+64] = mSunShadowMatrix[4].m[i]; + mat[i+80] = mSunShadowMatrix[5].m[i]; + } - stop_glerror(); + shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_SHADOW_MATRIX, 6, FALSE, mat); - channel = shader.enableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); - if (channel > -1) - { - LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; - if (cube_map) - { - cube_map->enable(channel); - cube_map->bind(); - F32* m = gGLModelView; - - F32 mat[] = { m[0], m[1], m[2], - m[4], m[5], m[6], - m[8], m[9], m[10] }; - - shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat); - } - } + stop_glerror(); + + channel = shader.enableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); + if (channel > -1) + { + LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; + if (cube_map) + { + cube_map->enable(channel); + cube_map->bind(); + F32* m = gGLModelView; + + F32 mat[] = { m[0], m[1], m[2], + m[4], m[5], m[6], + m[8], m[9], m[10] }; + + shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat); + } + } if (gAtmosphere) { @@ -8434,18 +8382,18 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ LLColor3 pow3f(LLColor3 v, F32 f) { - v.mV[0] = powf(v.mV[0], f); - v.mV[1] = powf(v.mV[1], f); - v.mV[2] = powf(v.mV[2], f); - return v; + v.mV[0] = powf(v.mV[0], f); + v.mV[1] = powf(v.mV[1], f); + v.mV[2] = powf(v.mV[2], f); + return v; } LLVector4 pow4fsrgb(LLVector4 v, F32 f) { - v.mV[0] = powf(v.mV[0], f); - v.mV[1] = powf(v.mV[1], f); - v.mV[2] = powf(v.mV[2], f); - return v; + v.mV[0] = powf(v.mV[0], f); + v.mV[1] = powf(v.mV[1], f); + v.mV[2] = powf(v.mV[2], f); + return v; } static LLTrace::BlockTimerStatHandle FTM_GI_TRACE("Trace"); @@ -9082,147 +9030,146 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget* screen_target) } } - screen_target->flush(); - + screen_target->flush(); } void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) { - //construct frustum - LLVOVolume* volume = drawablep->getVOVolume(); - LLVector3 params = volume->getSpotLightParams(); + //construct frustum + LLVOVolume* volume = drawablep->getVOVolume(); + LLVector3 params = volume->getSpotLightParams(); - F32 fov = params.mV[0]; - F32 focus = params.mV[1]; + F32 fov = params.mV[0]; + F32 focus = params.mV[1]; - LLVector3 pos = drawablep->getPositionAgent(); - LLQuaternion quat = volume->getRenderRotation(); - LLVector3 scale = volume->getScale(); - - //get near clip plane - LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); - at_axis *= quat; - - LLVector3 np = pos+at_axis; - at_axis.normVec(); + LLVector3 pos = drawablep->getPositionAgent(); + LLQuaternion quat = volume->getRenderRotation(); + LLVector3 scale = volume->getScale(); + + //get near clip plane + LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); + at_axis *= quat; - //get origin that has given fov for plane np, at_axis, and given scale - F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); + LLVector3 np = pos+at_axis; + at_axis.normVec(); - LLVector3 origin = np - at_axis*dist; + //get origin that has given fov for plane np, at_axis, and given scale + F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); - //matrix from volume space to agent space - LLMatrix4 light_mat(quat, LLVector4(origin,1.f)); + LLVector3 origin = np - at_axis*dist; - glh::matrix4f light_to_agent((F32*) light_mat.mMatrix); - glh::matrix4f light_to_screen = get_current_modelview() * light_to_agent; + //matrix from volume space to agent space + LLMatrix4 light_mat(quat, LLVector4(origin,1.f)); - glh::matrix4f screen_to_light = light_to_screen.inverse(); + glh::matrix4f light_to_agent((F32*) light_mat.mMatrix); + glh::matrix4f light_to_screen = get_current_modelview() * light_to_agent; - F32 s = volume->getLightRadius()*1.5f; - F32 near_clip = dist; - F32 width = scale.mV[VX]; - F32 height = scale.mV[VY]; - F32 far_clip = s+dist-scale.mV[VZ]; + glh::matrix4f screen_to_light = light_to_screen.inverse(); - F32 fovy = fov * RAD_TO_DEG; - F32 aspect = width/height; + F32 s = volume->getLightRadius()*1.5f; + F32 near_clip = dist; + F32 width = scale.mV[VX]; + F32 height = scale.mV[VY]; + F32 far_clip = s+dist-scale.mV[VZ]; - glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, - 0.f, 0.5f, 0.f, 0.5f, - 0.f, 0.f, 0.5f, 0.5f, - 0.f, 0.f, 0.f, 1.f); + F32 fovy = fov * RAD_TO_DEG; + F32 aspect = width/height; - glh::vec3f p1(0, 0, -(near_clip+0.01f)); - glh::vec3f p2(0, 0, -(near_clip+1.f)); + glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, + 0.f, 0.5f, 0.f, 0.5f, + 0.f, 0.f, 0.5f, 0.5f, + 0.f, 0.f, 0.f, 1.f); - glh::vec3f screen_origin(0, 0, 0); + glh::vec3f p1(0, 0, -(near_clip+0.01f)); + glh::vec3f p2(0, 0, -(near_clip+1.f)); - light_to_screen.mult_matrix_vec(p1); - light_to_screen.mult_matrix_vec(p2); - light_to_screen.mult_matrix_vec(screen_origin); + glh::vec3f screen_origin(0, 0, 0); - glh::vec3f n = p2-p1; - n.normalize(); - - F32 proj_range = far_clip - near_clip; - glh::matrix4f light_proj = gl_perspective(fovy, aspect, near_clip, far_clip); - screen_to_light = trans * light_proj * screen_to_light; - shader.uniformMatrix4fv(LLShaderMgr::PROJECTOR_MATRIX, 1, FALSE, screen_to_light.m); - shader.uniform1f(LLShaderMgr::PROJECTOR_NEAR, near_clip); - shader.uniform3fv(LLShaderMgr::PROJECTOR_P, 1, p1.v); - shader.uniform3fv(LLShaderMgr::PROJECTOR_N, 1, n.v); - shader.uniform3fv(LLShaderMgr::PROJECTOR_ORIGIN, 1, screen_origin.v); - shader.uniform1f(LLShaderMgr::PROJECTOR_RANGE, proj_range); - shader.uniform1f(LLShaderMgr::PROJECTOR_AMBIANCE, params.mV[2]); - S32 s_idx = -1; - - for (U32 i = 0; i < 2; i++) - { - if (mShadowSpotLight[i] == drawablep) - { - s_idx = i; - } - } + light_to_screen.mult_matrix_vec(p1); + light_to_screen.mult_matrix_vec(p2); + light_to_screen.mult_matrix_vec(screen_origin); - shader.uniform1i(LLShaderMgr::PROJECTOR_SHADOW_INDEX, s_idx); + glh::vec3f n = p2-p1; + n.normalize(); + + F32 proj_range = far_clip - near_clip; + glh::matrix4f light_proj = gl_perspective(fovy, aspect, near_clip, far_clip); + screen_to_light = trans * light_proj * screen_to_light; + shader.uniformMatrix4fv(LLShaderMgr::PROJECTOR_MATRIX, 1, FALSE, screen_to_light.m); + shader.uniform1f(LLShaderMgr::PROJECTOR_NEAR, near_clip); + shader.uniform3fv(LLShaderMgr::PROJECTOR_P, 1, p1.v); + shader.uniform3fv(LLShaderMgr::PROJECTOR_N, 1, n.v); + shader.uniform3fv(LLShaderMgr::PROJECTOR_ORIGIN, 1, screen_origin.v); + shader.uniform1f(LLShaderMgr::PROJECTOR_RANGE, proj_range); + shader.uniform1f(LLShaderMgr::PROJECTOR_AMBIANCE, params.mV[2]); + S32 s_idx = -1; - if (s_idx >= 0) - { - shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f-mSpotLightFade[s_idx]); - } - else - { - shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f); - } + for (U32 i = 0; i < 2; i++) + { + if (mShadowSpotLight[i] == drawablep) + { + s_idx = i; + } + } - { - LLDrawable* potential = drawablep; - //determine if this is a good light for casting shadows - F32 m_pri = volume->getSpotLightPriority(); + shader.uniform1i(LLShaderMgr::PROJECTOR_SHADOW_INDEX, s_idx); - for (U32 i = 0; i < 2; i++) - { - F32 pri = 0.f; - - if (mTargetShadowSpotLight[i].notNull()) - { - pri = mTargetShadowSpotLight[i]->getVOVolume()->getSpotLightPriority(); - } + if (s_idx >= 0) + { + shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f-mSpotLightFade[s_idx]); + } + else + { + shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f); + } - if (m_pri > pri) - { - LLDrawable* temp = mTargetShadowSpotLight[i]; - mTargetShadowSpotLight[i] = potential; - potential = temp; - m_pri = pri; - } - } - } + { + LLDrawable* potential = drawablep; + //determine if this is a good light for casting shadows + F32 m_pri = volume->getSpotLightPriority(); + + for (U32 i = 0; i < 2; i++) + { + F32 pri = 0.f; + + if (mTargetShadowSpotLight[i].notNull()) + { + pri = mTargetShadowSpotLight[i]->getVOVolume()->getSpotLightPriority(); + } + + if (m_pri > pri) + { + LLDrawable* temp = mTargetShadowSpotLight[i]; + mTargetShadowSpotLight[i] = potential; + potential = temp; + m_pri = pri; + } + } + } - LLViewerTexture* img = volume->getLightTexture(); + LLViewerTexture* img = volume->getLightTexture(); - if (img == NULL) - { - img = LLViewerFetchedTexture::sWhiteImagep; - } + if (img == NULL) + { + img = LLViewerFetchedTexture::sWhiteImagep; + } - S32 channel = shader.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); + S32 channel = shader.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); - if (channel > -1) - { - if (img) - { - gGL.getTexUnit(channel)->bind(img); + if (channel > -1) + { + if (img) + { + gGL.getTexUnit(channel)->bind(img); - F32 lod_range = logf(img->getWidth())/logf(2.f); + F32 lod_range = logf(img->getWidth())/logf(2.f); - shader.uniform1f(LLShaderMgr::PROJECTOR_FOCUS, focus); - shader.uniform1f(LLShaderMgr::PROJECTOR_LOD, lod_range); - shader.uniform1f(LLShaderMgr::PROJECTOR_AMBIENT_LOD, llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f)); - } - } - + shader.uniform1f(LLShaderMgr::PROJECTOR_FOCUS, focus); + shader.uniform1f(LLShaderMgr::PROJECTOR_LOD, lod_range); + shader.uniform1f(LLShaderMgr::PROJECTOR_AMBIENT_LOD, llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f)); + } + } + } void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) @@ -9555,68 +9502,68 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up) { - glh::matrix4f ret; + glh::matrix4f ret; - LLVector3 dirN; - LLVector3 upN; - LLVector3 lftN; + LLVector3 dirN; + LLVector3 upN; + LLVector3 lftN; - lftN = dir % up; - lftN.normVec(); - - upN = lftN % dir; - upN.normVec(); - - dirN = dir; - dirN.normVec(); + lftN = dir % up; + lftN.normVec(); + + upN = lftN % dir; + upN.normVec(); + + dirN = dir; + dirN.normVec(); - ret.m[ 0] = lftN[0]; - ret.m[ 1] = upN[0]; - ret.m[ 2] = -dirN[0]; - ret.m[ 3] = 0.f; + ret.m[ 0] = lftN[0]; + ret.m[ 1] = upN[0]; + ret.m[ 2] = -dirN[0]; + ret.m[ 3] = 0.f; - ret.m[ 4] = lftN[1]; - ret.m[ 5] = upN[1]; - ret.m[ 6] = -dirN[1]; - ret.m[ 7] = 0.f; + ret.m[ 4] = lftN[1]; + ret.m[ 5] = upN[1]; + ret.m[ 6] = -dirN[1]; + ret.m[ 7] = 0.f; - ret.m[ 8] = lftN[2]; - ret.m[ 9] = upN[2]; - ret.m[10] = -dirN[2]; - ret.m[11] = 0.f; + ret.m[ 8] = lftN[2]; + ret.m[ 9] = upN[2]; + ret.m[10] = -dirN[2]; + ret.m[11] = 0.f; - ret.m[12] = -(lftN*pos); - ret.m[13] = -(upN*pos); - ret.m[14] = dirN*pos; - ret.m[15] = 1.f; + ret.m[12] = -(lftN*pos); + ret.m[13] = -(upN*pos); + ret.m[14] = dirN*pos; + ret.m[15] = 1.f; - return ret; + return ret; } glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max) { - glh::matrix4f ret; - ret.m[ 0] = 2/(max[0]-min[0]); - ret.m[ 4] = 0; - ret.m[ 8] = 0; - ret.m[12] = -(max[0]+min[0])/(max[0]-min[0]); + glh::matrix4f ret; + ret.m[ 0] = 2/(max[0]-min[0]); + ret.m[ 4] = 0; + ret.m[ 8] = 0; + ret.m[12] = -(max[0]+min[0])/(max[0]-min[0]); - ret.m[ 1] = 0; - ret.m[ 5] = 2/(max[1]-min[1]); - ret.m[ 9] = 0; - ret.m[13] = -(max[1]+min[1])/(max[1]-min[1]); + ret.m[ 1] = 0; + ret.m[ 5] = 2/(max[1]-min[1]); + ret.m[ 9] = 0; + ret.m[13] = -(max[1]+min[1])/(max[1]-min[1]); - ret.m[ 2] = 0; - ret.m[ 6] = 0; - ret.m[10] = 2/(max[2]-min[2]); - ret.m[14] = -(max[2]+min[2])/(max[2]-min[2]); + ret.m[ 2] = 0; + ret.m[ 6] = 0; + ret.m[10] = 2/(max[2]-min[2]); + ret.m[14] = -(max[2]+min[2])/(max[2]-min[2]); - ret.m[ 3] = 0; - ret.m[ 7] = 0; - ret.m[11] = 0; - ret.m[15] = 1; + ret.m[ 3] = 0; + ret.m[ 7] = 0; + ret.m[11] = 0; + ret.m[15] = 1; - return ret; + return ret; } static LLTrace::BlockTimerStatHandle FTM_SHADOW_RENDER("Render Shadows"); @@ -9631,61 +9578,61 @@ static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_GRASS("Alpha Grass"); void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult &result, bool use_shader, bool use_occlusion, U32 target_width) { - LL_RECORD_BLOCK_TIME(FTM_SHADOW_RENDER); + LL_RECORD_BLOCK_TIME(FTM_SHADOW_RENDER); - //clip out geometry on the same side of water as the camera - S32 occlude = LLPipeline::sUseOcclusion; - if (!use_occlusion) - { - LLPipeline::sUseOcclusion = 0; - } - LLPipeline::sShadowRender = true; - - static const U32 types[] = { - LLRenderPass::PASS_SIMPLE, - LLRenderPass::PASS_FULLBRIGHT, - LLRenderPass::PASS_SHINY, - LLRenderPass::PASS_BUMP, - LLRenderPass::PASS_FULLBRIGHT_SHINY , - LLRenderPass::PASS_MATERIAL, - LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, - LLRenderPass::PASS_SPECMAP, - LLRenderPass::PASS_SPECMAP_EMISSIVE, - LLRenderPass::PASS_NORMMAP, - LLRenderPass::PASS_NORMMAP_EMISSIVE, - LLRenderPass::PASS_NORMSPEC, - LLRenderPass::PASS_NORMSPEC_EMISSIVE, - }; - - LLGLEnable cull(GL_CULL_FACE); - - //enable depth clamping if available - LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0); + //clip out geometry on the same side of water as the camera + S32 occlude = LLPipeline::sUseOcclusion; + if (!use_occlusion) + { + LLPipeline::sUseOcclusion = 0; + } + LLPipeline::sShadowRender = true; + + static const U32 types[] = { + LLRenderPass::PASS_SIMPLE, + LLRenderPass::PASS_FULLBRIGHT, + LLRenderPass::PASS_SHINY, + LLRenderPass::PASS_BUMP, + LLRenderPass::PASS_FULLBRIGHT_SHINY , + LLRenderPass::PASS_MATERIAL, + LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, + LLRenderPass::PASS_SPECMAP, + LLRenderPass::PASS_SPECMAP_EMISSIVE, + LLRenderPass::PASS_NORMMAP, + LLRenderPass::PASS_NORMMAP_EMISSIVE, + LLRenderPass::PASS_NORMSPEC, + LLRenderPass::PASS_NORMSPEC_EMISSIVE, + }; + + LLGLEnable cull(GL_CULL_FACE); + + //enable depth clamping if available + LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0); + + if (use_shader) + { + gDeferredShadowCubeProgram.bind(); + } - if (use_shader) - { - gDeferredShadowCubeProgram.bind(); - } + LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID-1]; - LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID-1]; + occlusion_target.bindTarget(); + updateCull(shadow_cam, result); + occlusion_target.flush(); - occlusion_target.bindTarget(); - updateCull(shadow_cam, result); - occlusion_target.flush(); + stateSort(shadow_cam, result); + + + //generate shadow map + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadMatrix(proj.m); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + gGL.loadMatrix(view.m); - stateSort(shadow_cam, result); - - - //generate shadow map - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadMatrix(proj.m); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - gGL.loadMatrix(view.m); - - stop_glerror(); - gGLLastMatrix = NULL; + stop_glerror(); + gGLLastMatrix = NULL; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -9819,262 +9766,255 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera static LLTrace::BlockTimerStatHandle FTM_VISIBLE_CLOUD("Visible Cloud"); bool LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir) { - LL_RECORD_BLOCK_TIME(FTM_VISIBLE_CLOUD); - //get point cloud of intersection of frust and min, max - - if (getVisibleExtents(camera, min, max)) - { - return false; - } - - //get set of planes on bounding box - LLPlane bp[] = { - LLPlane(min, LLVector3(-1,0,0)), - LLPlane(min, LLVector3(0,-1,0)), - LLPlane(min, LLVector3(0,0,-1)), - LLPlane(max, LLVector3(1,0,0)), - LLPlane(max, LLVector3(0,1,0)), - LLPlane(max, LLVector3(0,0,1))}; - - //potential points - std::vector<LLVector3> pp; - - //add corners of AABB - pp.push_back(LLVector3(min.mV[0], min.mV[1], min.mV[2])); - pp.push_back(LLVector3(max.mV[0], min.mV[1], min.mV[2])); - pp.push_back(LLVector3(min.mV[0], max.mV[1], min.mV[2])); - pp.push_back(LLVector3(max.mV[0], max.mV[1], min.mV[2])); - pp.push_back(LLVector3(min.mV[0], min.mV[1], max.mV[2])); - pp.push_back(LLVector3(max.mV[0], min.mV[1], max.mV[2])); - pp.push_back(LLVector3(min.mV[0], max.mV[1], max.mV[2])); - pp.push_back(LLVector3(max.mV[0], max.mV[1], max.mV[2])); - - //add corners of camera frustum - for (U32 i = 0; i < LLCamera::AGENT_FRUSTRUM_NUM; i++) - { - pp.push_back(camera.mAgentFrustum[i]); - } - + LL_RECORD_BLOCK_TIME(FTM_VISIBLE_CLOUD); + //get point cloud of intersection of frust and min, max - //bounding box line segments - U32 bs[] = - { - 0,1, - 1,3, - 3,2, - 2,0, - - 4,5, - 5,7, - 7,6, - 6,4, - - 0,4, - 1,5, - 3,7, - 2,6 - }; - - for (U32 i = 0; i < 12; i++) - { //for each line segment in bounding box - for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; j++) - { //for each plane in camera frustum - const LLPlane& cp = camera.getAgentPlane(j); - const LLVector3& v1 = pp[bs[i*2+0]]; - const LLVector3& v2 = pp[bs[i*2+1]]; - LLVector3 n; - cp.getVector3(n); - - LLVector3 line = v1-v2; - - F32 d1 = line*n; - F32 d2 = -cp.dist(v2); - - F32 t = d2/d1; - - if (t > 0.f && t < 1.f) - { - LLVector3 intersect = v2+line*t; - pp.push_back(intersect); - } - } - } - - //camera frustum line segments - const U32 fs[] = - { - 0,1, - 1,2, - 2,3, - 3,0, - - 4,5, - 5,6, - 6,7, - 7,4, - - 0,4, - 1,5, - 2,6, - 3,7 - }; - - for (U32 i = 0; i < 12; i++) - { - for (U32 j = 0; j < 6; ++j) - { - const LLVector3& v1 = pp[fs[i*2+0]+8]; - const LLVector3& v2 = pp[fs[i*2+1]+8]; - const LLPlane& cp = bp[j]; - LLVector3 n; - cp.getVector3(n); - - LLVector3 line = v1-v2; - - F32 d1 = line*n; - F32 d2 = -cp.dist(v2); - - F32 t = d2/d1; + if (getVisibleExtents(camera, min, max)) + { + return false; + } - if (t > 0.f && t < 1.f) - { - LLVector3 intersect = v2+line*t; - pp.push_back(intersect); - } - } - } + //get set of planes on bounding box + LLPlane bp[] = { + LLPlane(min, LLVector3(-1,0,0)), + LLPlane(min, LLVector3(0,-1,0)), + LLPlane(min, LLVector3(0,0,-1)), + LLPlane(max, LLVector3(1,0,0)), + LLPlane(max, LLVector3(0,1,0)), + LLPlane(max, LLVector3(0,0,1))}; + + //potential points + std::vector<LLVector3> pp; + + //add corners of AABB + pp.push_back(LLVector3(min.mV[0], min.mV[1], min.mV[2])); + pp.push_back(LLVector3(max.mV[0], min.mV[1], min.mV[2])); + pp.push_back(LLVector3(min.mV[0], max.mV[1], min.mV[2])); + pp.push_back(LLVector3(max.mV[0], max.mV[1], min.mV[2])); + pp.push_back(LLVector3(min.mV[0], min.mV[1], max.mV[2])); + pp.push_back(LLVector3(max.mV[0], min.mV[1], max.mV[2])); + pp.push_back(LLVector3(min.mV[0], max.mV[1], max.mV[2])); + pp.push_back(LLVector3(max.mV[0], max.mV[1], max.mV[2])); + + //add corners of camera frustum + for (U32 i = 0; i < LLCamera::AGENT_FRUSTRUM_NUM; i++) + { + pp.push_back(camera.mAgentFrustum[i]); + } - LLVector3 ext[] = { min-LLVector3(0.05f,0.05f,0.05f), - max+LLVector3(0.05f,0.05f,0.05f) }; - for (U32 i = 0; i < pp.size(); ++i) - { - bool found = true; + //bounding box line segments + U32 bs[] = + { + 0,1, + 1,3, + 3,2, + 2,0, + + 4,5, + 5,7, + 7,6, + 6,4, + + 0,4, + 1,5, + 3,7, + 2,6 + }; + + for (U32 i = 0; i < 12; i++) + { //for each line segment in bounding box + for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; j++) + { //for each plane in camera frustum + const LLPlane& cp = camera.getAgentPlane(j); + const LLVector3& v1 = pp[bs[i*2+0]]; + const LLVector3& v2 = pp[bs[i*2+1]]; + LLVector3 n; + cp.getVector3(n); + + LLVector3 line = v1-v2; + + F32 d1 = line*n; + F32 d2 = -cp.dist(v2); + + F32 t = d2/d1; + + if (t > 0.f && t < 1.f) + { + LLVector3 intersect = v2+line*t; + pp.push_back(intersect); + } + } + } + + //camera frustum line segments + const U32 fs[] = + { + 0,1, + 1,2, + 2,3, + 3,0, + + 4,5, + 5,6, + 6,7, + 7,4, + + 0,4, + 1,5, + 2,6, + 3,7 + }; + + for (U32 i = 0; i < 12; i++) + { + for (U32 j = 0; j < 6; ++j) + { + const LLVector3& v1 = pp[fs[i*2+0]+8]; + const LLVector3& v2 = pp[fs[i*2+1]+8]; + const LLPlane& cp = bp[j]; + LLVector3 n; + cp.getVector3(n); + + LLVector3 line = v1-v2; + + F32 d1 = line*n; + F32 d2 = -cp.dist(v2); + + F32 t = d2/d1; + + if (t > 0.f && t < 1.f) + { + LLVector3 intersect = v2+line*t; + pp.push_back(intersect); + } + } + } - const F32* p = pp[i].mV; - - for (U32 j = 0; j < 3; ++j) - { - if (p[j] < ext[0].mV[j] || p[j] > ext[1].mV[j]) - { - found = false; - break; - } - } - - if (found) // don't bother testing user clip planes if we're already rejected... - { - for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; ++j) - { - const LLPlane& cp = camera.getAgentPlane(j); - F32 dist = cp.dist(pp[i]); - if (dist > 0.05f) //point is above some plane, not contained - { - found = false; - break; - } - } - } + LLVector3 ext[] = { min-LLVector3(0.05f,0.05f,0.05f), + max+LLVector3(0.05f,0.05f,0.05f) }; - if (found) - { - fp.push_back(pp[i]); - } - } - - if (fp.empty()) - { - return false; - } - - return true; + for (U32 i = 0; i < pp.size(); ++i) + { + bool found = true; + + const F32* p = pp[i].mV; + + for (U32 j = 0; j < 3; ++j) + { + if (p[j] < ext[0].mV[j] || + p[j] > ext[1].mV[j]) + { + found = false; + break; + } + } + + for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; ++j) + { + const LLPlane& cp = camera.getAgentPlane(j); + F32 dist = cp.dist(pp[i]); + if (dist > 0.05f) //point is above some plane, not contained + { + found = false; + break; + } + } + + if (found) + { + fp.push_back(pp[i]); + } + } + + if (fp.empty()) + { + return false; + } + + return true; } void LLPipeline::renderHighlight(const LLViewerObject* obj, F32 fade) { - BOOL shaders = canUseVertexShaders(); - if(shaders) + if (obj && obj->getVolume()) { - gHighlightProgram.bind(); + for (LLViewerObject::child_list_t::const_iterator iter = obj->getChildren().begin(); iter != obj->getChildren().end(); ++iter) + { + renderHighlight(*iter, fade); + } + + LLDrawable* drawable = obj->mDrawable; + if (drawable) + { + for (S32 i = 0; i < drawable->getNumFaces(); ++i) + { + LLFace* face = drawable->getFace(i); + if (face) + { + face->renderSelected(LLViewerTexture::sNullImagep, LLColor4(1,1,1,fade)); + } + } + } } - else - { - gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); - } - - if (obj && obj->getVolume()) - { - for (LLViewerObject::child_list_t::const_iterator iter = obj->getChildren().begin(); iter != obj->getChildren().end(); ++iter) - { - renderHighlight(*iter, fade); - } - - LLDrawable* drawable = obj->mDrawable; - if (drawable) - { - for (S32 i = 0; i < drawable->getNumFaces(); ++i) - { - LLFace* face = drawable->getFace(i); - if (face) - { - face->renderSelected(LLViewerTexture::sNullImagep, LLColor4(1,1,1,fade)); - } - } - } - } } void LLPipeline::generateHighlight(LLCamera& camera) { - //render highlighted object as white into offscreen render target - if (mHighlightObject.notNull()) - { - mHighlightSet.insert(HighlightItem(mHighlightObject)); - } - - if (!mHighlightSet.empty()) - { - F32 transition = gFrameIntervalSeconds.value()/RenderHighlightFadeTime; + //render highlighted object as white into offscreen render target + if (mHighlightObject.notNull()) + { + mHighlightSet.insert(HighlightItem(mHighlightObject)); + } + + if (!mHighlightSet.empty()) + { + F32 transition = gFrameIntervalSeconds.value()/RenderHighlightFadeTime; - LLGLDisable test(GL_ALPHA_TEST); - LLGLDepthTest depth(GL_FALSE); - mHighlight.bindTarget(); - disableLights(); - gGL.setColorMask(true, true); - mHighlight.clear(); + LLGLDisable test(GL_ALPHA_TEST); + LLGLDepthTest depth(GL_FALSE); + mHighlight.bindTarget(); + disableLights(); + gGL.setColorMask(true, true); + mHighlight.clear(); - gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); - for (std::set<HighlightItem>::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); ) + if (LLGLSLShader::sNoFixedFunction) { - std::set<HighlightItem>::iterator cur_iter = iter++; - - if (cur_iter->mItem.isNull()) - { - mHighlightSet.erase(cur_iter); - continue; - } - - if (cur_iter->mItem == mHighlightObject) - { - cur_iter->incrFade(transition); - } - else - { - cur_iter->incrFade(-transition); - if (cur_iter->mFade <= 0.f) - { - mHighlightSet.erase(cur_iter); - continue; - } - } - - renderHighlight(cur_iter->mItem->getVObj(), cur_iter->mFade); - } - - mHighlight.flush(); - gGL.setColorMask(true, false); - gViewerWindow->setup3DViewport(); - } + gHighlightProgram.bind(); + } + + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); + for (std::set<HighlightItem>::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); ) + { + std::set<HighlightItem>::iterator cur_iter = iter++; + + if (cur_iter->mItem.isNull()) + { + mHighlightSet.erase(cur_iter); + continue; + } + + if (cur_iter->mItem == mHighlightObject) + { + cur_iter->incrFade(transition); + } + else + { + cur_iter->incrFade(-transition); + if (cur_iter->mFade <= 0.f) + { + mHighlightSet.erase(cur_iter); + continue; + } + } + + renderHighlight(cur_iter->mItem->getVObj(), cur_iter->mFade); + } + + mHighlight.flush(); + gGL.setColorMask(true, false); + gViewerWindow->setup3DViewport(); + } } LLRenderTarget* LLPipeline::getShadowTarget(U32 i) @@ -10931,17 +10871,17 @@ void LLPipeline::generateSunShadow(LLCamera& camera) void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture) { - for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) - { - LLSpatialGroup* group = *i; - if (!group->isDead() && - (!sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && - gPipeline.hasRenderType(group->getSpatialPartition()->mDrawableType) && - group->mDrawMap.find(type) != group->mDrawMap.end()) - { - pass->renderGroup(group,type,mask,texture); - } - } + for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) + { + LLSpatialGroup* group = *i; + if (!group->isDead() && + (!sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && + gPipeline.hasRenderType(group->getSpatialPartition()->mDrawableType) && + group->mDrawMap.find(type) != group->mDrawMap.end()) + { + pass->renderGroup(group,type,mask,texture); + } + } } static LLTrace::BlockTimerStatHandle FTM_IMPOSTOR_MARK_VISIBLE("Impostor Mark Visible"); @@ -10952,364 +10892,364 @@ static LLTrace::BlockTimerStatHandle FTM_IMPOSTOR_RESIZE("Impostor Resize"); void LLPipeline::generateImpostor(LLVOAvatar* avatar) { - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); - static LLCullResult result; - result.clear(); - grabReferences(result); - - if (!avatar || !avatar->mDrawable) - { + static LLCullResult result; + result.clear(); + grabReferences(result); + + if (!avatar || !avatar->mDrawable) + { LL_WARNS_ONCE("AvatarRenderPipeline") << "Avatar is " << (avatar ? "not drawable" : "null") << LL_ENDL; - return; - } + return; + } LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID() << " is drawable" << LL_ENDL; - assertInitialized(); + assertInitialized(); - bool visually_muted = avatar->isVisuallyMuted(); + bool visually_muted = avatar->isVisuallyMuted(); LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID() << " is " << ( visually_muted ? "" : "not ") << "visually muted" << LL_ENDL; - bool too_complex = avatar->isTooComplex(); + bool too_complex = avatar->isTooComplex(); LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID() << " is " << ( too_complex ? "" : "not ") << "too complex" << LL_ENDL; - pushRenderTypeMask(); - - if (visually_muted || too_complex) - { - andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); - } - else - { - andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, - LLPipeline::RENDER_TYPE_FULLBRIGHT, - LLPipeline::RENDER_TYPE_VOLUME, - LLPipeline::RENDER_TYPE_GLOW, - LLPipeline::RENDER_TYPE_BUMP, - LLPipeline::RENDER_TYPE_PASS_SIMPLE, - LLPipeline::RENDER_TYPE_PASS_ALPHA, - LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, - LLPipeline::RENDER_TYPE_PASS_BUMP, - LLPipeline::RENDER_TYPE_PASS_POST_BUMP, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, - LLPipeline::RENDER_TYPE_PASS_GLOW, - LLPipeline::RENDER_TYPE_PASS_GRASS, - LLPipeline::RENDER_TYPE_PASS_SHINY, - LLPipeline::RENDER_TYPE_PASS_INVISIBLE, - LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, - LLPipeline::RENDER_TYPE_AVATAR, - LLPipeline::RENDER_TYPE_ALPHA_MASK, - LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, - LLPipeline::RENDER_TYPE_INVISIBLE, - LLPipeline::RENDER_TYPE_SIMPLE, - END_RENDER_TYPES); - } - - S32 occlusion = sUseOcclusion; - sUseOcclusion = 0; - - sReflectionRender = ! sRenderDeferred; - - sShadowRender = true; - sImpostorRender = true; - - LLViewerCamera* viewer_camera = LLViewerCamera::getInstance(); - - { - LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_MARK_VISIBLE); - markVisible(avatar->mDrawable, *viewer_camera); - LLVOAvatar::sUseImpostors = false; // @TODO ??? - - LLVOAvatar::attachment_map_t::iterator iter; - for (iter = avatar->mAttachmentPoints.begin(); - iter != avatar->mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment *attachment = iter->second; - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - if (LLViewerObject* attached_object = (*attachment_iter)) - { - markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera); - } - } - } - } - - stateSort(*LLViewerCamera::getInstance(), result); - - LLCamera camera = *viewer_camera; - LLVector2 tdim; - U32 resY = 0; - U32 resX = 0; - - { - LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_SETUP); - const LLVector4a* ext = avatar->mDrawable->getSpatialExtents(); - LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); - - camera.lookAt(viewer_camera->getOrigin(), pos, viewer_camera->getUpAxis()); - - LLVector4a half_height; - half_height.setSub(ext[1], ext[0]); - half_height.mul(0.5f); - - LLVector4a left; - left.load3(camera.getLeftAxis().mV); - left.mul(left); - llassert(left.dot3(left).getF32() > F_APPROXIMATELY_ZERO); - left.normalize3fast(); - - LLVector4a up; - up.load3(camera.getUpAxis().mV); - up.mul(up); - llassert(up.dot3(up).getF32() > F_APPROXIMATELY_ZERO); - up.normalize3fast(); - - tdim.mV[0] = fabsf(half_height.dot3(left).getF32()); - tdim.mV[1] = fabsf(half_height.dot3(up).getF32()); - - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - - F32 distance = (pos-camera.getOrigin()).length(); - F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG; - F32 aspect = tdim.mV[0]/tdim.mV[1]; - glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f); - set_current_projection(persp); - gGL.loadMatrix(persp.m); - - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - glh::matrix4f mat; - camera.getOpenGLTransform(mat.m); - - mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat; + pushRenderTypeMask(); + + if (visually_muted || too_complex) + { + andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); + } + else + { + andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, + LLPipeline::RENDER_TYPE_FULLBRIGHT, + LLPipeline::RENDER_TYPE_VOLUME, + LLPipeline::RENDER_TYPE_GLOW, + LLPipeline::RENDER_TYPE_BUMP, + LLPipeline::RENDER_TYPE_PASS_SIMPLE, + LLPipeline::RENDER_TYPE_PASS_ALPHA, + LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_BUMP, + LLPipeline::RENDER_TYPE_PASS_POST_BUMP, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, + LLPipeline::RENDER_TYPE_PASS_GLOW, + LLPipeline::RENDER_TYPE_PASS_GRASS, + LLPipeline::RENDER_TYPE_PASS_SHINY, + LLPipeline::RENDER_TYPE_PASS_INVISIBLE, + LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, + LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_ALPHA_MASK, + LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, + LLPipeline::RENDER_TYPE_INVISIBLE, + LLPipeline::RENDER_TYPE_SIMPLE, + END_RENDER_TYPES); + } + + S32 occlusion = sUseOcclusion; + sUseOcclusion = 0; - gGL.loadMatrix(mat.m); - set_current_modelview(mat); + sReflectionRender = ! sRenderDeferred; - glClearColor(0.0f,0.0f,0.0f,0.0f); - gGL.setColorMask(true, true); - - // get the number of pixels per angle - F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView()); + sShadowRender = true; + sImpostorRender = true; - //get resolution based on angle width and height of impostor (double desired resolution to prevent aliasing) - resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512); - resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512); + LLViewerCamera* viewer_camera = LLViewerCamera::getInstance(); - if (!avatar->mImpostor.isComplete()) - { - LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_ALLOCATE); - + { + LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_MARK_VISIBLE); + markVisible(avatar->mDrawable, *viewer_camera); + LLVOAvatar::sUseImpostors = false; // @TODO ??? + + LLVOAvatar::attachment_map_t::iterator iter; + for (iter = avatar->mAttachmentPoints.begin(); + iter != avatar->mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment *attachment = iter->second; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + if (LLViewerObject* attached_object = (*attachment_iter)) + { + markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera); + } + } + } + } - if (LLPipeline::sRenderDeferred) - { - avatar->mImpostor.allocate(resX,resY,GL_SRGB8_ALPHA8,TRUE,FALSE); - addDeferredAttachments(avatar->mImpostor); - } - else - { - avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE); - } - - gGL.getTexUnit(0)->bind(&avatar->mImpostor); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - } - else if(resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight()) - { - LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_RESIZE); - avatar->mImpostor.resize(resX,resY); - } + stateSort(*LLViewerCamera::getInstance(), result); + + LLCamera camera = *viewer_camera; + LLVector2 tdim; + U32 resY = 0; + U32 resX = 0; - avatar->mImpostor.bindTarget(); - } + { + LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_SETUP); + const LLVector4a* ext = avatar->mDrawable->getSpatialExtents(); + LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); + + camera.lookAt(viewer_camera->getOrigin(), pos, viewer_camera->getUpAxis()); + + LLVector4a half_height; + half_height.setSub(ext[1], ext[0]); + half_height.mul(0.5f); + + LLVector4a left; + left.load3(camera.getLeftAxis().mV); + left.mul(left); + llassert(left.dot3(left).getF32() > F_APPROXIMATELY_ZERO); + left.normalize3fast(); + + LLVector4a up; + up.load3(camera.getUpAxis().mV); + up.mul(up); + llassert(up.dot3(up).getF32() > F_APPROXIMATELY_ZERO); + up.normalize3fast(); + + tdim.mV[0] = fabsf(half_height.dot3(left).getF32()); + tdim.mV[1] = fabsf(half_height.dot3(up).getF32()); + + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + + F32 distance = (pos-camera.getOrigin()).length(); + F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG; + F32 aspect = tdim.mV[0]/tdim.mV[1]; + glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f); + set_current_projection(persp); + gGL.loadMatrix(persp.m); + + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + glh::matrix4f mat; + camera.getOpenGLTransform(mat.m); + + mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat; + + gGL.loadMatrix(mat.m); + set_current_modelview(mat); + + glClearColor(0.0f,0.0f,0.0f,0.0f); + gGL.setColorMask(true, true); + + // get the number of pixels per angle + F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView()); + + //get resolution based on angle width and height of impostor (double desired resolution to prevent aliasing) + resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512); + resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512); + + if (!avatar->mImpostor.isComplete()) + { + LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_ALLOCATE); + + + if (LLPipeline::sRenderDeferred) + { + avatar->mImpostor.allocate(resX,resY,GL_SRGB8_ALPHA8,TRUE,FALSE); + addDeferredAttachments(avatar->mImpostor); + } + else + { + avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE); + } + + gGL.getTexUnit(0)->bind(&avatar->mImpostor); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + } + else if(resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight()) + { + LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_RESIZE); + avatar->mImpostor.resize(resX,resY); + } + + avatar->mImpostor.bindTarget(); + } - F32 old_alpha = LLDrawPoolAvatar::sMinimumAlpha; + F32 old_alpha = LLDrawPoolAvatar::sMinimumAlpha; - if (visually_muted || too_complex) - { //disable alpha masking for muted avatars (get whole skin silhouette) - LLDrawPoolAvatar::sMinimumAlpha = 0.f; - } + if (visually_muted || too_complex) + { //disable alpha masking for muted avatars (get whole skin silhouette) + LLDrawPoolAvatar::sMinimumAlpha = 0.f; + } - if (LLPipeline::sRenderDeferred) - { - avatar->mImpostor.clear(); - renderGeomDeferred(camera); + if (LLPipeline::sRenderDeferred) + { + avatar->mImpostor.clear(); + renderGeomDeferred(camera); - renderGeomPostDeferred(camera); + renderGeomPostDeferred(camera); - // Shameless hack time: render it all again, - // this time writing the depth - // values we need to generate the alpha mask below - // while preserving the alpha-sorted color rendering - // from the previous pass - // - sImpostorRenderAlphaDepthPass = true; - // depth-only here... - // - gGL.setColorMask(false,false); - renderGeomPostDeferred(camera); + // Shameless hack time: render it all again, + // this time writing the depth + // values we need to generate the alpha mask below + // while preserving the alpha-sorted color rendering + // from the previous pass + // + sImpostorRenderAlphaDepthPass = true; + // depth-only here... + // + gGL.setColorMask(false,false); + renderGeomPostDeferred(camera); - sImpostorRenderAlphaDepthPass = false; + sImpostorRenderAlphaDepthPass = false; - } - else - { - LLGLEnable scissor(GL_SCISSOR_TEST); - glScissor(0, 0, resX, resY); - avatar->mImpostor.clear(); - renderGeom(camera); - - // Shameless hack time: render it all again, - // this time writing the depth - // values we need to generate the alpha mask below - // while preserving the alpha-sorted color rendering - // from the previous pass - // - sImpostorRenderAlphaDepthPass = true; - - // depth-only here... - // - gGL.setColorMask(false,false); - renderGeom(camera); - - sImpostorRenderAlphaDepthPass = false; - } + } + else + { + LLGLEnable scissor(GL_SCISSOR_TEST); + glScissor(0, 0, resX, resY); + avatar->mImpostor.clear(); + renderGeom(camera); + + // Shameless hack time: render it all again, + // this time writing the depth + // values we need to generate the alpha mask below + // while preserving the alpha-sorted color rendering + // from the previous pass + // + sImpostorRenderAlphaDepthPass = true; + + // depth-only here... + // + gGL.setColorMask(false,false); + renderGeom(camera); + + sImpostorRenderAlphaDepthPass = false; + } - LLDrawPoolAvatar::sMinimumAlpha = old_alpha; + LLDrawPoolAvatar::sMinimumAlpha = old_alpha; - { //create alpha mask based on depth buffer (grey out if muted) - LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_BACKGROUND); - if (LLPipeline::sRenderDeferred) - { - GLuint buff = GL_COLOR_ATTACHMENT0; - glDrawBuffersARB(1, &buff); - } + { //create alpha mask based on depth buffer (grey out if muted) + LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_BACKGROUND); + if (LLPipeline::sRenderDeferred) + { + GLuint buff = GL_COLOR_ATTACHMENT0; + glDrawBuffersARB(1, &buff); + } - LLGLDisable blend(GL_BLEND); + LLGLDisable blend(GL_BLEND); - if (visually_muted || too_complex) - { - gGL.setColorMask(true, true); - } - else - { - gGL.setColorMask(false, true); - } - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + if (visually_muted || too_complex) + { + gGL.setColorMask(true, true); + } + else + { + gGL.setColorMask(false, true); + } + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); - gGL.flush(); + gGL.flush(); - gGL.pushMatrix(); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadIdentity(); + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); - static const F32 clip_plane = 0.99999f; + static const F32 clip_plane = 0.99999f; - if (LLGLSLShader::sNoFixedFunction) - { - gDebugProgram.bind(); - } + if (LLGLSLShader::sNoFixedFunction) + { + gDebugProgram.bind(); + } - if (visually_muted) - { // Visually muted avatar + if (visually_muted) + { // Visually muted avatar LLColor4 muted_color(avatar->getMutedAVColor()); LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID() << " MUTED set solid color " << muted_color << LL_ENDL; - gGL.diffuseColor4fv( muted_color.mV ); - } - else - { //grey muted avatar + gGL.diffuseColor4fv( muted_color.mV ); + } + else + { //grey muted avatar LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID() << " MUTED set grey" << LL_ENDL; - gGL.diffuseColor4fv(LLColor4::pink.mV ); - } - - { - gGL.begin(LLRender::QUADS); - gGL.vertex3f(-1, -1, clip_plane); - gGL.vertex3f(1, -1, clip_plane); - gGL.vertex3f(1, 1, clip_plane); - gGL.vertex3f(-1, 1, clip_plane); - gGL.end(); - gGL.flush(); - } - - if (LLGLSLShader::sNoFixedFunction) - { - gDebugProgram.unbind(); - } + gGL.diffuseColor4fv(LLColor4::pink.mV ); + } + + { + gGL.begin(LLRender::QUADS); + gGL.vertex3f(-1, -1, clip_plane); + gGL.vertex3f(1, -1, clip_plane); + gGL.vertex3f(1, 1, clip_plane); + gGL.vertex3f(-1, 1, clip_plane); + gGL.end(); + gGL.flush(); + } + + if (LLGLSLShader::sNoFixedFunction) + { + gDebugProgram.unbind(); + } + + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); + } - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); - } + avatar->mImpostor.flush(); - avatar->mImpostor.flush(); + avatar->setImpostorDim(tdim); - avatar->setImpostorDim(tdim); + LLVOAvatar::sUseImpostors = (0 != LLVOAvatar::sMaxNonImpostors); + sUseOcclusion = occlusion; + sReflectionRender = false; + sImpostorRender = false; + sShadowRender = false; + popRenderTypeMask(); - LLVOAvatar::sUseImpostors = (0 != LLVOAvatar::sMaxNonImpostors); - sUseOcclusion = occlusion; - sReflectionRender = false; - sImpostorRender = false; - sShadowRender = false; - popRenderTypeMask(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); + avatar->mNeedsImpostorUpdate = FALSE; + avatar->cacheImpostorValues(); + avatar->mLastImpostorUpdateFrameTime = gFrameTimeSeconds; - avatar->mNeedsImpostorUpdate = FALSE; - avatar->cacheImpostorValues(); - avatar->mLastImpostorUpdateFrameTime = gFrameTimeSeconds; - - LLVertexBuffer::unbind(); - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); + LLVertexBuffer::unbind(); + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); } bool LLPipeline::hasRenderBatches(const U32 type) const { - return sCull->getRenderMapSize(type) > 0; + return sCull->getRenderMapSize(type) > 0; } LLCullResult::drawinfo_iterator LLPipeline::beginRenderMap(U32 type) { - return sCull->beginRenderMap(type); + return sCull->beginRenderMap(type); } LLCullResult::drawinfo_iterator LLPipeline::endRenderMap(U32 type) { - return sCull->endRenderMap(type); + return sCull->endRenderMap(type); } LLCullResult::sg_iterator LLPipeline::beginAlphaGroups() { - return sCull->beginAlphaGroups(); + return sCull->beginAlphaGroups(); } LLCullResult::sg_iterator LLPipeline::endAlphaGroups() { - return sCull->endAlphaGroups(); + return sCull->endAlphaGroups(); } bool LLPipeline::hasRenderType(const U32 type) const @@ -11317,277 +11257,277 @@ bool LLPipeline::hasRenderType(const U32 type) const // STORM-365 : LLViewerJointAttachment::setAttachmentVisibility() is setting type to 0 to actually mean "do not render" // We then need to test that value here and return false to prevent attachment to render (in mouselook for instance) // TODO: reintroduce RENDER_TYPE_NONE in LLRenderTypeMask and initialize its mRenderTypeEnabled[RENDER_TYPE_NONE] to false explicitely - return (type == 0 ? false : mRenderTypeEnabled[type]); + return (type == 0 ? false : mRenderTypeEnabled[type]); } void LLPipeline::setRenderTypeMask(U32 type, ...) { - va_list args; + va_list args; - va_start(args, type); - while (type < END_RENDER_TYPES) - { - mRenderTypeEnabled[type] = true; - type = va_arg(args, U32); - } - va_end(args); + va_start(args, type); + while (type < END_RENDER_TYPES) + { + mRenderTypeEnabled[type] = true; + type = va_arg(args, U32); + } + va_end(args); - if (type > END_RENDER_TYPES) - { - LL_ERRS() << "Invalid render type." << LL_ENDL; - } + if (type > END_RENDER_TYPES) + { + LL_ERRS() << "Invalid render type." << LL_ENDL; + } } bool LLPipeline::hasAnyRenderType(U32 type, ...) const { - va_list args; + va_list args; - va_start(args, type); - while (type < END_RENDER_TYPES) - { - if (mRenderTypeEnabled[type]) - { - return true; - } - type = va_arg(args, U32); - } - va_end(args); + va_start(args, type); + while (type < END_RENDER_TYPES) + { + if (mRenderTypeEnabled[type]) + { + return true; + } + type = va_arg(args, U32); + } + va_end(args); - if (type > END_RENDER_TYPES) - { - LL_ERRS() << "Invalid render type." << LL_ENDL; - } + if (type > END_RENDER_TYPES) + { + LL_ERRS() << "Invalid render type." << LL_ENDL; + } - return false; + return false; } void LLPipeline::pushRenderTypeMask() { - std::string cur_mask; - cur_mask.assign((const char*) mRenderTypeEnabled, sizeof(mRenderTypeEnabled)); - mRenderTypeEnableStack.push(cur_mask); + std::string cur_mask; + cur_mask.assign((const char*) mRenderTypeEnabled, sizeof(mRenderTypeEnabled)); + mRenderTypeEnableStack.push(cur_mask); } void LLPipeline::popRenderTypeMask() { - if (mRenderTypeEnableStack.empty()) - { - LL_ERRS() << "Depleted render type stack." << LL_ENDL; - } + if (mRenderTypeEnableStack.empty()) + { + LL_ERRS() << "Depleted render type stack." << LL_ENDL; + } - memcpy(mRenderTypeEnabled, mRenderTypeEnableStack.top().data(), sizeof(mRenderTypeEnabled)); - mRenderTypeEnableStack.pop(); + memcpy(mRenderTypeEnabled, mRenderTypeEnableStack.top().data(), sizeof(mRenderTypeEnabled)); + mRenderTypeEnableStack.pop(); } void LLPipeline::andRenderTypeMask(U32 type, ...) { - va_list args; + va_list args; - bool tmp[NUM_RENDER_TYPES]; - for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) - { - tmp[i] = false; - } + bool tmp[NUM_RENDER_TYPES]; + for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) + { + tmp[i] = false; + } - va_start(args, type); - while (type < END_RENDER_TYPES) - { - if (mRenderTypeEnabled[type]) - { - tmp[type] = true; - } + va_start(args, type); + while (type < END_RENDER_TYPES) + { + if (mRenderTypeEnabled[type]) + { + tmp[type] = true; + } - type = va_arg(args, U32); - } - va_end(args); + type = va_arg(args, U32); + } + va_end(args); - if (type > END_RENDER_TYPES) - { - LL_ERRS() << "Invalid render type." << LL_ENDL; - } + if (type > END_RENDER_TYPES) + { + LL_ERRS() << "Invalid render type." << LL_ENDL; + } - for (U32 i = 0; i < LLPipeline::NUM_RENDER_TYPES; ++i) - { - mRenderTypeEnabled[i] = tmp[i]; - } + for (U32 i = 0; i < LLPipeline::NUM_RENDER_TYPES; ++i) + { + mRenderTypeEnabled[i] = tmp[i]; + } } void LLPipeline::clearRenderTypeMask(U32 type, ...) { - va_list args; + va_list args; - va_start(args, type); - while (type < END_RENDER_TYPES) - { - mRenderTypeEnabled[type] = false; - - type = va_arg(args, U32); - } - va_end(args); + va_start(args, type); + while (type < END_RENDER_TYPES) + { + mRenderTypeEnabled[type] = false; + + type = va_arg(args, U32); + } + va_end(args); - if (type > END_RENDER_TYPES) - { - LL_ERRS() << "Invalid render type." << LL_ENDL; - } + if (type > END_RENDER_TYPES) + { + LL_ERRS() << "Invalid render type." << LL_ENDL; + } } void LLPipeline::setAllRenderTypes() { - for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) - { - mRenderTypeEnabled[i] = true; - } + for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) + { + mRenderTypeEnabled[i] = true; + } } void LLPipeline::clearAllRenderTypes() { - for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) - { - mRenderTypeEnabled[i] = false; - } + for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) + { + mRenderTypeEnabled[i] = false; + } } void LLPipeline::addDebugBlip(const LLVector3& position, const LLColor4& color) { - DebugBlip blip(position, color); - mDebugBlips.push_back(blip); + DebugBlip blip(position, color); + mDebugBlips.push_back(blip); } void LLPipeline::hidePermanentObjects( std::vector<U32>& restoreList ) { - //This method is used to hide any vo's from the object list that may have - //the permanent flag set. - - U32 objCnt = gObjectList.getNumObjects(); - for (U32 i = 0; i < objCnt; ++i) - { - LLViewerObject* pObject = gObjectList.getObject(i); - if ( pObject && pObject->flagObjectPermanent() ) - { - LLDrawable *pDrawable = pObject->mDrawable; - - if ( pDrawable ) - { - restoreList.push_back( i ); - hideDrawable( pDrawable ); - } - } - } + //This method is used to hide any vo's from the object list that may have + //the permanent flag set. + + U32 objCnt = gObjectList.getNumObjects(); + for (U32 i = 0; i < objCnt; ++i) + { + LLViewerObject* pObject = gObjectList.getObject(i); + if ( pObject && pObject->flagObjectPermanent() ) + { + LLDrawable *pDrawable = pObject->mDrawable; + + if ( pDrawable ) + { + restoreList.push_back( i ); + hideDrawable( pDrawable ); + } + } + } - skipRenderingOfTerrain( true ); + skipRenderingOfTerrain( true ); } void LLPipeline::restorePermanentObjects( const std::vector<U32>& restoreList ) { - //This method is used to restore(unhide) any vo's from the object list that may have - //been hidden because their permanency flag was set. + //This method is used to restore(unhide) any vo's from the object list that may have + //been hidden because their permanency flag was set. - std::vector<U32>::const_iterator itCurrent = restoreList.begin(); - std::vector<U32>::const_iterator itEnd = restoreList.end(); - - U32 objCnt = gObjectList.getNumObjects(); + std::vector<U32>::const_iterator itCurrent = restoreList.begin(); + std::vector<U32>::const_iterator itEnd = restoreList.end(); + + U32 objCnt = gObjectList.getNumObjects(); - while ( itCurrent != itEnd ) - { - U32 index = *itCurrent; - LLViewerObject* pObject = NULL; - if ( index < objCnt ) - { - pObject = gObjectList.getObject( index ); - } - if ( pObject ) - { - LLDrawable *pDrawable = pObject->mDrawable; - if ( pDrawable ) - { - pDrawable->clearState( LLDrawable::FORCE_INVISIBLE ); - unhideDrawable( pDrawable ); - } - } - ++itCurrent; - } - - skipRenderingOfTerrain( false ); + while ( itCurrent != itEnd ) + { + U32 index = *itCurrent; + LLViewerObject* pObject = NULL; + if ( index < objCnt ) + { + pObject = gObjectList.getObject( index ); + } + if ( pObject ) + { + LLDrawable *pDrawable = pObject->mDrawable; + if ( pDrawable ) + { + pDrawable->clearState( LLDrawable::FORCE_INVISIBLE ); + unhideDrawable( pDrawable ); + } + } + ++itCurrent; + } + + skipRenderingOfTerrain( false ); } void LLPipeline::skipRenderingOfTerrain( bool flag ) { - pool_set_t::iterator iter = mPools.begin(); - while ( iter != mPools.end() ) - { - LLDrawPool* pPool = *iter; - U32 poolType = pPool->getType(); - if ( hasRenderType( pPool->getType() ) && poolType == LLDrawPool::POOL_TERRAIN ) - { - pPool->setSkipRenderFlag( flag ); - } - ++iter; - } + pool_set_t::iterator iter = mPools.begin(); + while ( iter != mPools.end() ) + { + LLDrawPool* pPool = *iter; + U32 poolType = pPool->getType(); + if ( hasRenderType( pPool->getType() ) && poolType == LLDrawPool::POOL_TERRAIN ) + { + pPool->setSkipRenderFlag( flag ); + } + ++iter; + } } void LLPipeline::hideObject( const LLUUID& id ) { - LLViewerObject *pVO = gObjectList.findObject( id ); - - if ( pVO ) - { - LLDrawable *pDrawable = pVO->mDrawable; - - if ( pDrawable ) - { - hideDrawable( pDrawable ); - } - } + LLViewerObject *pVO = gObjectList.findObject( id ); + + if ( pVO ) + { + LLDrawable *pDrawable = pVO->mDrawable; + + if ( pDrawable ) + { + hideDrawable( pDrawable ); + } + } } void LLPipeline::hideDrawable( LLDrawable *pDrawable ) { - pDrawable->setState( LLDrawable::FORCE_INVISIBLE ); - markRebuild( pDrawable, LLDrawable::REBUILD_ALL, TRUE ); - //hide the children - LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren(); - for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++ ) - { - LLViewerObject* child = *iter; - LLDrawable* drawable = child->mDrawable; - if ( drawable ) - { - drawable->setState( LLDrawable::FORCE_INVISIBLE ); - markRebuild( drawable, LLDrawable::REBUILD_ALL, TRUE ); - } - } + pDrawable->setState( LLDrawable::FORCE_INVISIBLE ); + markRebuild( pDrawable, LLDrawable::REBUILD_ALL, TRUE ); + //hide the children + LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren(); + for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++ ) + { + LLViewerObject* child = *iter; + LLDrawable* drawable = child->mDrawable; + if ( drawable ) + { + drawable->setState( LLDrawable::FORCE_INVISIBLE ); + markRebuild( drawable, LLDrawable::REBUILD_ALL, TRUE ); + } + } } void LLPipeline::unhideDrawable( LLDrawable *pDrawable ) { - pDrawable->clearState( LLDrawable::FORCE_INVISIBLE ); - markRebuild( pDrawable, LLDrawable::REBUILD_ALL, TRUE ); - //restore children - LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren(); - for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++) - { - LLViewerObject* child = *iter; - LLDrawable* drawable = child->mDrawable; - if ( drawable ) - { - drawable->clearState( LLDrawable::FORCE_INVISIBLE ); - markRebuild( drawable, LLDrawable::REBUILD_ALL, TRUE ); - } - } + pDrawable->clearState( LLDrawable::FORCE_INVISIBLE ); + markRebuild( pDrawable, LLDrawable::REBUILD_ALL, TRUE ); + //restore children + LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren(); + for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++) + { + LLViewerObject* child = *iter; + LLDrawable* drawable = child->mDrawable; + if ( drawable ) + { + drawable->clearState( LLDrawable::FORCE_INVISIBLE ); + markRebuild( drawable, LLDrawable::REBUILD_ALL, TRUE ); + } + } } void LLPipeline::restoreHiddenObject( const LLUUID& id ) { - LLViewerObject *pVO = gObjectList.findObject( id ); - - if ( pVO ) - { - LLDrawable *pDrawable = pVO->mDrawable; - if ( pDrawable ) - { - unhideDrawable( pDrawable ); - } - } + LLViewerObject *pVO = gObjectList.findObject( id ); + + if ( pVO ) + { + LLDrawable *pDrawable = pVO->mDrawable; + if ( pDrawable ) + { + unhideDrawable( pDrawable ); + } + } } diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index a31f880fbf..b4a8ca004e 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -166,9 +166,6 @@ public: // if source's depth buffer cannot be bound for reading, a scratch space depth buffer must be provided void downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL); - // Downsample depth buffer with gather and find local min/max depth values. Writes to a 16F RG render target. - void downsampleMinMaxDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL); - void doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL); void doOcclusion(LLCamera& camera); void markNotCulled(LLSpatialGroup* group, LLCamera &camera); @@ -539,8 +536,7 @@ public: RENDER_DEBUG_ATTACHMENT_BYTES = 0x20000000, // not used RENDER_DEBUG_TEXEL_DENSITY = 0x40000000, RENDER_DEBUG_TRIANGLE_COUNT = 0x80000000, - RENDER_DEBUG_IMPOSTORS = 0x100000000, - RENDER_DEBUG_SH = 0x200000000, + RENDER_DEBUG_IMPOSTORS = 0x100000000 }; public: @@ -628,13 +624,12 @@ public: //sun shadow map LLRenderTarget mShadow[6]; LLRenderTarget mShadowOcclusion[6]; - - std::vector<LLVector3> mShadowFrustPoints[4]; - LLVector4 mShadowError; - LLVector4 mShadowFOV; - LLVector3 mShadowFrustOrigin[4]; - LLCamera mShadowCamera[8]; - LLVector3 mShadowExtents[4][2]; + std::vector<LLVector3> mShadowFrustPoints[4]; + LLVector4 mShadowError; + LLVector4 mShadowFOV; + LLVector3 mShadowFrustOrigin[4]; + LLCamera mShadowCamera[8]; + LLVector3 mShadowExtents[4][2]; glh::matrix4f mSunShadowMatrix[6]; glh::matrix4f mShadowModelview[6]; glh::matrix4f mShadowProjection[6]; |