diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp index 7a516f838..12bcffac2 100644 --- a/indra/llcharacter/llbvhloader.cpp +++ b/indra/llcharacter/llbvhloader.cpp @@ -48,10 +48,10 @@ using namespace std; #define INCHES_TO_METERS 0.02540005f -const F32 POSITION_KEYFRAME_THRESHOLD = 0.03f; +const F32 POSITION_KEYFRAME_THRESHOLD_SQUARED = 0.03f * 0.03f; const F32 ROTATION_KEYFRAME_THRESHOLD = 0.01f; -const F32 POSITION_MOTION_THRESHOLD = 0.001f; +const F32 POSITION_MOTION_THRESHOLD_SQUARED = 0.001f * 0.001f; const F32 ROTATION_MOTION_THRESHOLD = 0.001f; char gInFile[1024]; /* Flawfinder: ignore */ @@ -1202,7 +1202,7 @@ void LLBVHLoader::optimize() if (ki_prev == ki_last_good_pos) { joint->mNumPosKeys++; - if (dist_vec(LLVector3(ki_prev->mPos), first_frame_pos) > POSITION_MOTION_THRESHOLD) + if (dist_vec_squared(LLVector3(ki_prev->mPos), first_frame_pos) > POSITION_MOTION_THRESHOLD_SQUARED) { pos_changed = TRUE; } @@ -1215,12 +1215,12 @@ void LLBVHLoader::optimize() LLVector3 current_pos(ki->mPos); LLVector3 interp_pos = lerp(current_pos, last_good_pos, 1.f / (F32)numPosFramesConsidered); - if (dist_vec(current_pos, first_frame_pos) > POSITION_MOTION_THRESHOLD) + if (dist_vec_squared(current_pos, first_frame_pos) > POSITION_MOTION_THRESHOLD_SQUARED) { pos_changed = TRUE; } - if (dist_vec(interp_pos, test_pos) < POSITION_KEYFRAME_THRESHOLD) + if (dist_vec_squared(interp_pos, test_pos) < POSITION_KEYFRAME_THRESHOLD_SQUARED) { ki_prev->mIgnorePos = TRUE; numPosFramesConsidered++; diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h index 4de59e9ee..f7206f750 100644 --- a/indra/llcharacter/llcharacter.h +++ b/indra/llcharacter/llcharacter.h @@ -261,7 +261,7 @@ public: } return 0; } - S32 getVisualParamCount() { return (S32)mVisualParamIndexMap.size(); } + S32 getVisualParamCount() const { return (S32)mVisualParamIndexMap.size(); } LLVisualParam* getVisualParam(const char *name); diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h index 7e8c84488..50d9d0504 100644 --- a/indra/llcharacter/llkeyframemotion.h +++ b/indra/llcharacter/llkeyframemotion.h @@ -47,7 +47,6 @@ #include "llquaternion.h" #include "v3dmath.h" #include "v3math.h" -#include "llapr.h" #include "llbvhconsts.h" class LLKeyframeDataCache; diff --git a/indra/llcharacter/llkeyframestandmotion.cpp b/indra/llcharacter/llkeyframestandmotion.cpp index 1d42298f4..1ae0ddeea 100644 --- a/indra/llcharacter/llkeyframestandmotion.cpp +++ b/indra/llcharacter/llkeyframestandmotion.cpp @@ -190,7 +190,7 @@ BOOL LLKeyframeStandMotion::onUpdate(F32 time, U8* joint_mask) if (dot(mPelvisState->getJoint()->getWorldRotation(), mLastGoodPelvisRotation) < ROTATION_THRESHOLD) { mLastGoodPelvisRotation = mPelvisState->getJoint()->getWorldRotation(); - mLastGoodPelvisRotation.normQuat(); + mLastGoodPelvisRotation.normalize(); mTrackAnkles = TRUE; } else if ((mCharacter->getCharacterPosition() - mLastGoodPosition).magVecSquared() > POSITION_THRESHOLD) diff --git a/indra/llcharacter/llpose.h b/indra/llcharacter/llpose.h index 5698f2161..80487bd12 100644 --- a/indra/llcharacter/llpose.h +++ b/indra/llcharacter/llpose.h @@ -36,12 +36,12 @@ //----------------------------------------------------------------------------- // Header Files //----------------------------------------------------------------------------- -#include -#include "llmap.h" #include "lljointstate.h" #include "lljoint.h" +#include "llmap.h" #include +#include //----------------------------------------------------------------------------- diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index e88c404eb..dbd1f092d 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -33,6 +33,7 @@ set(llcommon_SOURCE_FILES llerror.cpp llerrorthread.cpp llevent.cpp + lleventtimer.cpp llfasttimer.cpp llfile.cpp llfindlocale.cpp @@ -40,6 +41,7 @@ set(llcommon_SOURCE_FILES llformat.cpp llframetimer.cpp llheartbeat.cpp + llinstancetracker.cpp llindraconfigfile.cpp llliveappconfig.cpp lllivefile.cpp @@ -123,6 +125,7 @@ set(llcommon_HEADER_FILES llevent.h lleventemitter.h llextendedstatus.h + lleventtimer.h llfasttimer.h llfile.h llfindlocale.h @@ -133,6 +136,7 @@ set(llcommon_HEADER_FILES llheartbeat.h llhttpstatuscodes.h llindexedqueue.h + llinstancetracker.h llindraconfigfile.h llkeythrottle.h lllinkedqueue.h @@ -189,7 +193,6 @@ set(llcommon_HEADER_FILES metaclasst.h metaproperty.h metapropertyt.h - processor.h reflective.h reflectivet.h roles_constants.h diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index 3725b1d84..a95b6499d 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -48,7 +48,7 @@ class LLUUID; #define PHYSICS_TIMESTEP (1.f / 45.f) const F32 COLLISION_TOLERANCE = 0.1f; -const F32 HALF_COLLISION_TOLERANCE = COLLISION_TOLERANCE * 0.5f; +const F32 HALF_COLLISION_TOLERANCE = 0.05f; // Time constants const U32 HOURS_PER_LINDEN_DAY = 4; @@ -99,9 +99,9 @@ const F32 MIN_AGENT_WIDTH = 0.40f; const F32 DEFAULT_AGENT_WIDTH = 0.60f; const F32 MAX_AGENT_WIDTH = 0.80f; -const F32 MIN_AGENT_HEIGHT = 1.3f - 2.0f * COLLISION_TOLERANCE; +const F32 MIN_AGENT_HEIGHT = 1.1f; const F32 DEFAULT_AGENT_HEIGHT = 1.9f; -const F32 MAX_AGENT_HEIGHT = 2.65f - 2.0f * COLLISION_TOLERANCE; +const F32 MAX_AGENT_HEIGHT = 2.45f; // For linked sets const S32 MAX_CHILDREN_PER_TASK = 255; @@ -252,9 +252,6 @@ const U8 SIM_ACCESS_ADULT = 42; // Seriously Adult Only const U8 SIM_ACCESS_DOWN = 254; const U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT; -// group constants -const S32 DEFAULT_MAX_AGENT_GROUPS = 25; - // attachment constants const S32 MAX_AGENT_ATTACHMENTS = 38; const U8 ATTACHMENT_ADD = 0x80; @@ -293,6 +290,7 @@ const U8 UPD_UNIFORM = 0x10; // used with UPD_SCALE // Agent Update Flags (U8) const U8 AU_FLAGS_NONE = 0x00; const U8 AU_FLAGS_HIDETITLE = 0x01; +const U8 AU_FLAGS_CLIENT_AUTOPILOT = 0x02; // start location constants const U32 START_LOCATION_ID_LAST = 0; @@ -306,6 +304,14 @@ const U32 START_LOCATION_ID_COUNT = 6; // group constants const U32 GROUP_MIN_SIZE = 2; +// gMaxAgentGroups is now sent by login.cgi, which +// looks it up from globals.xml. +// +// For now we need an old default value however, +// so the viewer can be deployed ahead of login.cgi. +// +const S32 DEFAULT_MAX_AGENT_GROUPS = 25; + // radius within which a chat message is fully audible const F32 CHAT_WHISPER_RADIUS = 10.f; const F32 CHAT_NORMAL_RADIUS = 20.f; diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 3bb833a94..c35a84255 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -38,8 +38,10 @@ #include "llerrorcontrol.h" #include "llerrorthread.h" #include "llframetimer.h" +#include "lllivefile.h" #include "llmemory.h" -#include "lltimer.h" +#include "llstl.h" // for DeletePointer() +#include "lleventtimer.h" // // Signal handling @@ -139,6 +141,11 @@ LLApp::~LLApp() delete sSigChildCount; sSigChildCount = NULL; #endif + + // reclaim live file memory + std::for_each(mLiveFiles.begin(), mLiveFiles.end(), DeletePointer()); + mLiveFiles.clear(); + setStopped(); // HACK: wait for the error thread to clean itself ms_sleep(20); @@ -212,6 +219,15 @@ bool LLApp::parseCommandOptions(int argc, char** argv) return true; } + +void LLApp::manageLiveFile(LLLiveFile* livefile) +{ + if(!livefile) return; + livefile->checkAndReload(); + livefile->addToEventTimer(); + mLiveFiles.push_back(livefile); +} + bool LLApp::setOptionData(OptionPriority level, LLSD data) { if((level < 0) diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index d5cf6ea93..05e2bccaf 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -131,6 +131,19 @@ public: */ bool parseCommandOptions(int argc, char** argv); + /** + * @brief Keep track of live files automatically. + * + * *TODO: it currently uses the addToEventTimer() API + * instead of the runner. I should probalby use the runner. + * + * *NOTE: DO NOT add the livefile instance to any kind of check loop. + * + * @param livefile A valid instance of an LLLiveFile. This LLApp + * instance will delete the livefile instance. + */ + void manageLiveFile(LLLiveFile* livefile); + /** * @brief Set the options at the specified priority. * @@ -285,6 +298,8 @@ private: // The application options. LLSD mOptions; + // The live files for this application + std::vector mLiveFiles; //@} private: diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index 9595707cb..d2169d65e 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -81,7 +81,7 @@ bool ll_apr_warn_status(apr_status_t status) { if(APR_SUCCESS == status) return false; char buf[MAX_STRING]; /* Flawfinder: ignore */ - apr_strerror(status, buf, MAX_STRING); + apr_strerror(status, buf, sizeof(buf)); LL_WARNS("APR") << "APR: " << buf << LL_ENDL; return true; } diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index f9c73a20a..13c8f649d 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -33,207 +33,115 @@ #include "linden_common.h" #include "llassettype.h" +#include "lldictionary.h" +#include "llmemory.h" -#include "llstring.h" -#include "lltimer.h" - -// I added lookups for exact text of asset type enums in addition to the ones below, so shoot me. -Steve - -struct asset_info_t +///---------------------------------------------------------------------------- +/// Class LLAssetType +///---------------------------------------------------------------------------- +struct AssetEntry : public LLDictionaryEntry { - LLAssetType::EType type; - const char* desc; + AssetEntry(const char *desc_name, + const char *type_name, // 8 character limit! + const char *human_name, // for decoding to human readable form; put any and as many printable characters you want in each one + bool can_link, // can you create a link to this type? + bool can_fetch, // can you fetch this asset by ID? + bool can_know) // can you see this asset's ID? + : + LLDictionaryEntry(desc_name), + mTypeName(type_name), + mHumanName(human_name), + mCanLink(can_link), + mCanFetch(can_fetch), + mCanKnow(can_know) + { + llassert(strlen(mTypeName) <= 8); + } + + const char *mTypeName; + const char *mHumanName; + bool mCanLink; + bool mCanFetch; + bool mCanKnow; }; -asset_info_t asset_types[] = +class LLAssetDictionary : public LLSingleton, + public LLDictionary { - { LLAssetType::AT_TEXTURE, "TEXTURE" }, - { LLAssetType::AT_SOUND, "SOUND" }, - { LLAssetType::AT_CALLINGCARD, "CALLINGCARD" }, - { LLAssetType::AT_LANDMARK, "LANDMARK" }, - { LLAssetType::AT_SCRIPT, "SCRIPT" }, - { LLAssetType::AT_CLOTHING, "CLOTHING" }, - { LLAssetType::AT_OBJECT, "OBJECT" }, - { LLAssetType::AT_NOTECARD, "NOTECARD" }, - { LLAssetType::AT_CATEGORY, "CATEGORY" }, - { LLAssetType::AT_ROOT_CATEGORY, "ROOT_CATEGORY" }, - { LLAssetType::AT_LSL_TEXT, "LSL_TEXT" }, - { LLAssetType::AT_LSL_BYTECODE, "LSL_BYTECODE" }, - { LLAssetType::AT_TEXTURE_TGA, "TEXTURE_TGA" }, - { LLAssetType::AT_BODYPART, "BODYPART" }, - { LLAssetType::AT_TRASH, "TRASH" }, - { LLAssetType::AT_SNAPSHOT_CATEGORY, "SNAPSHOT_CATEGORY" }, - { LLAssetType::AT_LOST_AND_FOUND, "LOST_AND_FOUND" }, - { LLAssetType::AT_SOUND_WAV, "SOUND_WAV" }, - { LLAssetType::AT_IMAGE_TGA, "IMAGE_TGA" }, - { LLAssetType::AT_IMAGE_JPEG, "IMAGE_JPEG" }, - { LLAssetType::AT_ANIMATION, "ANIMATION" }, - { LLAssetType::AT_GESTURE, "GESTURE" }, - { LLAssetType::AT_SIMSTATE, "SIMSTATE" }, - { LLAssetType::AT_FAVORITE, "FAVORITE" }, - { LLAssetType::AT_LINK, "LINK" }, - { LLAssetType::AT_LINK_FOLDER, "CURRENT" }, - { LLAssetType::AT_CURRENT_OUTFIT, "FOLDER_LINK" }, - { LLAssetType::AT_OUTFIT, "OUTFIT" }, - { LLAssetType::AT_MY_OUTFITS, "MY_OUTFITS" }, - { LLAssetType::AT_NONE, "NONE" } +public: + LLAssetDictionary(); }; -LLAssetType::EType LLAssetType::getType(const std::string& sin) +LLAssetDictionary::LLAssetDictionary() { - std::string s = sin; + // 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_ROOT_CATEGORY, new AssetEntry("ROOT_CATEGORY", "root", "root", false, 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_TRASH, new AssetEntry("TRASH", "trash", "trash", false, false, false)); + addEntry(LLAssetType::AT_SNAPSHOT_CATEGORY, new AssetEntry("SNAPSHOT_CATEGORY", "snapshot", "snapshot", false, false, false)); + addEntry(LLAssetType::AT_LOST_AND_FOUND, new AssetEntry("LOST_AND_FOUND", "lstndfnd", "lost and found", false, false, false)); + 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_FAVORITE, new AssetEntry("FAVORITE", "favorite", "", 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_CURRENT_OUTFIT, new AssetEntry("FOLDER_LINK", "current", "current outfit", false, false, false)); + addEntry(LLAssetType::AT_OUTFIT, new AssetEntry("OUTFIT", "outfit", "outfit", false, false, false)); + addEntry(LLAssetType::AT_MY_OUTFITS, new AssetEntry("MY_OUTFITS", "my_otfts", "my outfits", false, false, false)); + addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, false, false, false)); +}; + +// static +LLAssetType::EType LLAssetType::getType(const std::string& desc_name) +{ + std::string s = desc_name; LLStringUtil::toUpper(s); - for (S32 idx = 0; ;idx++) - { - asset_info_t* info = asset_types + idx; - if (info->type == LLAssetType::AT_NONE) - break; - if (s == info->desc) - return info->type; - } - return LLAssetType::AT_NONE; + return LLAssetDictionary::getInstance()->lookup(s); } -std::string LLAssetType::getDesc(LLAssetType::EType type) -{ - for (S32 idx = 0; ;idx++) - { - asset_info_t* info = asset_types + idx; - if (type == info->type) - return info->desc; - if (info->type == LLAssetType::AT_NONE) - break; - } - return "BAD TYPE"; -} - -//============================================================================ - -// The asset type names are limited to 8 characters. // static -const char* LLAssetType::mAssetTypeNames[LLAssetType::AT_COUNT] = -{ - "texture", - "sound", - "callcard", - "landmark", - "script", - "clothing", - "object", - "notecard", - "category", - "root", - "lsltext", - "lslbyte", - "txtr_tga",// Intentionally spelled this way. Limited to eight characters. - "bodypart", - "trash", - "snapshot", - "lstndfnd", - "snd_wav", - "img_tga", - "jpeg", - "animatn", - "gesture", - "simstate", - "favorite", - "link", - "link_f", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "current", - "outfit", - "my_otfts" -}; - -// This table is meant for decoding to human readable form. Put any -// and as many printable characters you want in each one. -// See also llinventory.cpp INVENTORY_TYPE_HUMAN_NAMES -const char* LLAssetType::mAssetTypeHumanNames[LLAssetType::AT_COUNT] = -{ - "texture", - "sound", - "calling card", - "landmark", - "legacy script", - "clothing", - "object", - "note card", - "folder", - "root", - "lsl2 script", - "lsl bytecode", - "tga texture", - "body part", - "trash", - "snapshot", - "lost and found", - "sound", - "targa image", - "jpeg image", - "animation", - "gesture", - "simstate", - "", - "symbolic link", - "symbolic folder link" - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "current outfit", - "outfit", - "my outfits" -}; - -///---------------------------------------------------------------------------- -/// class LLAssetType -///---------------------------------------------------------------------------- - -// static -const char* LLAssetType::lookup( LLAssetType::EType type ) +const std::string &LLAssetType::getDesc(LLAssetType::EType asset_type) { - if( (type >= 0) && (type < AT_COUNT )) + const AssetEntry *entry = LLAssetDictionary::getInstance()->lookup(asset_type); + if (entry) { - return mAssetTypeNames[ S32( type ) ]; + return entry->mName; } else { - return "-1"; + return badLookup(); + } +} + +// static +const char *LLAssetType::lookup(LLAssetType::EType asset_type) +{ + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); + const AssetEntry *entry = dict->lookup(asset_type); + if (entry) + { + return entry->mTypeName; + } + else + { + return badLookup().c_str(); } } @@ -243,29 +151,35 @@ LLAssetType::EType LLAssetType::lookup( const char* name ) return lookup(ll_safe_string(name)); } -LLAssetType::EType LLAssetType::lookup( const std::string& name ) +// static +LLAssetType::EType LLAssetType::lookup(const std::string& type_name) { - for( S32 i = 0; i < AT_COUNT; i++ ) + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); + for (LLAssetDictionary::const_iterator iter = dict->begin(); + iter != dict->end(); + iter++) { - if( name == mAssetTypeNames[i] ) + const AssetEntry *entry = iter->second; + if (type_name == entry->mTypeName) { - // match - return (EType)i; + return iter->first; } } return AT_NONE; } // static -const char* LLAssetType::lookupHumanReadable(LLAssetType::EType type) +const char *LLAssetType::lookupHumanReadable(LLAssetType::EType asset_type) { - if( (type >= 0) && (type < AT_COUNT )) + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); + const AssetEntry *entry = dict->lookup(asset_type); + if (entry) { - return mAssetTypeHumanNames[S32(type)]; + return entry->mHumanName; } else { - return NULL; + return badLookup().c_str(); } } @@ -275,14 +189,18 @@ LLAssetType::EType LLAssetType::lookupHumanReadable( const char* name ) return lookupHumanReadable(ll_safe_string(name)); } -LLAssetType::EType LLAssetType::lookupHumanReadable( const std::string& name ) +// static +LLAssetType::EType LLAssetType::lookupHumanReadable(const std::string& readable_name) { - for( S32 i = 0; i < AT_COUNT; i++ ) + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); + for (LLAssetDictionary::const_iterator iter = dict->begin(); + iter != dict->end(); + iter++) { - if( name == mAssetTypeHumanNames[i] ) + const AssetEntry *entry = iter->second; + if (entry->mHumanName && (readable_name == entry->mHumanName)) { - // match - return (EType)i; + return iter->first; } } return AT_NONE; @@ -333,6 +251,16 @@ void LLAssetType::generateDescriptionFor(LLAssetType::EType type, // static bool LLAssetType::lookupCanLink(EType asset_type) { + //Check that enabling all these other types as linkable doesn't break things. + /*const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); + const AssetEntry *entry = dict->lookup(asset_type); + if (entry) + { + return entry->mCanLink; + } + return false; + */ + return (asset_type == AT_CLOTHING || asset_type == AT_OBJECT || asset_type == AT_CATEGORY || asset_type == AT_BODYPART || asset_type == AT_GESTURE); } @@ -341,45 +269,42 @@ bool LLAssetType::lookupCanLink(EType asset_type) // Not adding this to dictionary since we probably will only have these two types bool LLAssetType::lookupIsLinkType(EType asset_type) { - return (asset_type == AT_LINK || asset_type == AT_LINK_FOLDER); + if (asset_type == AT_LINK || asset_type == AT_LINK_FOLDER) + { + return true; + } + return false; +} + +// static +const std::string &LLAssetType::badLookup() +{ + static const std::string sBadLookup = "llassettype_bad_lookup"; + return sBadLookup; + } // static bool LLAssetType::lookupIsAssetFetchByIDAllowed(EType asset_type) { - // *FIX: Make this list smaller. - switch(asset_type) + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); + const AssetEntry *entry = dict->lookup(asset_type); + if (entry) { - case LLAssetType::AT_SOUND: - case LLAssetType::AT_LANDMARK: - case LLAssetType::AT_CLOTHING: - case LLAssetType::AT_BODYPART: - case LLAssetType::AT_ANIMATION: - case LLAssetType::AT_GESTURE: - return true; - default: - return false; + return entry->mCanFetch; } + return false; } // static bool LLAssetType::lookupIsAssetIDKnowable(EType asset_type) { - switch(asset_type) + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); + const AssetEntry *entry = dict->lookup(asset_type); + if (entry) { - case LLAssetType::AT_TEXTURE: - case LLAssetType::AT_SOUND: - case LLAssetType::AT_LANDMARK: - case LLAssetType::AT_CLOTHING: - case LLAssetType::AT_NOTECARD: - case LLAssetType::AT_BODYPART: - case LLAssetType::AT_ANIMATION: - case LLAssetType::AT_GESTURE: - case LLAssetType::AT_LINK: - case LLAssetType::AT_LINK_FOLDER: - return true; - default: - return false; + return entry->mCanKnow; } + return false; } diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h index 9912ecba2..0363956d7 100644 --- a/indra/llcommon/llassettype.h +++ b/indra/llcommon/llassettype.h @@ -160,39 +160,36 @@ public: }; // machine transation between type and strings - static EType lookup(const char* name); // safe conversion to std::string, *TODO: deprecate - static EType lookup(const std::string& name); - static const char* lookup(EType type); + static EType lookup(const char* name); // safe conversion to std::string, *TODO: deprecate + static EType lookup(const std::string& type_name); + static const char* lookup(EType asset_type); // translation from a type to a human readable form. - static EType lookupHumanReadable( const char* name ); // safe conversion to std::string, *TODO: deprecate - static EType lookupHumanReadable( const std::string& name ); - static const char* lookupHumanReadable(EType type); + static EType lookupHumanReadable(const char* desc_name); // safe conversion to std::string, *TODO: deprecate + static EType lookupHumanReadable(const std::string& readable_name); + static const char* lookupHumanReadable(EType asset_type); - static EDragAndDropType lookupDragAndDropType( EType ); + static EDragAndDropType lookupDragAndDropType( EType ); // Generate a good default description. You may want to add a verb // or agent name after this depending on your application. static void generateDescriptionFor(LLAssetType::EType type, std::string& desc); - static EType getType(const std::string& sin); - static std::string getDesc(EType type); - + static EType getType(const std::string& desc_name); + static const std::string& getDesc(EType asset_type); + static bool lookupCanLink(EType asset_type); static bool lookupIsLinkType(EType asset_type); static bool lookupIsAssetFetchByIDAllowed(EType asset_type); // the asset allows direct download static bool lookupIsAssetIDKnowable(EType asset_type); // asset data can be known by the viewer -private: - // don't instantiate or derive one of these objects - LLAssetType( void ) {} - ~LLAssetType( void ) {} + static const std::string& badLookup(); // error string when a lookup fails -private: - static const char* mAssetTypeNames[]; - static const char* mAssetTypeHumanNames[]; +protected: + LLAssetType() {} + ~LLAssetType() {} }; #ifdef CWDEBUG diff --git a/indra/llcommon/llboost.h b/indra/llcommon/llboost.h index 4df9dbf3b..4901d6689 100644 --- a/indra/llcommon/llboost.h +++ b/indra/llcommon/llboost.h @@ -46,4 +46,18 @@ */ typedef boost::tokenizer > boost_tokenizer; +// Useful combiner for boost signals that return a bool (e.g. validation) +// returns false if any of the callbacks return false +struct boost_boolean_combiner +{ + typedef bool result_type; + template + bool operator()(InputIterator first, InputIterator last) const + { + bool res = true; + while (first != last) + res &= *first++; + return res; + } +}; #endif // LL_LLBOOST_H diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp index be294480e..e949cbbb4 100644 --- a/indra/llcommon/lldate.cpp +++ b/indra/llcommon/lldate.cpp @@ -38,10 +38,13 @@ #include "apr_time.h" #include +#include +#include #include #include #include "lltimer.h" +#include "llstring.h" static const F64 DATE_EPOCH = 0.0; @@ -88,47 +91,40 @@ std::string LLDate::asString() const // is one of the standards used and the prefered format std::string LLDate::asRFC1123() const { - std::ostringstream stream; - toHTTPDateStream(stream); - return stream.str(); + return toHTTPDateString (std::string ("%A, %d %b %Y %H:%M:%S GMT")); } -void LLDate::toHTTPDateStream(std::ostream& s) const + +std::string LLDate::toHTTPDateString (std::string fmt) const { - // http://apr.apache.org/docs/apr/0.9/group__apr__time.html - apr_time_t time = (apr_time_t)(mSecondsSinceEpoch * LL_APR_USEC_PER_SEC); + + time_t locSeconds = (time_t) mSecondsSinceEpoch; + struct tm * gmt = gmtime (&locSeconds); + return toHTTPDateString(gmt, fmt); +} - apr_time_exp_t exp_time ; //Apache time module - - if (apr_time_exp_gmt(&exp_time, time) != APR_SUCCESS) - { +std::string LLDate::toHTTPDateString (tm * gmt, std::string fmt) +{ // Return Epoch UTC date - s << "Thursday, 01 Jan 1970 00:00:00 GMT" ; - return; - } - s << std::dec << std::setfill('0'); -#if( LL_WINDOWS || __GNUC__ > 2) - s << std::right ; -#else - s.setf(ios::right); -#endif - static char const* const weekdays[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; - static char const* const months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - std::string day = weekdays[exp_time.tm_wday]; - std::string month = months[exp_time.tm_mon]; + // avoid calling setlocale() unnecessarily - it's expensive. + static std::string prev_locale = ""; + std::string this_locale = LLStringUtil::getLocale(); + if (this_locale != prev_locale) + { + setlocale(LC_TIME, this_locale.c_str()); + prev_locale = this_locale; + } - s << std::setw(day.length()) << (day) - << ", " << std::setw(2) << (exp_time.tm_mday) - << ' ' << std::setw(month.length()) << (month) - << ' ' << std::setw(4) << (exp_time.tm_year + 1900) - << ' ' << std::setw(2) << (exp_time.tm_hour) - << ':' << std::setw(2) << (exp_time.tm_min) - << ':' << std::setw(2) << (exp_time.tm_sec) - << " GMT"; - - // RFC 1123 date does not use microseconds - //llinfos << "Date in RFC 1123 format is " << s << llendl; + // use strftime() as it appears to be faster than std::time_put + char buffer[128]; + strftime(buffer, 128, fmt.c_str(), gmt); + std::string res(buffer); +#if LL_WINDOWS + // Convert from locale-dependant charset to UTF-8 (EXT-8524). + res = ll_convert_string_to_utf8_string(res); +#endif + return res; } void LLDate::toStream(std::ostream& s) const @@ -159,7 +155,39 @@ void LLDate::toStream(std::ostream& s) const s << '.' << std::setw(2) << (int)(exp_time.tm_usec / (LL_APR_USEC_PER_SEC / 100)); } - s << 'Z'; + s << 'Z' + << std::setfill(' '); +} + +bool LLDate::split(S32 *year, S32 *month, S32 *day, S32 *hour, S32 *min, S32 *sec) const +{ + apr_time_t time = (apr_time_t)(mSecondsSinceEpoch * LL_APR_USEC_PER_SEC); + + apr_time_exp_t exp_time; + if (apr_time_exp_gmt(&exp_time, time) != APR_SUCCESS) + { + return false; + } + + if (year) + *year = exp_time.tm_year + 1900; + + if (month) + *month = exp_time.tm_mon + 1; + + if (day) + *day = exp_time.tm_mday; + + if (hour) + *hour = exp_time.tm_hour; + + if (min) + *min = exp_time.tm_min; + + if (sec) + *sec = exp_time.tm_sec; + + return true; } bool LLDate::fromString(const std::string& iso8601_date) @@ -223,13 +251,62 @@ bool LLDate::fromStream(std::istream& s) s >> fractional; seconds_since_epoch += fractional; } - c = s.get(); // skip the Z - if (c != 'Z') { return false; } + + c = s.peek(); // check for offset + if (c == '+' || c == '-') + { + S32 offset_sign = (c == '+') ? 1 : -1; + S32 offset_hours = 0; + S32 offset_minutes = 0; + S32 offset_in_seconds = 0; + + s >> offset_hours; + + c = s.get(); // skip the colon a get the minutes if there are any + if (c == ':') + { + s >> offset_minutes; + } + + offset_in_seconds = (offset_hours * 60 + offset_sign * offset_minutes) * 60; + seconds_since_epoch -= offset_in_seconds; + } + else if (c != 'Z') { return false; } // skip the Z mSecondsSinceEpoch = seconds_since_epoch; return true; } +bool LLDate::fromYMDHMS(S32 year, S32 month, S32 day, S32 hour, S32 min, S32 sec) +{ + struct apr_time_exp_t exp_time; + + exp_time.tm_year = year - 1900; + exp_time.tm_mon = month - 1; + exp_time.tm_mday = day; + exp_time.tm_hour = hour; + exp_time.tm_min = min; + exp_time.tm_sec = sec; + + // zero out the unused fields + exp_time.tm_usec = 0; + exp_time.tm_wday = 0; + exp_time.tm_yday = 0; + exp_time.tm_isdst = 0; + exp_time.tm_gmtoff = 0; + + // generate a time_t from that + apr_time_t time; + if (apr_time_exp_gmt_get(&time, &exp_time) != APR_SUCCESS) + { + return false; + } + + mSecondsSinceEpoch = time / LL_APR_USEC_PER_SEC; + + return true; +} + F64 LLDate::secondsSinceEpoch() const { return mSecondsSinceEpoch; diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h index d27da79ad..e116e9cdf 100644 --- a/indra/llcommon/lldate.h +++ b/indra/llcommon/lldate.h @@ -84,7 +84,9 @@ public: std::string asString() const; std::string asRFC1123() const; void toStream(std::ostream&) const; - void toHTTPDateStream(std::ostream&) const; + bool split(S32 *year, S32 *month = NULL, S32 *day = NULL, S32 *hour = NULL, S32 *min = NULL, S32 *sec = NULL) const; + std::string toHTTPDateString (std::string fmt) const; + static std::string toHTTPDateString (tm * gmt, std::string fmt); /** * @brief Set the date from an ISO-8601 string. * @@ -99,6 +101,7 @@ public: */ bool fromString(const std::string& iso8601_date); bool fromStream(std::istream&); + bool fromYMDHMS(S32 year, S32 month = 1, S32 day = 0, S32 hour = 0, S32 min = 0, S32 sec = 0); /** * @brief Return the date in seconds since epoch. diff --git a/indra/llcommon/lldefs.h b/indra/llcommon/lldefs.h index f3b5ca361..10e6cb34b 100644 --- a/indra/llcommon/lldefs.h +++ b/indra/llcommon/lldefs.h @@ -242,5 +242,13 @@ inline LLDATATYPE llclampb(const LLDATATYPE& a) return llmin(llmax(a, (LLDATATYPE)0), (LLDATATYPE)255); } +template +inline void llswap(LLDATATYPE& lhs, LLDATATYPE& rhs) +{ + LLDATATYPE tmp = lhs; + lhs = rhs; + rhs = tmp; +} + #endif // LL_LLDEFS_H diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 60f3bfad1..e04e59d53 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -179,7 +179,7 @@ namespace LLError { return s; } // used to indicate the end of a message - class NoClassInfo { }; + class LL_COMMON_API NoClassInfo { }; // used to indicate no class info known for logging //LLCallStacks keeps track of call stacks and output the call stacks to log file diff --git a/indra/llcommon/llerrorlegacy.h b/indra/llcommon/llerrorlegacy.h index fc563dc09..476d75380 100644 --- a/indra/llcommon/llerrorlegacy.h +++ b/indra/llcommon/llerrorlegacy.h @@ -34,7 +34,7 @@ #ifndef LL_LLERRORLEGACY_H #define LL_LLERRORLEGACY_H - +#include "llpreprocessor.h" /* LEGACY -- DO NOT USE THIS STUFF ANYMORE diff --git a/indra/llcommon/llerrorthread.cpp b/indra/llcommon/llerrorthread.cpp index e2b106aa2..293379910 100644 --- a/indra/llcommon/llerrorthread.cpp +++ b/indra/llcommon/llerrorthread.cpp @@ -32,7 +32,7 @@ #include "linden_common.h" #include "llerrorthread.h" #include "llapp.h" -#include "lltimer.h" +#include "lltimer.h" // ms_sleep() LLErrorThread::LLErrorThread() : LLThread("Error"), diff --git a/indra/llcommon/lleventtimer.cpp b/indra/llcommon/lleventtimer.cpp new file mode 100644 index 000000000..2720b93ab --- /dev/null +++ b/indra/llcommon/lleventtimer.cpp @@ -0,0 +1,115 @@ +/** + * @file lleventtimer.cpp + * @brief Cross-platform objects for doing timing + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + * + */ + +#include "linden_common.h" + +#include "lleventtimer.h" + +#include "u64.h" + + +////////////////////////////////////////////////////////////////////////////// +// +// LLEventTimer Implementation +// +////////////////////////////////////////////////////////////////////////////// + +//std::list LLEventTimer::sActiveList; + +LLEventTimer::LLEventTimer(F32 period) +: mEventTimer() +{ + mPeriod = period; + //sActiveList.push_back(this); +} + +LLEventTimer::LLEventTimer(const LLDate& time) +: mEventTimer() +{ + mPeriod = (F32)(time.secondsSinceEpoch() - LLDate::now().secondsSinceEpoch()); + //sActiveList.push_back(this); +} + + +LLEventTimer::~LLEventTimer() +{ + //sActiveList.remove(this); +} + +//static +void LLEventTimer::updateClass() +{ + std::list completed_timers; + + /*{ + for (std::list::iterator iter = sActiveList.begin(); iter != sActiveList.end(); ) + { + LLEventTimer* timer = *iter++; + F32 et = timer->mEventTimer.getElapsedTimeF32(); + if (timer->mEventTimer.getStarted() && et > timer->mPeriod) { + timer->mEventTimer.reset(); + if ( timer->tick() ) + { + completed_timers.push_back( timer ); + } + } + } + }*/ + { + LLInstanceTrackerScopedGuard guard; + for (instance_iter iter = guard.beginInstances(); iter != guard.endInstances(); ) + { + LLEventTimer& timer = *iter++; + F32 et = timer.mEventTimer.getElapsedTimeF32(); + if (timer.mEventTimer.getStarted() && et > timer.mPeriod) { + timer.mEventTimer.reset(); + if ( timer.tick() ) + { + completed_timers.push_back( &timer ); + } + } + } + } + + if ( completed_timers.size() > 0 ) + { + for (std::list::iterator completed_iter = completed_timers.begin(); + completed_iter != completed_timers.end(); + completed_iter++ ) + { + delete *completed_iter; + } + } +} + + diff --git a/indra/llcommon/lleventtimer.h b/indra/llcommon/lleventtimer.h new file mode 100644 index 000000000..1521b507a --- /dev/null +++ b/indra/llcommon/lleventtimer.h @@ -0,0 +1,66 @@ +/** + * @file lleventtimer.h + * @brief Cross-platform objects for doing timing + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + * + */ + +#ifndef LL_EVENTTIMER_H +#define LL_EVENTTIMER_H + +#include "stdtypes.h" +#include "lldate.h" +#include "llinstancetracker.h" +#include "lltimer.h" + +// class for scheduling a function to be called at a given frequency (approximate, inprecise) +class LL_COMMON_API LLEventTimer : public LLInstanceTracker +{ +public: + LLEventTimer(F32 period); // period is the amount of time between each call to tick() in seconds + LLEventTimer(const LLDate& time); + virtual ~LLEventTimer(); + + //function to be called at the supplied frequency + // Normally return FALSE; TRUE will delete the timer after the function returns. + virtual BOOL tick() = 0; + + static void updateClass(); + +protected: + LLTimer mEventTimer; + F32 mPeriod; + +//private: + //list of active timers +// static std::list sActiveList; // TODO should this be a vector +}; + + +#endif //LL_EVENTTIMER_H diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 726274c23..5cb654a46 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -51,6 +51,9 @@ public: FTM_IDLE, FTM_SLEEP, + // general timers + FT_STRING_FORMAT, + // common messaging components FTM_PUMP, FTM_CURL, diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index 8b28d77bd..31d025bb0 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -233,7 +233,7 @@ public: * and should only be used for config files and the like -- not in a * loop. */ -std::streamsize llifstream_size(llifstream& fstr); -std::streamsize llofstream_size(llofstream& fstr); +std::streamsize LL_COMMON_API llifstream_size(llifstream& fstr); +std::streamsize LL_COMMON_API llofstream_size(llofstream& fstr); #endif // not LL_LLFILE_H diff --git a/indra/llcommon/llformat.cpp b/indra/llcommon/llformat.cpp index 7a500c9e5..f9f16006a 100644 --- a/indra/llcommon/llformat.cpp +++ b/indra/llcommon/llformat.cpp @@ -37,17 +37,41 @@ #include -std::string llformat(const char *fmt, ...) +// common used function with va_list argument +// wrapper for vsnprintf to be called from llformatXXX functions. +static void va_format(std::string& out, const char *fmt, va_list va) { char tstr[1024]; /* Flawfinder: ignore */ - va_list va; - va_start(va, fmt); #if LL_WINDOWS _vsnprintf(tstr, 1024, fmt, va); #else vsnprintf(tstr, 1024, fmt, va); /* Flawfinder: ignore */ #endif - va_end(va); - tstr[1023] = '\0'; - return std::string(tstr); + out.assign(tstr); } + +std::string llformat(const char *fmt, ...) +{ + std::string res; + va_list va; + va_start(va, fmt); + va_format(res, fmt, va); + va_end(va); + return res; +} + +std::string llformat_to_utf8(const char *fmt, ...) +{ + std::string res; + va_list va; + va_start(va, fmt); + va_format(res, fmt, va); + va_end(va); + +#if LL_WINDOWS + // made converting to utf8. See EXT-8318. + res = ll_convert_string_to_utf8_string(res); +#endif + return res; +} + diff --git a/indra/llcommon/llformat.h b/indra/llcommon/llformat.h index ad30d4fb1..1cf3bfcca 100644 --- a/indra/llcommon/llformat.h +++ b/indra/llcommon/llformat.h @@ -40,6 +40,9 @@ // *NOTE: buffer limited to 1024, (but vsnprintf prevents overrun) // should perhaps be replaced with boost::format. -LL_COMMON_API std::string llformat(const char *fmt, ...); +std::string LL_COMMON_API llformat(const char *fmt, ...); +// the same version as above but ensures that returned string is in utf8 on windows +// to enable correct converting utf8_to_wstring. +std::string LL_COMMON_API llformat_to_utf8(const char *fmt, ...); #endif // LL_LLFORMAT_H diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp new file mode 100644 index 000000000..293a1388f --- /dev/null +++ b/indra/llcommon/llinstancetracker.cpp @@ -0,0 +1,47 @@ +/** + * @file lllinstancetracker.cpp + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "llinstancetracker.h" +// STL headers +// std headers +// external library headers +// other Linden headers + +//static +void * & LLInstanceTrackerBase::getInstances(std::type_info const & info) +{ + static std::map instances; + + std::string k = info.name(); + if(instances.find(k) == instances.end()) + { + instances[k] = NULL; + } + + return instances[k]; +} diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h new file mode 100644 index 000000000..e4e535222 --- /dev/null +++ b/indra/llcommon/llinstancetracker.h @@ -0,0 +1,202 @@ +/** + * @file llinstancetracker.h + * @brief LLInstanceTracker is a mixin class that automatically tracks object + * instances with or without an associated key + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + * + */ + +#ifndef LL_LLINSTANCETRACKER_H +#define LL_LLINSTANCETRACKER_H + +#include + +#include "string_table.h" +#include +#include +#include +#include +#include + +class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable +{ + protected: + static void * & getInstances(std::type_info const & info); +}; +/// This mix-in class adds support for tracking all instances of the specified class parameter T +/// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup +/// If KEY is not provided, then instances are stored in a simple set +/// @NOTE: see explicit specialization below for default KEY==T* case +template +class LLInstanceTracker : public LLInstanceTrackerBase +{ + typedef typename std::map InstanceMap; + typedef LLInstanceTracker MyT; + typedef boost::function KeyGetter; + typedef boost::function InstancePtrGetter; +public: + /// Dereferencing key_iter gives you a const KEY& + typedef boost::transform_iterator key_iter; + /// Dereferencing instance_iter gives you a T& + typedef boost::indirect_iterator< boost::transform_iterator > instance_iter; + + static T* getInstance(const KEY& k) + { + typename InstanceMap::const_iterator found = getMap_().find(k); + return (found == getMap_().end()) ? NULL : found->second; + } + + static key_iter beginKeys() + { + return boost::make_transform_iterator(getMap_().begin(), + boost::bind(&InstanceMap::value_type::first, _1)); + } + static key_iter endKeys() + { + return boost::make_transform_iterator(getMap_().end(), + boost::bind(&InstanceMap::value_type::first, _1)); + } + static instance_iter beginInstances() + { + return instance_iter(boost::make_transform_iterator(getMap_().begin(), + boost::bind(&InstanceMap::value_type::second, _1))); + } + static instance_iter endInstances() + { + return instance_iter(boost::make_transform_iterator(getMap_().end(), + boost::bind(&InstanceMap::value_type::second, _1))); + } + static S32 instanceCount() { return getMap_().size(); } +protected: + LLInstanceTracker(KEY key) { add_(key); } + virtual ~LLInstanceTracker() { remove_(); } + virtual void setKey(KEY key) { remove_(); add_(key); } + virtual const KEY& getKey() const { return mKey; } + +private: + void add_(KEY key) + { + mKey = key; + getMap_()[key] = static_cast(this); + } + void remove_() + { + getMap_().erase(mKey); + } + + static InstanceMap& getMap_() + { + void * & instances = getInstances(typeid(MyT)); + if (! instances) + { + instances = new InstanceMap; + } + return * static_cast(instances); + } + +private: + + KEY mKey; +}; + +/// explicit specialization for default case where KEY is T* +/// use a simple std::set +template +class LLInstanceTracker : public LLInstanceTrackerBase +{ + typedef typename std::set InstanceSet; + typedef LLInstanceTracker MyT; +public: + /// Dereferencing key_iter gives you a T* (since T* is the key) + typedef typename InstanceSet::iterator key_iter; + /// Dereferencing instance_iter gives you a T& + typedef boost::indirect_iterator instance_iter; + + /// for completeness of analogy with the generic implementation + static T* getInstance(T* k) { return k; } + static S32 instanceCount() { return getSet_().size(); } + + // Instantiate this to get access to iterators for this type. It's a 'guard' in the sense + // that it treats deletes of this type as errors as long as there is an instance of + // this class alive in scope somewhere (i.e. deleting while iterating is bad). + class LLInstanceTrackerScopedGuard + { + public: + LLInstanceTrackerScopedGuard() + { + ++sIterationNestDepth; + } + + ~LLInstanceTrackerScopedGuard() + { + --sIterationNestDepth; + } + + static instance_iter beginInstances() { return instance_iter(getSet_().begin()); } + static instance_iter endInstances() { return instance_iter(getSet_().end()); } + static key_iter beginKeys() { return getSet_().begin(); } + static key_iter endKeys() { return getSet_().end(); } + }; + +protected: + LLInstanceTracker() + { + // it's safe but unpredictable to create instances of this type while all instances are being iterated over. I hate unpredictable. This assert will probably be turned on early in the next development cycle. + //llassert(sIterationNestDepth == 0); + getSet_().insert(static_cast(this)); + } + virtual ~LLInstanceTracker() + { + // it's unsafe to delete instances of this type while all instances are being iterated over. + llassert(sIterationNestDepth == 0); + getSet_().erase(static_cast(this)); + } + + LLInstanceTracker(const LLInstanceTracker& other) + { + //llassert(sIterationNestDepth == 0); + getSet_().insert(static_cast(this)); + } + + static InstanceSet& getSet_() + { + void * & instances = getInstances(typeid(MyT)); + if (! instances) + { + instances = new InstanceSet; + } + return * static_cast(instances); + } + + static S32 sIterationNestDepth; +}; + +template S32 LLInstanceTracker::sIterationNestDepth = 0; + +#endif diff --git a/indra/llcommon/llliveappconfig.cpp b/indra/llcommon/llliveappconfig.cpp index d2744875d..75bdfee8b 100644 --- a/indra/llcommon/llliveappconfig.cpp +++ b/indra/llcommon/llliveappconfig.cpp @@ -38,9 +38,12 @@ #include "llsd.h" #include "llsdserialize.h" -LLLiveAppConfig::LLLiveAppConfig(LLApp* app, const std::string& filename, F32 refresh_period) -: LLLiveFile(filename, refresh_period), - mApp(app) +LLLiveAppConfig::LLLiveAppConfig( + const std::string& filename, + F32 refresh_period, + LLApp::OptionPriority priority) : + LLLiveFile(filename, refresh_period), + mPriority(priority) { } @@ -77,7 +80,7 @@ bool LLLiveAppConfig::loadFile() // to set the config to an empty config, and return that it // changed. - mApp->setOptionData( - LLApp::PRIORITY_SPECIFIC_CONFIGURATION, config); + LLApp* app = LLApp::instance(); + if(app) app->setOptionData(mPriority, config); return true; } diff --git a/indra/llcommon/llliveappconfig.h b/indra/llcommon/llliveappconfig.h index 465dde160..73b3a2335 100644 --- a/indra/llcommon/llliveappconfig.h +++ b/indra/llcommon/llliveappconfig.h @@ -33,25 +33,43 @@ #ifndef LLLIVEAPPCONFIG_H #define LLLIVEAPPCONFIG_H +#include "llapp.h" #include "lllivefile.h" -class LLApp; +/** + * @class LLLiveAppConfig + * @see LLLiveFile + * + * To use this, instantiate a LLLiveAppConfig object inside your main + * loop. The traditional name for it is live_config. Be sure to call + * live_config.checkAndReload() periodically. + */ class LL_COMMON_API LLLiveAppConfig : public LLLiveFile { public: - // To use this, instantiate a LLLiveAppConfig object inside your main loop. - // The traditional name for it is live_config. - // Be sure to call live_config.checkAndReload() periodically. - LLLiveAppConfig(LLApp* app, const std::string& filename, F32 refresh_period); - ~LLLiveAppConfig(); + /** + * @brief Constructor + * + * @param filename. The name of the file for periodically checking + * configuration. + * @param refresh_period How often the internal timer should + * bother checking the filesystem. + * @param The application priority level of that configuration file. + */ + LLLiveAppConfig( + const std::string& filename, + F32 refresh_period, + LLApp::OptionPriority priority); + + ~LLLiveAppConfig(); ///< Destructor protected: /*virtual*/ bool loadFile(); private: - LLApp* mApp; + LLApp::OptionPriority mPriority; }; #endif diff --git a/indra/llcommon/lllivefile.cpp b/indra/llcommon/lllivefile.cpp index 322f226d5..ce6ac4fac 100644 --- a/indra/llcommon/lllivefile.cpp +++ b/indra/llcommon/lllivefile.cpp @@ -33,7 +33,7 @@ #include "lllivefile.h" #include "llframetimer.h" -#include "lltimer.h" +#include "lleventtimer.h" const F32 DEFAULT_CONFIG_FILE_REFRESH = 5.0f; diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp index 35067b3b3..1257af0e3 100644 --- a/indra/llcommon/llmd5.cpp +++ b/indra/llcommon/llmd5.cpp @@ -83,7 +83,7 @@ documentation and/or software. #include "llmd5.h" #include -#include +#include // cerr // how many bytes to grab at a time when checking files const int LLMD5::BLOCK_LEN = 4096; diff --git a/indra/llcommon/llmd5.h b/indra/llcommon/llmd5.h index 837dd3e5a..8bf715f14 100644 --- a/indra/llcommon/llmd5.h +++ b/indra/llcommon/llmd5.h @@ -108,9 +108,8 @@ public: // methods to acquire finalized result void raw_digest(unsigned char *array) const; // provide 16-byte array for binary data void hex_digest(char *string) const; // provide 33-byte array for ascii-hex string - friend std::ostream& operator<< (std::ostream&, LLMD5 context); - + friend LL_COMMON_API std::ostream& operator<< (std::ostream&, LLMD5 context); private: diff --git a/indra/llcommon/llmetrics.cpp b/indra/llcommon/llmetrics.cpp index 8db3284c4..30e5d435a 100644 --- a/indra/llcommon/llmetrics.cpp +++ b/indra/llcommon/llmetrics.cpp @@ -71,7 +71,7 @@ void LLMetricsImpl::recordEventDetails(const std::string& location, metrics["location"] = location; metrics["stats"] = stats; - llinfos << "LLMETRICS: " << LLSDNotationStreamer(metrics) << llendl; + llinfos << "LLMETRICS: " << (LLSDNotationStreamer(metrics)) << llendl; } // Store this: diff --git a/indra/llcommon/llprocesslauncher.cpp b/indra/llcommon/llprocesslauncher.cpp index ee120fc94..45bd98e20 100644 --- a/indra/llcommon/llprocesslauncher.cpp +++ b/indra/llcommon/llprocesslauncher.cpp @@ -68,6 +68,11 @@ void LLProcessLauncher::setWorkingDirectory(const std::string &dir) mWorkingDir = dir; } +const std::string& LLProcessLauncher::getExecutable() const +{ + return mExecutable; +} + void LLProcessLauncher::clearArguments() { mLaunchArguments.clear(); diff --git a/indra/llcommon/llprocesslauncher.h b/indra/llcommon/llprocesslauncher.h index 9f49a85bd..0b96f3f7b 100644 --- a/indra/llcommon/llprocesslauncher.h +++ b/indra/llcommon/llprocesslauncher.h @@ -53,6 +53,8 @@ public: void setExecutable(const std::string &executable); void setWorkingDirectory(const std::string &dir); + const std::string& getExecutable() const; + void clearArguments(); void addArgument(const std::string &arg); void addArgument(const char *arg); diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index 469e544b1..88c49a10c 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -47,10 +47,8 @@ // solving some compiler conversion problems // - Fixed a bug at family=6, model=6 (Celeron -> P2) ////////////////////////////////////////////////////////////////////////////////// - #include "linden_common.h" - -#include "processor.h" +#include "llprocessor.h" #include diff --git a/indra/llcommon/llrand.h b/indra/llcommon/llrand.h index 73ea17956..30fec9b98 100644 --- a/indra/llcommon/llrand.h +++ b/indra/llcommon/llrand.h @@ -65,32 +65,32 @@ /** *@brief Generate a float from [0, RAND_MAX). */ -LL_COMMON_API S32 ll_rand(); +S32 LL_COMMON_API ll_rand(); /** *@brief Generate a float from [0, val) or (val, 0]. */ -LL_COMMON_API S32 ll_rand(S32 val); +S32 LL_COMMON_API ll_rand(S32 val); /** *@brief Generate a float from [0, 1.0). */ -LL_COMMON_API F32 ll_frand(); +F32 LL_COMMON_API ll_frand(); /** *@brief Generate a float from [0, val) or (val, 0]. */ -LL_COMMON_API F32 ll_frand(F32 val); +F32 LL_COMMON_API ll_frand(F32 val); /** *@brief Generate a double from [0, 1.0). */ -LL_COMMON_API F64 ll_drand(); +F64 LL_COMMON_API ll_drand(); /** *@brief Generate a double from [0, val) or (val, 0]. */ -LL_COMMON_API F64 ll_drand(F64 val); +F64 LL_COMMON_API ll_drand(F64 val); /** * @brief typedefs for good boost lagged fibonacci. diff --git a/indra/llcommon/llrun.h b/indra/llcommon/llrun.h index 0f8d51d81..1fc9925df 100644 --- a/indra/llcommon/llrun.h +++ b/indra/llcommon/llrun.h @@ -38,8 +38,6 @@ #include #include -#include "llpreprocessor.h" - class LLRunnable; /** diff --git a/indra/llcommon/llstreamtools.cpp b/indra/llcommon/llstreamtools.cpp index ee4f46318..b60220830 100644 --- a/indra/llcommon/llstreamtools.cpp +++ b/indra/llcommon/llstreamtools.cpp @@ -436,7 +436,7 @@ void get_keyword_and_value(std::string& keyword, while (line_index < line_size) { c = line[line_index]; - if (!isspace(c)) + if (!LLStringOps::isSpace(c)) { break; } @@ -448,7 +448,7 @@ void get_keyword_and_value(std::string& keyword, while (line_index < line_size) { c = line[line_index]; - if (isspace(c) || '\r' == c || '\n' == c) + if (LLStringOps::isSpace(c) || '\r' == c || '\n' == c) { break; } diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index f08b4c042..7423726cb 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -34,6 +34,7 @@ #include "llstring.h" #include "llerror.h" +#include "llfasttimer.h" #if LL_WINDOWS #define WIN32_LEAN_AND_MEAN @@ -71,6 +72,24 @@ U8 hex_as_nybble(char hex) return 0; // uh - oh, not hex any more... } +bool iswindividual(llwchar elem) +{ + U32 cur_char = (U32)elem; + bool result = false; + if (0x2E80<= cur_char && cur_char <= 0x9FFF) + { + result = true; + } + else if (0xAC00<= cur_char && cur_char <= 0xD7A0 ) + { + result = true; + } + else if (0xF900<= cur_char && cur_char <= 0xFA60 ) + { + result = true; + } + return result; +} bool _read_file_into_string(std::string& str, const std::string& filename) { @@ -630,14 +649,14 @@ namespace snprintf_hack } } -std::string ll_convert_wide_to_string(const wchar_t* in) +std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page) { std::string out; if(in) { int len_in = wcslen(in); int len_out = WideCharToMultiByte( - CP_ACP, + code_page, 0, in, len_in, @@ -652,7 +671,7 @@ std::string ll_convert_wide_to_string(const wchar_t* in) if(pout) { WideCharToMultiByte( - CP_ACP, + code_page, 0, in, len_in, @@ -666,8 +685,55 @@ std::string ll_convert_wide_to_string(const wchar_t* in) } return out; } + +wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page) +{ + // From review: + // We can preallocate a wide char buffer that is the same length (in wchar_t elements) as the utf8 input, + // plus one for a null terminator, and be guaranteed to not overflow. + + // Normally, I'd call that sort of thing premature optimization, + // but we *are* seeing string operations taking a bunch of time, especially when constructing widgets. +// int output_str_len = MultiByteToWideChar(code_page, 0, in.c_str(), in.length(), NULL, 0); + + // reserve place to NULL terminator + int output_str_len = in.length(); + wchar_t* w_out = new wchar_t[output_str_len + 1]; + + memset(w_out, 0, output_str_len + 1); + int real_output_str_len = MultiByteToWideChar (code_page, 0, in.c_str(), in.length(), w_out, output_str_len); + + //looks like MultiByteToWideChar didn't add null terminator to converted string, see EXT-4858. + w_out[real_output_str_len] = 0; + + return w_out; +} + +std::string ll_convert_string_to_utf8_string(const std::string& in) +{ + wchar_t* w_mesg = ll_convert_string_to_wide(in, CP_ACP); + std::string out_utf8(ll_convert_wide_to_string(w_mesg, CP_UTF8)); + delete[] w_mesg; + + return out_utf8; +} #endif // LL_WINDOWS +long LLStringOps::sPacificTimeOffset = 0; +long LLStringOps::sLocalTimeOffset = 0; +bool LLStringOps::sPacificDaylightTime = 0; +std::map LLStringOps::datetimeToCodes; + +std::vector LLStringOps::sWeekDayList; +std::vector LLStringOps::sWeekDayShortList; +std::vector LLStringOps::sMonthList; +std::vector LLStringOps::sMonthShortList; + + +std::string LLStringOps::sDayFormat; +std::string LLStringOps::sAM; +std::string LLStringOps::sPM; + S32 LLStringOps::collate(const llwchar* a, const llwchar* b) { #if LL_WINDOWS @@ -679,6 +745,107 @@ S32 LLStringOps::collate(const llwchar* a, const llwchar* b) #endif } +void LLStringOps::setupDatetimeInfo (bool daylight) +{ + time_t nowT, localT, gmtT; + struct tm * tmpT; + + nowT = time (NULL); + + tmpT = gmtime (&nowT); + gmtT = mktime (tmpT); + + tmpT = localtime (&nowT); + localT = mktime (tmpT); + + sLocalTimeOffset = (long) (gmtT - localT); + if (tmpT->tm_isdst) + { + sLocalTimeOffset -= 60 * 60; // 1 hour + } + + sPacificDaylightTime = daylight; + sPacificTimeOffset = (sPacificDaylightTime? 7 : 8 ) * 60 * 60; + + datetimeToCodes["wkday"] = "%a"; // Thu + datetimeToCodes["weekday"] = "%A"; // Thursday + datetimeToCodes["year4"] = "%Y"; // 2009 + datetimeToCodes["year"] = "%Y"; // 2009 + datetimeToCodes["year2"] = "%y"; // 09 + datetimeToCodes["mth"] = "%b"; // Aug + datetimeToCodes["month"] = "%B"; // August + datetimeToCodes["mthnum"] = "%m"; // 08 + datetimeToCodes["day"] = "%d"; // 31 + datetimeToCodes["sday"] = "%-d"; // 9 + datetimeToCodes["hour24"] = "%H"; // 14 + datetimeToCodes["hour"] = "%H"; // 14 + datetimeToCodes["hour12"] = "%I"; // 02 + datetimeToCodes["min"] = "%M"; // 59 + datetimeToCodes["ampm"] = "%p"; // AM + datetimeToCodes["second"] = "%S"; // 59 + datetimeToCodes["timezone"] = "%Z"; // PST +} + +void tokenizeStringToArray(const std::string& data, std::vector& output) +{ + output.clear(); + size_t length = data.size(); + + // tokenize it and put it in the array + std::string cur_word; + for(size_t i = 0; i < length; ++i) + { + if(data[i] == ':') + { + output.push_back(cur_word); + cur_word.clear(); + } + else + { + cur_word.append(1, data[i]); + } + } + output.push_back(cur_word); +} + +void LLStringOps::setupWeekDaysNames(const std::string& data) +{ + tokenizeStringToArray(data,sWeekDayList); +} +void LLStringOps::setupWeekDaysShortNames(const std::string& data) +{ + tokenizeStringToArray(data,sWeekDayShortList); +} +void LLStringOps::setupMonthNames(const std::string& data) +{ + tokenizeStringToArray(data,sMonthList); +} +void LLStringOps::setupMonthShortNames(const std::string& data) +{ + tokenizeStringToArray(data,sMonthShortList); +} +void LLStringOps::setupDayFormat(const std::string& data) +{ + sDayFormat = data; +} + + +std::string LLStringOps::getDatetimeCode (std::string key) +{ + std::map::iterator iter; + + iter = datetimeToCodes.find (key); + if (iter != datetimeToCodes.end()) + { + return iter->second; + } + else + { + return std::string(""); + } +} + + namespace LLStringFn { // NOTE - this restricts output to ascii @@ -715,12 +882,12 @@ namespace LLStringFn // https://wiki.lindenlab.com/wiki/Unicode_Guidelines has details on // allowable code points for XML. Specifically, they are: // 0x09, 0x0a, 0x0d, and 0x20 on up. JC - std::string strip_invalid_xml(const std::string& input) + std::string strip_invalid_xml(const std::string& instr) { std::string output; - output.reserve( input.size() ); - std::string::const_iterator it = input.begin(); - while (it != input.end()) + output.reserve( instr.size() ); + std::string::const_iterator it = instr.begin(); + while (it != instr.end()) { // Must compare as unsigned for >= // Test most likely match first @@ -756,6 +923,412 @@ namespace LLStringFn } } +//////////////////////////////////////////////////////////// + +// Forward specialization of LLStringUtil::format before use in LLStringUtil::formatDatetime. +template<> +S32 LLStringUtil::format(std::string& s, const format_map_t& substitutions); + +//static +template<> +void LLStringUtil::getTokens(const std::string& instr, std::vector& tokens, const std::string& delims) +{ + std::string currToken; + std::string::size_type begIdx, endIdx; + + begIdx = instr.find_first_not_of (delims); + while (begIdx != std::string::npos) + { + endIdx = instr.find_first_of (delims, begIdx); + if (endIdx == std::string::npos) + { + endIdx = instr.length(); + } + + currToken = instr.substr(begIdx, endIdx - begIdx); + LLStringUtil::trim (currToken); + tokens.push_back(currToken); + begIdx = instr.find_first_not_of (delims, endIdx); + } +} + +template<> +LLStringUtil::size_type LLStringUtil::getSubstitution(const std::string& instr, size_type& start, std::vector& tokens) +{ + const std::string delims (","); + + // Find the first ] + size_type pos2 = instr.find(']', start); + if (pos2 == std::string::npos) + return std::string::npos; + + // Find the last [ before ] + size_type pos1 = instr.find_last_of('[', pos2-1); + if (pos1 == std::string::npos || pos1 < start) + return std::string::npos; + + getTokens(std::string(instr,pos1+1,pos2-pos1-1), tokens, delims); + start = pos2+1; + + return pos1; +} + +// static +template<> +bool LLStringUtil::simpleReplacement(std::string &replacement, std::string token, const format_map_t& substitutions) +{ + // see if we have a replacement for the bracketed string (without the brackets) + // test first using has() because if we just look up with operator[] we get back an + // empty string even if the value is missing. We want to distinguish between + // missing replacements and deliberately empty replacement strings. + format_map_t::const_iterator iter = substitutions.find(token); + if (iter != substitutions.end()) + { + replacement = iter->second; + return true; + } + // if not, see if there's one WITH brackets + iter = substitutions.find(std::string("[" + token + "]")); + if (iter != substitutions.end()) + { + replacement = iter->second; + return true; + } + + return false; +} + +// static +template<> +bool LLStringUtil::simpleReplacement(std::string &replacement, std::string token, const LLSD& substitutions) +{ + // see if we have a replacement for the bracketed string (without the brackets) + // test first using has() because if we just look up with operator[] we get back an + // empty string even if the value is missing. We want to distinguish between + // missing replacements and deliberately empty replacement strings. + if (substitutions.has(token)) + { + replacement = substitutions[token].asString(); + return true; + } + // if not, see if there's one WITH brackets + else if (substitutions.has(std::string("[" + token + "]"))) + { + replacement = substitutions[std::string("[" + token + "]")].asString(); + return true; + } + + return false; +} + +//static +template<> +void LLStringUtil::setLocale(std::string inLocale) +{ + sLocale = inLocale; +}; + +//static +template<> +std::string LLStringUtil::getLocale(void) +{ + return sLocale; +}; + +// static +template<> +void LLStringUtil::formatNumber(std::string& numStr, std::string decimals) +{ + std::stringstream strStream; + S32 intDecimals = 0; + + convertToS32 (decimals, intDecimals); + if (!sLocale.empty()) + { + // std::locale() throws if the locale is unknown! (EXT-7926) + try + { + strStream.imbue(std::locale(sLocale.c_str())); + } catch (const std::exception &) + { + LL_WARNS_ONCE("Locale") << "Cannot set locale to " << sLocale << LL_ENDL; + } + } + + if (!intDecimals) + { + S32 intStr; + + if (convertToS32(numStr, intStr)) + { + strStream << intStr; + numStr = strStream.str(); + } + } + else + { + F32 floatStr; + + if (convertToF32(numStr, floatStr)) + { + strStream << std::fixed << std::showpoint << std::setprecision(intDecimals) << floatStr; + numStr = strStream.str(); + } + } +} + +// static +template<> +bool LLStringUtil::formatDatetime(std::string& replacement, std::string token, + std::string param, S32 secFromEpoch) +{ + if (param == "local") // local + { + secFromEpoch -= LLStringOps::getLocalTimeOffset(); + } + else if (param != "utc") // slt + { + secFromEpoch -= LLStringOps::getPacificTimeOffset(); + } + + // if never fell into those two ifs above, param must be utc + if (secFromEpoch < 0) secFromEpoch = 0; + + LLDate datetime((F64)secFromEpoch); + std::string code = LLStringOps::getDatetimeCode (token); + + // special case to handle timezone + if (code == "%Z") { + if (param == "utc") + { + replacement = "GMT"; + } + else if (param == "local") + { + replacement = ""; // user knows their own timezone + } + else + { + // "slt" = Second Life Time, which is deprecated. + // If not utc or user local time, fallback to Pacific time + replacement = LLStringOps::getPacificDaylightTime() ? "PDT" : "PST"; + } + return true; + } + + //EXT-7013 + //few codes are not suppotred by strtime function (example - weekdays for Japanise) + //so use predefined ones + + //if sWeekDayList is not empty than current locale doesn't support + //weekday name. + time_t loc_seconds = (time_t) secFromEpoch; + if(LLStringOps::sWeekDayList.size() == 7 && code == "%A") + { + struct tm * gmt = gmtime (&loc_seconds); + replacement = LLStringOps::sWeekDayList[gmt->tm_wday]; + } + else if(LLStringOps::sWeekDayShortList.size() == 7 && code == "%a") + { + struct tm * gmt = gmtime (&loc_seconds); + replacement = LLStringOps::sWeekDayShortList[gmt->tm_wday]; + } + else if(LLStringOps::sMonthList.size() == 12 && code == "%B") + { + struct tm * gmt = gmtime (&loc_seconds); + replacement = LLStringOps::sMonthList[gmt->tm_mon]; + } + else if( !LLStringOps::sDayFormat.empty() && code == "%d" ) + { + struct tm * gmt = gmtime (&loc_seconds); + LLStringUtil::format_map_t args; + args["[MDAY]"] = llformat ("%d", gmt->tm_mday); + replacement = LLStringOps::sDayFormat; + LLStringUtil::format(replacement, args); + } + else if (code == "%-d") + { + struct tm * gmt = gmtime (&loc_seconds); + replacement = llformat ("%d", gmt->tm_mday); // day of the month without leading zero + } + else if( !LLStringOps::sAM.empty() && !LLStringOps::sPM.empty() && code == "%p" ) + { + struct tm * gmt = gmtime (&loc_seconds); + if(gmt->tm_hour<12) + { + replacement = LLStringOps::sAM; + } + else + { + replacement = LLStringOps::sPM; + } + } + else + { + replacement = datetime.toHTTPDateString(code); + } + + // *HACK: delete leading zero from hour string in case 'hour12' (code = %I) time format + // to show time without leading zero, e.g. 08:16 -> 8:16 (EXT-2738). + // We could have used '%l' format instead, but it's not supported by Windows. + if(code == "%I" && token == "hour12" && replacement.at(0) == '0') + { + replacement = replacement.at(1); + } + + return !code.empty(); +} + +// LLStringUtil::format recogizes the following patterns. +// All substitutions *must* be encased in []'s in the input string. +// The []'s are optional in the substitution map. +// [FOO_123] +// [FOO,number,precision] +// [FOO,datetime,format] + + +// static +template<> +S32 LLStringUtil::format(std::string& s, const format_map_t& substitutions) +{ + LLFastTimer ft(LLFastTimer::FT_STRING_FORMAT); + S32 res = 0; + + std::string output; + std::vector tokens; + + std::string::size_type start = 0; + std::string::size_type prev_start = 0; + std::string::size_type key_start = 0; + while ((key_start = getSubstitution(s, start, tokens)) != std::string::npos) + { + output += std::string(s, prev_start, key_start-prev_start); + prev_start = start; + + bool found_replacement = false; + std::string replacement; + + if (tokens.size() == 0) + { + found_replacement = false; + } + else if (tokens.size() == 1) + { + found_replacement = simpleReplacement (replacement, tokens[0], substitutions); + } + else if (tokens[1] == "number") + { + std::string param = "0"; + + if (tokens.size() > 2) param = tokens[2]; + found_replacement = simpleReplacement (replacement, tokens[0], substitutions); + if (found_replacement) formatNumber (replacement, param); + } + else if (tokens[1] == "datetime") + { + std::string param; + if (tokens.size() > 2) param = tokens[2]; + + format_map_t::const_iterator iter = substitutions.find("datetime"); + if (iter != substitutions.end()) + { + S32 secFromEpoch = 0; + BOOL r = LLStringUtil::convertToS32(iter->second, secFromEpoch); + if (r) + { + found_replacement = formatDatetime(replacement, tokens[0], param, secFromEpoch); + } + } + } + + if (found_replacement) + { + output += replacement; + res++; + } + else + { + // we had no replacement, use the string as is + // e.g. "hello [MISSING_REPLACEMENT]" or "-=[Stylized Name]=-" + output += std::string(s, key_start, start-key_start); + } + tokens.clear(); + } + // send the remainder of the string (with no further matches for bracketed names) + output += std::string(s, start); + s = output; + return res; +} + +//static +template<> +S32 LLStringUtil::format(std::string& s, const LLSD& substitutions) +{ + LLFastTimer ft(LLFastTimer::FT_STRING_FORMAT); + S32 res = 0; + + if (!substitutions.isMap()) + { + return res; + } + + std::string output; + std::vector tokens; + + std::string::size_type start = 0; + std::string::size_type prev_start = 0; + std::string::size_type key_start = 0; + while ((key_start = getSubstitution(s, start, tokens)) != std::string::npos) + { + output += std::string(s, prev_start, key_start-prev_start); + prev_start = start; + + bool found_replacement = false; + std::string replacement; + + if (tokens.size() == 0) + { + found_replacement = false; + } + else if (tokens.size() == 1) + { + found_replacement = simpleReplacement (replacement, tokens[0], substitutions); + } + else if (tokens[1] == "number") + { + std::string param = "0"; + + if (tokens.size() > 2) param = tokens[2]; + found_replacement = simpleReplacement (replacement, tokens[0], substitutions); + if (found_replacement) formatNumber (replacement, param); + } + else if (tokens[1] == "datetime") + { + std::string param; + if (tokens.size() > 2) param = tokens[2]; + + S32 secFromEpoch = (S32) substitutions["datetime"].asInteger(); + found_replacement = formatDatetime (replacement, tokens[0], param, secFromEpoch); + } + + if (found_replacement) + { + output += replacement; + res++; + } + else + { + // we had no replacement, use the string as is + // e.g. "hello [MISSING_REPLACEMENT]" or "-=[Stylized Name]=-" + output += std::string(s, key_start, start-key_start); + } + tokens.clear(); + } + // send the remainder of the string (with no further matches for bracketed names) + output += std::string(s, start); + s = output; + return res; +} //////////////////////////////////////////////////////////// // Testing diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 171747921..bdbefe935 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -37,6 +37,9 @@ #include #include #include +#include +#include +#include "llsd.h" #if LL_LINUX || LL_SOLARIS #include @@ -148,7 +151,23 @@ struct char_traits class LL_COMMON_API LLStringOps { +private: + static long sPacificTimeOffset; + static long sLocalTimeOffset; + static bool sPacificDaylightTime; + + static std::map datetimeToCodes; + public: + static std::vector sWeekDayList; + static std::vector sWeekDayShortList; + static std::vector sMonthList; + static std::vector sMonthShortList; + static std::string sDayFormat; + + static std::string sAM; + static std::string sPM; + static char toUpper(char elem) { return toupper((unsigned char)elem); } static llwchar toUpper(llwchar elem) { return towupper(elem); } @@ -177,14 +196,31 @@ public: static S32 collate(const llwchar* a, const llwchar* b); static bool isHexString(const std::string& str); + + static void setupDatetimeInfo(bool pacific_daylight_time); + + static void setupWeekDaysNames(const std::string& data); + static void setupWeekDaysShortNames(const std::string& data); + static void setupMonthNames(const std::string& data); + static void setupMonthShortNames(const std::string& data); + static void setupDayFormat(const std::string& data); + + + static long getPacificTimeOffset(void) { return sPacificTimeOffset;} + static long getLocalTimeOffset(void) { return sLocalTimeOffset;} + // Is the Pacific time zone (aka server time zone) + // currently in daylight savings time? + static bool getPacificDaylightTime(void) { return sPacificDaylightTime;} + + static std::string getDatetimeCode (std::string key); }; /** * @brief Return a string constructed from in without crashing if the * pointer is NULL. */ -std::string LL_COMMON_API ll_safe_string(const char* in); -std::string LL_COMMON_API ll_safe_string(const char* in, S32 maxlen); +LL_COMMON_API std::string ll_safe_string(const char* in); +LL_COMMON_API std::string ll_safe_string(const char* in, S32 maxlen); // Allowing assignments from non-strings into format_map_t is apparently @@ -206,6 +242,9 @@ private: template class LLStringUtilBase { +private: + static std::string sLocale; + public: typedef typename std::basic_string::size_type size_type; @@ -213,10 +252,18 @@ public: ///////////////////////////////////////////////////////////////////////////////////////// // Static Utility functions that operate on std::strings - static std::basic_string const null; + static const std::basic_string null; typedef std::map format_map_t; - static S32 format(std::basic_string& s, const format_map_t& fmt_map); + LL_COMMON_API static void getTokens(const std::basic_string& instr, std::vector >& tokens, const std::basic_string& delims); + LL_COMMON_API static void formatNumber(std::basic_string& numStr, std::basic_string decimals); + LL_COMMON_API static bool formatDatetime(std::basic_string& replacement, std::basic_string token, std::basic_string param, S32 secFromEpoch); + LL_COMMON_API static S32 format(std::basic_string& s, const format_map_t& substitutions); + LL_COMMON_API static S32 format(std::basic_string& s, const LLSD& substitutions); + LL_COMMON_API static bool simpleReplacement(std::basic_string& replacement, std::basic_string token, const format_map_t& substitutions); + LL_COMMON_API static bool simpleReplacement(std::basic_string& replacement, std::basic_string token, const LLSD& substitutions); + LL_COMMON_API static void setLocale (std::string inLocale); + LL_COMMON_API static std::string getLocale (void); static bool isValidIndex(const std::basic_string& string, size_type i) { @@ -233,7 +280,25 @@ public: // True if this is the head of s. static BOOL isHead( const std::basic_string& string, const T* s ); - + + /** + * @brief Returns true if string starts with substr + * + * If etither string or substr are empty, this method returns false. + */ + static bool startsWith( + const std::basic_string& string, + const std::basic_string& substr); + + /** + * @brief Returns true if string ends in substr + * + * If etither string or substr are empty, this method returns false. + */ + static bool endsWith( + const std::basic_string& string, + const std::basic_string& substr); + static void addCRLF(std::basic_string& string); static void removeCRLF(std::basic_string& string); @@ -298,13 +363,19 @@ public: // Copies src into dst at a given offset. static void copyInto(std::basic_string& dst, const std::basic_string& src, size_type offset); + static bool isPartOfWord(T c) { return (c == (T)'_') || LLStringOps::isAlnum(c); } + + #ifdef _DEBUG - static void testHarness(); + LL_COMMON_API static void testHarness(); #endif +private: + LL_COMMON_API static size_type getSubstitution(const std::basic_string& instr, size_type& start, std::vector >& tokens); }; -template std::basic_string const LLStringUtilBase::null; +template const std::basic_string LLStringUtilBase::null; +template std::string LLStringUtilBase::sLocale; typedef LLStringUtilBase LLStringUtil; typedef LLStringUtilBase LLWStringUtil; @@ -366,6 +437,7 @@ LL_COMMON_API U8 hex_as_nybble(char hex); * @return Returns true on success. If false, str is unmodified. */ LL_COMMON_API bool _read_file_into_string(std::string& str, const std::string& filename); +LL_COMMON_API bool iswindividual(llwchar elem); /** * Unicode support @@ -495,7 +567,20 @@ using snprintf_hack::snprintf; * * This replaces the unsafe W2A macro from ATL. */ -LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in); +LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page); + +/** + * Converts a string to wide string. + * + * It will allocate memory for result string with "new []". Don't forget to release it with "delete []". + */ +LL_COMMON_API wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page); + +/** + * Converts incoming string into urf8 string + * + */ +LL_COMMON_API std::string ll_convert_string_to_utf8_string(const std::string& in); //@} #endif // LL_WINDOWS @@ -558,63 +643,12 @@ namespace LLStringFn } //////////////////////////////////////////////////////////// +// NOTE: LLStringUtil::format, getTokens, and support functions moved to llstring.cpp. +// There is no LLWStringUtil::format implementation currently. +// Calling thse for anything other than LLStringUtil will produce link errors. -// LLStringBase::format() -// -// This function takes a string 's' and a map 'fmt_map' of strings-to-strings. -// All occurances of strings in 's' from the left-hand side of 'fmt_map' are -// then replaced with the corresponding right-hand side of 'fmt_map', non- -// recursively. The function returns the number of substitutions made. +//////////////////////////////////////////////////////////// -// static -template -S32 LLStringUtilBase::format(std::basic_string& s, const format_map_t& fmt_map) -{ - typedef typename std::basic_string::size_type string_size_type_t; - string_size_type_t scanstart = 0; - S32 res = 0; - - // Look for the first match of any keyword, replace that keyword, - // repeat from the end of the replacement string. This avoids - // accidentally performing substitution on a substituted string. - while (1) - { - string_size_type_t first_match_pos = scanstart; - string_size_type_t first_match_str_length = 0; - std::basic_string first_match_str_replacement; - - for (format_map_t::const_iterator iter = fmt_map.begin(); - iter != fmt_map.end(); - ++iter) - { - string_size_type_t n = s.find(iter->first, scanstart); - if (n != std::basic_string::npos && - (n < first_match_pos || - 0 == first_match_str_length)) - { - first_match_pos = n; - first_match_str_length = iter->first.length(); - first_match_str_replacement = iter->second; - } - } - - if (0 == first_match_str_length) - { - // no more keys found to substitute from this point - // in the string forward. - break; - } - else - { - s.erase(first_match_pos, first_match_str_length); - s.insert(first_match_pos, first_match_str_replacement); - scanstart = first_match_pos + - first_match_str_replacement.length(); - ++res; - } - } - return res; -} // static template @@ -1003,14 +1037,15 @@ void LLStringUtilBase::stripNonprintable(std::basic_string& string) { return; } - char* c_string = new char[string.size() + 1]; + size_t src_size = string.size(); + char* c_string = new char[src_size + 1]; if(c_string == NULL) { return; } - strcpy(c_string, string.c_str()); /*Flawfinder: ignore*/ + copy(c_string, string.c_str(), src_size+1); char* write_head = &c_string[0]; - for (size_type i = 0; i < string.size(); i++) + for (size_type i = 0; i < src_size; i++) { char* read_head = &string[i]; write_head = &c_string[j]; @@ -1090,6 +1125,30 @@ BOOL LLStringUtilBase::isHead( const std::basic_string& string, const T* s } } +// static +template +bool LLStringUtilBase::startsWith( + const std::basic_string& string, + const std::basic_string& substr) +{ + if(string.empty() || (substr.empty())) return false; + if(0 == string.find(substr)) return true; + return false; +} + +// static +template +bool LLStringUtilBase::endsWith( + const std::basic_string& string, + const std::basic_string& substr) +{ + if(string.empty() || (substr.empty())) return false; + std::string::size_type idx = string.rfind(substr); + if(std::string::npos == idx) return false; + return (idx == (string.size() - substr.size())); +} + + template BOOL LLStringUtilBase::convertToBOOL(const std::basic_string& string, BOOL& value) { diff --git a/indra/llcommon/llstringtable.cpp b/indra/llcommon/llstringtable.cpp index 27f9036b8..2f3a994d8 100644 --- a/indra/llcommon/llstringtable.cpp +++ b/indra/llcommon/llstringtable.cpp @@ -38,6 +38,23 @@ LLStringTable gStringTable(32768); +LLStringTableEntry::LLStringTableEntry(const char *str) +: mString(NULL), mCount(1) +{ + // Copy string + U32 length = (U32)strlen(str) + 1; /*Flawfinder: ignore*/ + length = llmin(length, MAX_STRINGS_LENGTH); + mString = new char[length]; + strncpy(mString, str, length); /*Flawfinder: ignore*/ + mString[length - 1] = 0; +} + +LLStringTableEntry::~LLStringTableEntry() +{ + delete [] mString; + mCount = 0; +} + LLStringTable::LLStringTable(int tablesize) : mUniqueEntries(0) { diff --git a/indra/llcommon/llstringtable.h b/indra/llcommon/llstringtable.h index 238701dfd..d40c9d8df 100644 --- a/indra/llcommon/llstringtable.h +++ b/indra/llcommon/llstringtable.h @@ -49,11 +49,11 @@ #endif #if STRING_TABLE_HASH_MAP -#if LL_WINDOWS -#include -#else -#include -#endif +# if LL_WINDOWS +# include +# else +# include +# endif #endif const U32 MAX_STRINGS_LENGTH = 256; @@ -61,21 +61,9 @@ const U32 MAX_STRINGS_LENGTH = 256; class LL_COMMON_API LLStringTableEntry { public: - LLStringTableEntry(const char *str) - : mString(NULL), mCount(1) - { - // Copy string - U32 length = (U32)strlen(str) + 1; /*Flawfinder: ignore*/ - length = llmin(length, MAX_STRINGS_LENGTH); - mString = new char[length]; - strncpy(mString, str, length); /*Flawfinder: ignore*/ - mString[length - 1] = 0; - } - ~LLStringTableEntry() - { - delete [] mString; - mCount = 0; - } + LLStringTableEntry(const char *str); + ~LLStringTableEntry(); + void incCount() { mCount++; } BOOL decCount() { return --mCount; } diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index bde0cbd6e..d729d9883 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -74,7 +74,7 @@ extern int errno; static const S32 CPUINFO_BUFFER_SIZE = 16383; -LL_COMMON_API LLCPUInfo gSysCPU; +LLCPUInfo gSysCPU; #if LL_WINDOWS #ifndef DLLVERSIONINFO diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h index e481c8838..10f963d50 100644 --- a/indra/llcommon/llsys.h +++ b/indra/llcommon/llsys.h @@ -131,10 +131,10 @@ LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLCPUInfo& info); LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLMemoryInfo& info); // gunzip srcfile into dstfile. Returns FALSE on error. -LL_COMMON_API BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile); +BOOL LL_COMMON_API gunzip_file(const std::string& srcfile, const std::string& dstfile); // gzip srcfile into dstfile. Returns FALSE on error. -LL_COMMON_API BOOL gzip_file(const std::string& srcfile, const std::string& dstfile); +BOOL LL_COMMON_API gzip_file(const std::string& srcfile, const std::string& dstfile); -LL_COMMON_API extern LLCPUInfo gSysCPU; +extern LL_COMMON_API LLCPUInfo gSysCPU; #endif // LL_LLSYS_H diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index c0d47890c..34e19f83f 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -33,7 +33,6 @@ #include "linden_common.h" #include "lltimer.h" -#include "timing.h" // totalTime prototype. #include "u64.h" @@ -52,6 +51,9 @@ // // Locally used constants // +const U32 SEC_PER_DAY = 86400; +const F64 SEC_TO_MICROSEC = 1000000.f; +const U64 SEC_TO_MICROSEC_U64 = 1000000; const F64 USEC_TO_SEC_F64 = 0.000001; @@ -571,59 +573,6 @@ void timeStructToFormattedString(struct tm * time, std::string format, std::stri } -////////////////////////////////////////////////////////////////////////////// -// -// LLEventTimer Implementation -// -////////////////////////////////////////////////////////////////////////////// - -std::list LLEventTimer::sActiveList; - -LLEventTimer::LLEventTimer(F32 period) -: mEventTimer() -{ - mPeriod = period; - sActiveList.push_back(this); -} - -LLEventTimer::LLEventTimer(const LLDate& time) -: mEventTimer() -{ - mPeriod = (F32)(time.secondsSinceEpoch() - LLDate::now().secondsSinceEpoch()); - sActiveList.push_back(this); -} -LLEventTimer::~LLEventTimer() -{ - sActiveList.remove(this); -} - -void LLEventTimer::updateClass() -{ - std::list completed_timers; - for (std::list::iterator iter = sActiveList.begin(); iter != sActiveList.end(); ) - { - LLEventTimer* timer = *iter++; - F32 et = timer->mEventTimer.getElapsedTimeF32(); - if (timer->mEventTimer.getStarted() && et > timer->mPeriod) { - timer->mEventTimer.reset(); - if ( timer->tick() ) - { - completed_timers.push_back( timer ); - } - } - } - - if ( completed_timers.size() > 0 ) - { - for (std::list::iterator completed_iter = completed_timers.begin(); - completed_iter != completed_timers.end(); - completed_iter++ ) - { - delete *completed_iter; - } - } -} - diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h index 26734919c..68f06fdce 100644 --- a/indra/llcommon/lltimer.h +++ b/indra/llcommon/lltimer.h @@ -55,6 +55,8 @@ const U32 USEC_PER_HOUR = USEC_PER_MIN * MIN_PER_HOUR; const U32 SEC_PER_HOUR = SEC_PER_MIN * MIN_PER_HOUR; const F64 SEC_PER_USEC = 1.0 / (F64) USEC_PER_SEC; +LL_COMMON_API U64 totalTime(); // Returns current system time in microseconds + class LL_COMMON_API LLTimer { public: @@ -155,7 +157,7 @@ static inline time_t time_max() } // Correction factor used by time_corrected() above. -LL_COMMON_API extern S32 gUTCOffset; +extern LL_COMMON_API S32 gUTCOffset; // Is the current computer (in its current time zone) // observing daylight savings time? @@ -173,27 +175,4 @@ LL_COMMON_API void secondsToTimecodeString(F32 current_time, std::string& tcstri LL_COMMON_API void timeToFormattedString(time_t time, std::string format, std::string ×tr); LL_COMMON_API void timeStructToFormattedString(struct tm * time, std::string format, std::string ×tr); -// class for scheduling a function to be called at a given frequency (approximate, inprecise) -class LL_COMMON_API LLEventTimer -{ -public: - LLEventTimer(F32 period); // period is the amount of time between each call to tick() in seconds - LLEventTimer(const LLDate& time); - virtual ~LLEventTimer(); - - //function to be called at the supplied frequency - // Normally return FALSE; TRUE will delete the timer after the function returns. - virtual BOOL tick() = 0; - - static void updateClass(); - -protected: - LLTimer mEventTimer; - F32 mPeriod; - -private: - //list of active timers - static std::list sActiveList; // TODO should this be a vector -}; - #endif diff --git a/indra/llcommon/processor.h b/indra/llcommon/processor.h deleted file mode 100644 index 5ba55402b..000000000 --- a/indra/llcommon/processor.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file processor.h - * @brief Legacy wrapper header. - * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llprocessor.h" diff --git a/indra/llcommon/timing.h b/indra/llcommon/timing.h index cfc637eb6..140ce1fca 100644 --- a/indra/llcommon/timing.h +++ b/indra/llcommon/timing.h @@ -43,7 +43,6 @@ const F32 SEC_TO_MICROSEC = 1000000.f; const U64 SEC_TO_MICROSEC_U64 = 1000000; const U32 SEC_PER_DAY = 86400; -// This is just a stub, implementation in lltimer.cpp. This file will be deprecated in the future. -LL_COMMON_API U64 totalTime(); // Returns current system time in microseconds +// functionality has been moved lltimer.{cpp,h}. This file will be deprecated in the future. #endif diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp index e6b6797c6..da71cae9d 100644 --- a/indra/llmath/llcamera.cpp +++ b/indra/llmath/llcamera.cpp @@ -45,7 +45,8 @@ LLCamera::LLCamera() : mNearPlane(DEFAULT_NEAR_PLANE), mFarPlane(DEFAULT_FAR_PLANE), mFixedDistance(-1.f), - mPlaneCount(6) + mPlaneCount(6), + mFrustumCornerDist(0.f) { calculateFrustumPlanes(); } @@ -55,7 +56,8 @@ LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_p LLCoordFrame(), mViewHeightInPixels(view_height_in_pixels), mFixedDistance(-1.f), - mPlaneCount(6) + mPlaneCount(6), + mFrustumCornerDist(0.f) { mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO); mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE); @@ -65,6 +67,10 @@ LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_p setView(vertical_fov_rads); } +LLCamera::~LLCamera() +{ + +} // ---------------- LLCamera::getFoo() member functions ---------------- @@ -86,11 +92,11 @@ F32 LLCamera::getMaxView() const // ---------------- LLCamera::setFoo() member functions ---------------- -void LLCamera::setUserClipPlane(LLPlane plane) +void LLCamera::setUserClipPlane(LLPlane& plane) { mPlaneCount = 7; - mAgentPlanes[6].p = plane; - mAgentPlanes[6].mask = calcPlaneMask(plane); + mAgentPlanes[6] = plane; + mPlaneMask[6] = plane.calcPlaneMask(); } void LLCamera::disableUserClipPlane() @@ -178,7 +184,7 @@ S32 LLCamera::AABBInFrustum(const LLVector3 ¢er, const LLVector3& radius) U8 mask = 0; S32 result = 2; - if (radius.magVecSquared() > mFrustumCornerDist * mFrustumCornerDist) + /*if (radius.magVecSquared() > mFrustumCornerDist * mFrustumCornerDist) { //box is larger than frustum, check frustum quads against box planes static const LLVector3 dir[] = @@ -241,12 +247,16 @@ S32 LLCamera::AABBInFrustum(const LLVector3 ¢er, const LLVector3& radius) result = 1; } } - else + else*/ { for (U32 i = 0; i < mPlaneCount; i++) { - mask = mAgentPlanes[i].mask; - LLPlane p = mAgentPlanes[i].p; + mask = mPlaneMask[i]; + if (mask == 0xff) + { + continue; + } + LLPlane p = mAgentPlanes[i]; LLVector3 n = LLVector3(p); float d = p.mV[3]; LLVector3 rscale = radius.scaledVec(scaler[mask]); @@ -293,8 +303,12 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector3 ¢er, const LLVector3& r continue; } - mask = mAgentPlanes[i].mask; - LLPlane p = mAgentPlanes[i].p; + mask = mPlaneMask[i]; + if (mask == 0xff) + { + continue; + } + LLPlane p = mAgentPlanes[i]; LLVector3 n = LLVector3(p); float d = p.mV[3]; LLVector3 rscale = radius.scaledVec(scaler[mask]); @@ -434,23 +448,22 @@ int LLCamera::sphereInFrustumOld(const LLVector3 &sphere_center, const F32 radiu int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius) const { // Returns 1 if sphere is in frustum, 0 if not. - int res = 2; + bool res = false; for (int i = 0; i < 6; i++) { - float d = mAgentPlanes[i].p.dist(sphere_center); - - if (d > radius) + if (mPlaneMask[i] != 0xff) { - return 0; - } + float d = mAgentPlanes[i].dist(sphere_center); - if (d > -radius) - { - res = 1; + if (d > radius) + { + return 0; + } + res = res || (d > -radius); } } - return res; + return res?1:2; } @@ -602,29 +615,20 @@ LLPlane planeFromPoints(LLVector3 p1, LLVector3 p2, LLVector3 p3) return LLPlane(p1, n); } -U8 LLCamera::calcPlaneMask(const LLPlane& plane) + +void LLCamera::ignoreAgentFrustumPlane(S32 idx) { - U8 mask = 0; - - if (plane.mV[0] >= 0) + if (idx < 0 || idx > (S32) mPlaneCount) { - mask |= 1; - } - if (plane.mV[1] >= 0) - { - mask |= 2; - } - if (plane.mV[2] >= 0) - { - mask |= 4; + return; } - return mask; + mPlaneMask[idx] = 0xff; + mAgentPlanes[idx].clear(); } void LLCamera::calcAgentFrustumPlanes(LLVector3* frust) { - for (int i = 0; i < 8; i++) { mAgentFrustum[i] = frust[i]; @@ -637,27 +641,27 @@ void LLCamera::calcAgentFrustumPlanes(LLVector3* frust) //order of planes is important, keep most likely to fail in the front of the list //near - frust[0], frust[1], frust[2] - mAgentPlanes[2].p = planeFromPoints(frust[0], frust[1], frust[2]); + mAgentPlanes[2] = planeFromPoints(frust[0], frust[1], frust[2]); //far - mAgentPlanes[5].p = planeFromPoints(frust[5], frust[4], frust[6]); + mAgentPlanes[5] = planeFromPoints(frust[5], frust[4], frust[6]); //left - mAgentPlanes[0].p = planeFromPoints(frust[4], frust[0], frust[7]); + mAgentPlanes[0] = planeFromPoints(frust[4], frust[0], frust[7]); //right - mAgentPlanes[1].p = planeFromPoints(frust[1], frust[5], frust[6]); + mAgentPlanes[1] = planeFromPoints(frust[1], frust[5], frust[6]); //top - mAgentPlanes[4].p = planeFromPoints(frust[3], frust[2], frust[6]); + mAgentPlanes[4] = planeFromPoints(frust[3], frust[2], frust[6]); //bottom - mAgentPlanes[3].p = planeFromPoints(frust[1], frust[0], frust[4]); + mAgentPlanes[3] = planeFromPoints(frust[1], frust[0], frust[4]); //cache plane octant facing mask for use in AABBInFrustum for (U32 i = 0; i < mPlaneCount; i++) { - mAgentPlanes[i].mask = calcPlaneMask(mAgentPlanes[i].p); + mPlaneMask[i] = mAgentPlanes[i].calcPlaneMask(); } } diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h index 85b93dfc9..38555b1e7 100644 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -70,6 +70,12 @@ class LLCamera : public LLCoordFrame { public: + + LLCamera(const LLCamera& rhs) + { + *this = rhs; + } + enum { PLANE_LEFT = 0, PLANE_RIGHT = 1, @@ -84,6 +90,17 @@ public: PLANE_TOP_MASK = (1< 0.f) ? 1.f : -1.f; + F32 new_foo = F32( S64(foo * bar + sign * 0.5f)); + new_foo /= bar; + + return new_foo; } inline F32 lerp(F32 a, F32 b, F32 u) @@ -522,4 +525,41 @@ inline F32 llgaussian(F32 x, F32 o) return 1.f/(F_SQRT_TWO_PI*o)*powf(F_E, -(x*x)/(2*o*o)); } +//helper function for removing outliers +template +inline void ll_remove_outliers(std::vector& data, F32 k) +{ + if (data.size() < 100) + { //not enough samples + return; + } + + VEC_TYPE Q1 = data[data.size()/4]; + VEC_TYPE Q3 = data[data.size()-data.size()/4-1]; + + VEC_TYPE min = (VEC_TYPE) ((F32) Q1-k * (F32) (Q3-Q1)); + VEC_TYPE max = (VEC_TYPE) ((F32) Q3+k * (F32) (Q3-Q1)); + + U32 i = 0; + while (i < data.size() && data[i] < min) + { + i++; + } + + S32 j = data.size()-1; + while (j > 0 && data[j] > max) + { + j--; + } + + if (j < data.size()-1) + { + data.erase(data.begin()+j, data.end()); + } + + if (i > 0) + { + data.erase(data.begin(), data.begin()+i); + } +} #endif diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index ced65d1d9..86589b87e 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -73,6 +73,13 @@ public: virtual void visit(const LLOctreeNode* branch) = 0; }; +template +class LLOctreeTravelerDepthFirst : public LLOctreeTraveler +{ +public: + virtual void traverse(const LLOctreeNode* node); +}; + template class LLOctreeNode : public LLTreeNode { @@ -124,11 +131,10 @@ public: inline void setParent(BaseType* parent) { mParent = (oct_node*) parent; } inline const LLVector3d& getCenter() const { return mCenter; } inline const LLVector3d& getSize() const { return mSize; } - inline void setCenter(LLVector3d center) { mCenter = center; } - inline void setSize(LLVector3d size) { mSize = size; } - inline oct_node* getNodeAt(T* data) { return getNodeAt(data->getPositionGroup(), data->getBinRadius()); } - inline U8 getOctant() const { return mOctant; } - inline void setOctant(U8 octant) { mOctant = octant; } + inline void setCenter(const LLVector3d center) { mCenter = center; } + inline void setSize(const LLVector3d size) { mSize = size; } + inline oct_node* getNodeAt(T* data) { return getNodeAt(data->getPositionGroup(), data->getBinRadius()); } + inline U8 getOctant() const { return mOctant; } inline const oct_node* getOctParent() const { return (const oct_node*) getParent(); } inline oct_node* getOctParent() { return (oct_node*) getParent(); } @@ -197,17 +203,17 @@ public: return contains(xform->getBinRadius()); } - bool contains(F64 radius) + bool contains(F32 radius) { if (mParent == NULL) { //root node contains nothing return false; } - F64 size = mSize.mdV[0]; - F64 p_size = size * 2.0; + F32 size = mSize[0]; + F32 p_size = size * 2.f; - return (radius <= 0.001 && size <= 0.001) || + return (radius <= 0.001f && size <= 0.001f) || (radius <= p_size && radius > size); } @@ -243,7 +249,30 @@ public: void accept(tree_traveler* visitor) const { visitor->visit(this); } void accept(oct_traveler* visitor) const { visitor->visit(this); } - oct_node* getNodeAt(const LLVector3d& pos, const F64& rad) + void validateChildMap() + { + for (U32 i = 0; i < 8; i++) + { + U8 idx = mChildMap[i]; + if (idx != 255) + { + LLOctreeNode* child = mChild[idx]; + + if (child->getOctant() != i) + { + llerrs << "Invalid child map, bad octant data." << llendl; + } + + if (getOctant(child->getCenter()) != child->getOctant()) + { + llerrs << "Invalid child octant compared to position data." << llendl; + } + } + } + } + + + oct_node* getNodeAt(const LLVector3d& pos, const F32& rad) { LLOctreeNode* node = this; @@ -251,24 +280,18 @@ public: { //do a quick search by octant U8 octant = node->getOctant(pos.mdV); - BOOL keep_going = TRUE; - + //traverse the tree until we find a node that has no node //at the appropriate octant or is smaller than the object. //by definition, that node is the smallest node that contains // the data - while (keep_going && node->getSize().mdV[0] >= rad) + U8 next_node = node->mChildMap[octant]; + + while (next_node != 255 && node->getSize()[0] >= rad) { - keep_going = FALSE; - for (U32 i = 0; i < node->getChildCount() && !keep_going; i++) - { - if (node->getChild(i)->getOctant() == octant) - { - node = node->getChild(i); - octant = node->getOctant(pos.mdV); - keep_going = TRUE; - } - } + node = node->getChild(next_node); + octant = node->getOctant(pos.mdV); + next_node = node->mChildMap[octant]; } } else if (!node->contains(rad) && node->getParent()) @@ -444,6 +467,9 @@ public: void clearChildren() { mChild.clear(); + + U32* foo = (U32*) mChildMap; + foo[0] = foo[1] = 0xFFFFFFFF; } void validate() @@ -477,6 +503,12 @@ public: void addChild(oct_node* child, BOOL silent = FALSE) { #if LL_OCTREE_PARANOIA_CHECK + + if (child->getSize() == getSize()) + { + OCT_ERRS << "Child size is same as parent size!" << llendl; + } + for (U32 i = 0; i < getChildCount(); i++) { if(mChild[i]->getSize() != child->getSize()) @@ -495,6 +527,8 @@ public: } #endif + mChildMap[child->getOctant()] = (U8) mChild.size(); + mChild.push_back(child); child->setParent(this); @@ -508,7 +542,7 @@ public: } } - void removeChild(U8 index, BOOL destroy = FALSE) + void removeChild(S32 index, BOOL destroy = FALSE) { for (U32 i = 0; i < this->getListenerCount(); i++) { @@ -516,6 +550,8 @@ public: listener->handleChildRemoval(this, getChild(index)); } + + if (destroy) { mChild[index]->destroy(); @@ -523,6 +559,15 @@ public: } mChild.erase(mChild.begin() + index); + //rebuild child map + U32* foo = (U32*) mChildMap; + foo[0] = foo[1] = 0xFFFFFFFF; + + for (U32 i = 0; i < mChild.size(); ++i) + { + mChildMap[mChild[i]->getOctant()] = i; + } + checkAlive(); } @@ -553,14 +598,27 @@ public: } protected: - child_list mChild; - element_list mData; - oct_node* mParent; + typedef enum + { + CENTER = 0, + SIZE = 1, + MAX = 2, + MIN = 3 + } eDName; + LLVector3d mCenter; LLVector3d mSize; LLVector3d mMax; LLVector3d mMin; + + oct_node* mParent; U8 mOctant; + + child_list mChild; + U8 mChildMap[8]; + + element_list mData; + }; //just like a regular node, except it might expand on insert and compress on balance @@ -571,8 +629,8 @@ public: typedef LLOctreeNode BaseType; typedef LLOctreeNode oct_node; - LLOctreeRoot( LLVector3d center, - LLVector3d size, + LLOctreeRoot( const LLVector3d ¢er, + const LLVector3d &size, BaseType* parent) : BaseType(center, size, parent) { @@ -604,6 +662,8 @@ public: //destroy child child->clearChildren(); delete child; + + return false; } return true; @@ -700,7 +760,6 @@ public: } }; - //======================== // LLOctreeTraveler //======================== @@ -714,4 +773,14 @@ void LLOctreeTraveler::traverse(const LLOctreeNode* node) } } +template +void LLOctreeTravelerDepthFirst::traverse(const LLOctreeNode* node) +{ + for (U32 i = 0; i < node->getChildCount(); i++) + { + traverse(node->getChild(i)); + } + node->accept(this); +} + #endif diff --git a/indra/llmath/llplane.h b/indra/llmath/llplane.h index 89c6a1460..ebfe77a9c 100644 --- a/indra/llmath/llplane.h +++ b/indra/llmath/llplane.h @@ -48,13 +48,13 @@ public: LLPlane() {}; // no default constructor LLPlane(const LLVector3 &p0, F32 d) { setVec(p0, d); } LLPlane(const LLVector3 &p0, const LLVector3 &n) { setVec(p0, n); } - void setVec(const LLVector3 &p0, F32 d) { LLVector4::setVec(p0[0], p0[1], p0[2], d); } - void setVec(const LLVector3 &p0, const LLVector3 &n) + inline void setVec(const LLVector3 &p0, F32 d) { LLVector4::setVec(p0[0], p0[1], p0[2], d); } + inline void setVec(const LLVector3 &p0, const LLVector3 &n) { F32 d = -(p0 * n); setVec(n, d); } - void setVec(const LLVector3 &p0, const LLVector3 &p1, const LLVector3 &p2) + inline void setVec(const LLVector3 &p0, const LLVector3 &p1, const LLVector3 &p2) { LLVector3 u, v, w; u = p1 - p0; @@ -64,8 +64,39 @@ public: F32 d = -(w * p0); setVec(w, d); } - LLPlane& operator=(const LLVector4& v2) { LLVector4::setVec(v2[0],v2[1],v2[2],v2[3]); return *this;} + + inline LLPlane& operator=(const LLVector4& v2) { LLVector4::setVec(v2[0],v2[1],v2[2],v2[3]); return *this;} + + inline void set(const LLPlane& p2) { LLVector4::setVec(p2); } + + // F32 dist(const LLVector3 &v2) const { return mV[0]*v2[0] + mV[1]*v2[1] + mV[2]*v2[2] + mV[3]; } + + // reset the vector to 0, 0, 0, 1 + inline void clear() { LLVector4::setVec(0, 0, 0, 1); } + + inline void getVector3(LLVector3& vec) const { vec.set(mV[0], mV[1], mV[2]); } + + // Retrieve the mask indicating which of the x, y, or z axis are greater or equal to zero. + inline U8 calcPlaneMask() + { + U8 mask = 0; + + if (mV[0] >= 0) + { + mask |= 1; + } + if (mV[1] >= 0) + { + mask |= 2; + } + if (mV[2] >= 0) + { + mask |= 4; + } + + return mask; + } }; diff --git a/indra/llmath/llquaternion.cpp b/indra/llmath/llquaternion.cpp index fdcc19d65..73c5f4505 100644 --- a/indra/llmath/llquaternion.cpp +++ b/indra/llmath/llquaternion.cpp @@ -32,9 +32,10 @@ #include "linden_common.h" +#include "llmath.h" // for F_PI + #include "llquaternion.h" -#include "llmath.h" // for F_PI //#include "vmath.h" #include "v3math.h" #include "v3dmath.h" diff --git a/indra/llmath/llquaternion.h b/indra/llmath/llquaternion.h index 0769f29f2..a7bb09fae 100644 --- a/indra/llmath/llquaternion.h +++ b/indra/llmath/llquaternion.h @@ -33,7 +33,11 @@ #ifndef LLQUATERNION_H #define LLQUATERNION_H -#include "llmath.h" +#include + +#ifndef LLMATH_H //enforce specific include order to avoid tangling inline dependencies +#error "Please include llmath.h first." +#endif class LLVector4; class LLVector3; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index bc1a4fa9f..1ee561750 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -103,27 +103,33 @@ BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLV BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size) { - float fAWdU[3]; - LLVector3 dir; - LLVector3 diff; + return LLLineSegmentBoxIntersect(start.mV, end.mV, center.mV, size.mV); +} + +BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size) +{ + F32 fAWdU[3]; + F32 dir[3]; + F32 diff[3]; for (U32 i = 0; i < 3; i++) { - dir.mV[i] = 0.5f * (end.mV[i] - start.mV[i]); - diff.mV[i] = (0.5f * (end.mV[i] + start.mV[i])) - center.mV[i]; - fAWdU[i] = fabsf(dir.mV[i]); - if(fabsf(diff.mV[i])>size.mV[i] + fAWdU[i]) return false; + dir[i] = 0.5f * (end[i] - start[i]); + diff[i] = (0.5f * (end[i] + start[i])) - center[i]; + fAWdU[i] = fabsf(dir[i]); + if(fabsf(diff[i])>size[i] + fAWdU[i]) return false; } float f; - f = dir.mV[1] * diff.mV[2] - dir.mV[2] * diff.mV[1]; if(fabsf(f)>size.mV[1]*fAWdU[2] + size.mV[2]*fAWdU[1]) return false; - f = dir.mV[2] * diff.mV[0] - dir.mV[0] * diff.mV[2]; if(fabsf(f)>size.mV[0]*fAWdU[2] + size.mV[2]*fAWdU[0]) return false; - f = dir.mV[0] * diff.mV[1] - dir.mV[1] * diff.mV[0]; if(fabsf(f)>size.mV[0]*fAWdU[1] + size.mV[1]*fAWdU[0]) return false; + f = dir[1] * diff[2] - dir[2] * diff[1]; if(fabsf(f)>size[1]*fAWdU[2] + size[2]*fAWdU[1]) return false; + f = dir[2] * diff[0] - dir[0] * diff[2]; if(fabsf(f)>size[0]*fAWdU[2] + size[2]*fAWdU[0]) return false; + f = dir[0] * diff[1] - dir[1] * diff[0]; if(fabsf(f)>size[0]*fAWdU[1] + size[1]*fAWdU[0]) return false; return true; } + // intersect test between triangle vert0, vert1, vert2 and a ray from orig in direction dir. // returns TRUE if intersecting and returns barycentric coordinates in intersection_a, intersection_b, // and returns the intersection point along dir in intersection_t. @@ -1688,7 +1694,8 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge mGenerateSingleFace = generate_single_face; generate(); - if (mParams.getSculptID().isNull() && params.getSculptType() == LL_SCULPT_TYPE_NONE) + + if (mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE) { createVolumeFaces(); } diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index ddfac18cd..7bae2749e 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -984,6 +984,7 @@ LLVector3 calc_binormal_from_triangle( const LLVector3& pos2, const LLVector2& tex2); +BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size); BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size); BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir, F32* intersection_a, F32* intersection_b, F32* intersection_t, BOOL two_sided); diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp index d8e7b4aaf..74855bdc4 100644 --- a/indra/llmath/m4math.cpp +++ b/indra/llmath/m4math.cpp @@ -221,8 +221,33 @@ const LLMatrix4& LLMatrix4::transpose() F32 LLMatrix4::determinant() const { - llerrs << "Not implemented!" << llendl; - return 0.f; + F32 value = + mMatrix[0][3] * mMatrix[1][2] * mMatrix[2][1] * mMatrix[3][0] - + mMatrix[0][2] * mMatrix[1][3] * mMatrix[2][1] * mMatrix[3][0] - + mMatrix[0][3] * mMatrix[1][1] * mMatrix[2][2] * mMatrix[3][0] + + mMatrix[0][1] * mMatrix[1][3] * mMatrix[2][2] * mMatrix[3][0] + + mMatrix[0][2] * mMatrix[1][1] * mMatrix[2][3] * mMatrix[3][0] - + mMatrix[0][1] * mMatrix[1][2] * mMatrix[2][3] * mMatrix[3][0] - + mMatrix[0][3] * mMatrix[1][2] * mMatrix[2][0] * mMatrix[3][1] + + mMatrix[0][2] * mMatrix[1][3] * mMatrix[2][0] * mMatrix[3][1] + + mMatrix[0][3] * mMatrix[1][0] * mMatrix[2][2] * mMatrix[3][1] - + mMatrix[0][0] * mMatrix[1][3] * mMatrix[2][2] * mMatrix[3][1] - + mMatrix[0][2] * mMatrix[1][0] * mMatrix[2][3] * mMatrix[3][1] + + mMatrix[0][0] * mMatrix[1][2] * mMatrix[2][3] * mMatrix[3][1] + + mMatrix[0][3] * mMatrix[1][1] * mMatrix[2][0] * mMatrix[3][2] - + mMatrix[0][1] * mMatrix[1][3] * mMatrix[2][0] * mMatrix[3][2] - + mMatrix[0][3] * mMatrix[1][0] * mMatrix[2][1] * mMatrix[3][2] + + mMatrix[0][0] * mMatrix[1][3] * mMatrix[2][1] * mMatrix[3][2] + + mMatrix[0][1] * mMatrix[1][0] * mMatrix[2][3] * mMatrix[3][2] - + mMatrix[0][0] * mMatrix[1][1] * mMatrix[2][3] * mMatrix[3][2] - + mMatrix[0][2] * mMatrix[1][1] * mMatrix[2][0] * mMatrix[3][3] + + mMatrix[0][1] * mMatrix[1][2] * mMatrix[2][0] * mMatrix[3][3] + + mMatrix[0][2] * mMatrix[1][0] * mMatrix[2][1] * mMatrix[3][3] - + mMatrix[0][0] * mMatrix[1][2] * mMatrix[2][1] * mMatrix[3][3] - + mMatrix[0][1] * mMatrix[1][0] * mMatrix[2][2] * mMatrix[3][3] + + mMatrix[0][0] * mMatrix[1][1] * mMatrix[2][2] * mMatrix[3][3]; + + return value; } // Only works for pure orthonormal, homogeneous transform matrices. @@ -428,6 +453,17 @@ const LLMatrix4& LLMatrix4::initRotTrans(const LLQuaternion &q, const LLVector return (*this); } +const LLMatrix4& LLMatrix4::initScale(const LLVector3 &scale) +{ + setIdentity(); + + mMatrix[VX][VX] = scale.mV[VX]; + mMatrix[VY][VY] = scale.mV[VY]; + mMatrix[VZ][VZ] = scale.mV[VZ]; + + return (*this); +} + const LLMatrix4& LLMatrix4::initAll(const LLVector3 &scale, const LLQuaternion &q, const LLVector3 &pos) { F32 sx, sy, sz; @@ -774,6 +810,23 @@ bool operator!=(const LLMatrix4 &a, const LLMatrix4 &b) return FALSE; } +bool operator<(const LLMatrix4& a, const LLMatrix4 &b) +{ + U32 i, j; + for (i = 0; i < NUM_VALUES_IN_MAT4; i++) + { + for (j = 0; j < NUM_VALUES_IN_MAT4; j++) + { + if (a.mMatrix[i][j] != b.mMatrix[i][j]) + { + return a.mMatrix[i][j] < b.mMatrix[i][j]; + } + } + } + + return false; +} + const LLMatrix4& operator*=(LLMatrix4 &a, F32 k) { U32 i, j; @@ -813,4 +866,54 @@ std::ostream& operator<<(std::ostream& s, const LLMatrix4 &a) return s; } +LLSD LLMatrix4::getValue() const +{ + LLSD ret; + + ret[0] = mMatrix[0][0]; + ret[1] = mMatrix[0][1]; + ret[2] = mMatrix[0][2]; + ret[3] = mMatrix[0][3]; + + ret[4] = mMatrix[1][0]; + ret[5] = mMatrix[1][1]; + ret[6] = mMatrix[1][2]; + ret[7] = mMatrix[1][3]; + + ret[8] = mMatrix[2][0]; + ret[9] = mMatrix[2][1]; + ret[10] = mMatrix[2][2]; + ret[11] = mMatrix[2][3]; + + ret[12] = mMatrix[3][0]; + ret[13] = mMatrix[3][1]; + ret[14] = mMatrix[3][2]; + ret[15] = mMatrix[3][3]; + + return ret; +} + +void LLMatrix4::setValue(const LLSD& data) +{ + mMatrix[0][0] = data[0].asReal(); + mMatrix[0][1] = data[1].asReal(); + mMatrix[0][2] = data[2].asReal(); + mMatrix[0][3] = data[3].asReal(); + + mMatrix[1][0] = data[4].asReal(); + mMatrix[1][1] = data[5].asReal(); + mMatrix[1][2] = data[6].asReal(); + mMatrix[1][3] = data[7].asReal(); + + mMatrix[2][0] = data[8].asReal(); + mMatrix[2][1] = data[9].asReal(); + mMatrix[2][2] = data[10].asReal(); + mMatrix[2][3] = data[11].asReal(); + + mMatrix[3][0] = data[12].asReal(); + mMatrix[3][1] = data[13].asReal(); + mMatrix[3][2] = data[14].asReal(); + mMatrix[3][3] = data[15].asReal(); +} + diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h index e74b7afe9..27e4be4b4 100644 --- a/indra/llmath/m4math.h +++ b/indra/llmath/m4math.h @@ -125,6 +125,8 @@ public: ~LLMatrix4(void); // Destructor + LLSD getValue() const; + void setValue(const LLSD&); ////////////////////////////// // @@ -138,6 +140,7 @@ public: // various useful matrix functions const LLMatrix4& setIdentity(); // Load identity matrix + bool isIdentity() const; const LLMatrix4& setZero(); // Clears matrix to all zeros. const LLMatrix4& initRotation(const F32 angle, const F32 x, const F32 y, const F32 z); // Calculate rotation matrix by rotating angle radians about (x, y, z) @@ -159,6 +162,7 @@ public: const LLMatrix4& initRotTrans(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &pos); // Rotation from Euler + translation const LLMatrix4& initRotTrans(const LLQuaternion &q, const LLVector4 &pos); // Set with Quaternion and position + const LLMatrix4& initScale(const LLVector3 &scale); // Set all const LLMatrix4& initAll(const LLVector3 &scale, const LLQuaternion &q, const LLVector3 &pos); @@ -236,6 +240,7 @@ public: friend bool operator==(const LLMatrix4 &a, const LLMatrix4 &b); // Return a == b friend bool operator!=(const LLMatrix4 &a, const LLMatrix4 &b); // Return a != b + friend bool operator<(const LLMatrix4 &a, const LLMatrix4& b); // Return a < b friend const LLMatrix4& operator+=(LLMatrix4 &a, const LLMatrix4 &b); // Return a + b friend const LLMatrix4& operator-=(LLMatrix4 &a, const LLMatrix4 &b); // Return a - b @@ -269,6 +274,30 @@ inline const LLMatrix4& LLMatrix4::setIdentity() return (*this); } +inline bool LLMatrix4::isIdentity() const +{ + return + mMatrix[0][0] == 1.f && + mMatrix[0][1] == 0.f && + mMatrix[0][2] == 0.f && + mMatrix[0][3] == 0.f && + + mMatrix[1][0] == 0.f && + mMatrix[1][1] == 1.f && + mMatrix[1][2] == 0.f && + mMatrix[1][3] == 0.f && + + mMatrix[2][0] == 0.f && + mMatrix[2][1] == 0.f && + mMatrix[2][2] == 1.f && + mMatrix[2][3] == 0.f && + + mMatrix[3][0] == 0.f && + mMatrix[3][1] == 0.f && + mMatrix[3][2] == 0.f && + mMatrix[3][3] == 1.f; +} + /* inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b) diff --git a/indra/llmath/v2math.cpp b/indra/llmath/v2math.cpp index 555e1f92b..220336e0c 100644 --- a/indra/llmath/v2math.cpp +++ b/indra/llmath/v2math.cpp @@ -115,3 +115,18 @@ LLVector2 lerp(const LLVector2 &a, const LLVector2 &b, F32 u) a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u, a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u ); } + +LLSD LLVector2::getValue() const +{ + LLSD ret; + ret[0] = mV[0]; + ret[1] = mV[1]; + return ret; +} + +void LLVector2::setValue(LLSD& sd) +{ + mV[0] = (F32) sd[0].asReal(); + mV[1] = (F32) sd[1].asReal(); +} + diff --git a/indra/llmath/v2math.h b/indra/llmath/v2math.h index 65f371431..ae26c85ce 100644 --- a/indra/llmath/v2math.h +++ b/indra/llmath/v2math.h @@ -66,6 +66,9 @@ class LLVector2 void set(const LLVector2 &vec); // Sets LLVector2 to vec void set(const F32 *vec); // Sets LLVector2 to vec + LLSD getValue() const; + void setValue(LLSD& sd); + void setVec(F32 x, F32 y); // deprecated void setVec(const LLVector2 &vec); // deprecated void setVec(const F32 *vec); // deprecated diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp index 63683ed49..daabbcc37 100644 --- a/indra/llmath/v3math.cpp +++ b/indra/llmath/v3math.cpp @@ -140,6 +140,21 @@ BOOL LLVector3::clampLength( F32 length_limit ) return changed; } +BOOL LLVector3::clamp(const LLVector3 &min_vec, const LLVector3 &max_vec) +{ + BOOL ret = FALSE; + + if (mV[0] < min_vec[0]) { mV[0] = min_vec[0]; ret = TRUE; } + if (mV[1] < min_vec[1]) { mV[1] = min_vec[1]; ret = TRUE; } + if (mV[2] < min_vec[2]) { mV[2] = min_vec[2]; ret = TRUE; } + + if (mV[0] > max_vec[0]) { mV[0] = max_vec[0]; ret = TRUE; } + if (mV[1] > max_vec[1]) { mV[1] = max_vec[1]; ret = TRUE; } + if (mV[2] > max_vec[2]) { mV[2] = max_vec[2]; ret = TRUE; } + + return ret; +} + // Sets all values to absolute value of their original values // Returns TRUE if data changed @@ -197,6 +212,28 @@ const LLVector3& LLVector3::rotVec(const LLQuaternion &q) return *this; } +const LLVector3& LLVector3::transVec(const LLMatrix4& mat) +{ + setVec( + mV[VX] * mat.mMatrix[VX][VX] + + mV[VY] * mat.mMatrix[VX][VY] + + mV[VZ] * mat.mMatrix[VX][VZ] + + mat.mMatrix[VX][VW], + + mV[VX] * mat.mMatrix[VY][VX] + + mV[VY] * mat.mMatrix[VY][VY] + + mV[VZ] * mat.mMatrix[VY][VZ] + + mat.mMatrix[VY][VW], + + mV[VX] * mat.mMatrix[VZ][VX] + + mV[VY] * mat.mMatrix[VZ][VY] + + mV[VZ] * mat.mMatrix[VZ][VZ] + + mat.mMatrix[VZ][VW]); + + return *this; +} + + const LLVector3& LLVector3::rotVec(F32 angle, const LLVector3 &vec) { if ( !vec.isExactlyZero() && angle ) diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index e1461f29d..1cfa1edaa 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -40,6 +40,7 @@ class LLVector2; class LLVector4; class LLMatrix3; +class LLMatrix4; class LLVector3d; class LLQuaternion; @@ -75,6 +76,7 @@ class LLVector3 inline BOOL isFinite() const; // checks to see if all values of LLVector3 are finite BOOL clamp(F32 min, F32 max); // Clamps all values to (min,max), returns TRUE if data changed + BOOL clamp(const LLVector3 &min_vec, const LLVector3 &max_vec); // Scales vector by another vector BOOL clampLength( F32 length_limit ); // Scales vector to limit length to a value void quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz); // changes the vector to reflect quatization @@ -115,6 +117,7 @@ class LLVector3 const LLVector3& rotVec(F32 angle, F32 x, F32 y, F32 z); // Rotates about x,y,z by angle radians const LLVector3& rotVec(const LLMatrix3 &mat); // Rotates by LLMatrix4 mat const LLVector3& rotVec(const LLQuaternion &q); // Rotates by LLQuaternion q + const LLVector3& transVec(const LLMatrix4& mat); // Transforms by LLMatrix4 mat (mat * v) const LLVector3& scaleVec(const LLVector3& vec); // scales per component by vec LLVector3 scaledVec(const LLVector3& vec) const; // get a copy of this vector scaled by vec @@ -162,6 +165,8 @@ F32 dist_vec(const LLVector3 &a, const LLVector3 &b); // Returns distance betwe F32 dist_vec_squared(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b F32 dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b ignoring Z component LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b +LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b (same as projected_vec) +LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b); // Returns component of vector a not parallel to vector b (same as projected_vec) LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u); // Returns a vector that is a linear interpolation between a and b inline LLVector3::LLVector3(void) @@ -496,6 +501,17 @@ inline LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b) return project_axis * (a * project_axis); } +inline LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b) +{ + return projected_vec(a, b); +} + +inline LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b) +{ + return a - projected_vec(a, b); +} + + inline LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u) { return LLVector3( @@ -529,6 +545,21 @@ inline void update_min_max(LLVector3& min, LLVector3& max, const LLVector3& pos) } } +inline void update_min_max(LLVector3& min, LLVector3& max, const F32* pos) +{ + for (U32 i = 0; i < 3; i++) + { + if (min.mV[i] > pos[i]) + { + min.mV[i] = pos[i]; + } + if (max.mV[i] < pos[i]) + { + max.mV[i] = pos[i]; + } + } +} + inline F32 angle_between(const LLVector3& a, const LLVector3& b) { LLVector3 an = a; diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h index 5d8e2ad9f..f5a9adcfc 100644 --- a/indra/llmath/v4color.h +++ b/indra/llmath/v4color.h @@ -114,6 +114,7 @@ class LLColor4 const LLColor4& operator=(const LLColor3 &a); // Assigns vec3 to vec4 and returns vec4 + bool operator<(const LLColor4& rhs) const; friend std::ostream& operator<<(std::ostream& s, const LLColor4 &a); // Print a friend LLColor4 operator+(const LLColor4 &a, const LLColor4 &b); // Return vector a + b friend LLColor4 operator-(const LLColor4 &a, const LLColor4 &b); // Return vector a minus b @@ -595,6 +596,23 @@ inline LLColor4 lerp(const LLColor4 &a, const LLColor4 &b, F32 u) a.mV[VW] + (b.mV[VW] - a.mV[VW]) * u); } +inline bool LLColor4::operator<(const LLColor4& rhs) const +{ + if (mV[0] != rhs.mV[0]) + { + return mV[0] < rhs.mV[0]; + } + if (mV[1] != rhs.mV[1]) + { + return mV[1] < rhs.mV[1]; + } + if (mV[2] != rhs.mV[2]) + { + return mV[2] < rhs.mV[2]; + } + + return mV[3] < rhs.mV[3]; +} void LLColor4::clamp() { diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 38b2bea1b..6b8e86b94 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -55,8 +55,8 @@ #include "llstl.h" #include "llsdserialize.h" #include "llthread.h" - #include "llsocks5.h" +#include "lltimer.h" ////////////////////////////////////////////////////////////////////////////// /* @@ -92,6 +92,26 @@ std::vector LLCurl::sSSLMutex; std::string LLCurl::sCAPath; std::string LLCurl::sCAFile; +void check_curl_code(CURLcode code) +{ + if (code != CURLE_OK) + { + // linux appears to throw a curl error once per session for a bad initialization + // at a pretty random time (when enabling cookies). + llinfos << "curl error detected: " << curl_easy_strerror(code) << llendl; + } +} + +void check_curl_multi_code(CURLMcode code) +{ + if (code != CURLM_OK) + { + // linux appears to throw a curl error once per session for a bad initialization + // at a pretty random time (when enabling cookies). + llinfos << "curl multi error detected: " << curl_multi_strerror(code) << llendl; + } +} + //static void LLCurl::setCAPath(const std::string& path) { @@ -241,7 +261,12 @@ public: void resetState(); + static CURL* allocEasyHandle(); + static void releaseEasyHandle(CURL* handle); + private: + friend class LLCurl; + CURL* mCurlEasyHandle; struct curl_slist* mHeaders; @@ -256,8 +281,62 @@ private: std::vector mStrings; ResponderPtr mResponder; + + static std::set sFreeHandles; + static std::set sActiveHandles; + static LLMutex* sHandleMutex; }; +std::set LLCurl::Easy::sFreeHandles; +std::set LLCurl::Easy::sActiveHandles; +LLMutex* LLCurl::Easy::sHandleMutex = NULL; + + +//static +CURL* LLCurl::Easy::allocEasyHandle() +{ + CURL* ret = NULL; + LLMutexLock lock(sHandleMutex); + if (sFreeHandles.empty()) + { + ret = curl_easy_init(); + } + else + { + ret = *(sFreeHandles.begin()); + sFreeHandles.erase(ret); + curl_easy_reset(ret); + } + + if (ret) + { + sActiveHandles.insert(ret); + } + + return ret; +} + +//static +void LLCurl::Easy::releaseEasyHandle(CURL* handle) +{ + if (!handle) + { + llerrs << "handle cannot be NULL!" << llendl; + } + + LLMutexLock lock(sHandleMutex); + + if (sActiveHandles.find(handle) != sActiveHandles.end()) + { + sActiveHandles.erase(handle); + sFreeHandles.insert(handle); + } + else + { + llerrs << "Invalid handle." << llendl; + } +} + LLCurl::Easy::Easy() : mHeaders(NULL), mCurlEasyHandle(NULL) @@ -268,18 +347,20 @@ LLCurl::Easy::Easy() LLCurl::Easy* LLCurl::Easy::getEasy() { Easy* easy = new Easy(); - easy->mCurlEasyHandle = curl_easy_init(); + easy->mCurlEasyHandle = allocEasyHandle(); + if (!easy->mCurlEasyHandle) { // this can happen if we have too many open files (fails in c-ares/ares_init.c) - llwarns << "curl_multi_init() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl; + llwarns << "allocEasyHandle() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl; delete easy; return NULL; } - // set no DMS caching as default for all easy handles. This prevents them adopting a + // set no DNS caching as default for all easy handles. This prevents them adopting a // multi handles cache if they are added to one. - curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_DNS_CACHE_TIMEOUT, 0); + CURLcode result = curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_DNS_CACHE_TIMEOUT, 0); + check_curl_code(result); if (LLSocks::getInstance()->isHttpProxyEnabled()) { @@ -305,7 +386,7 @@ LLCurl::Easy* LLCurl::Easy::getEasy() LLCurl::Easy::~Easy() { - curl_easy_cleanup(mCurlEasyHandle); + releaseEasyHandle(mCurlEasyHandle); --gCurlEasyCount; curl_slist_free_all(mHeaders); for_each(mStrings.begin(), mStrings.end(), DeletePointerArray()); @@ -364,9 +445,9 @@ void LLCurl::Easy::setHeaders() void LLCurl::Easy::getTransferInfo(LLCurl::TransferInfo* info) { - curl_easy_getinfo(mCurlEasyHandle, CURLINFO_SIZE_DOWNLOAD, &info->mSizeDownload); - curl_easy_getinfo(mCurlEasyHandle, CURLINFO_TOTAL_TIME, &info->mTotalTime); - curl_easy_getinfo(mCurlEasyHandle, CURLINFO_SPEED_DOWNLOAD, &info->mSpeedDownload); + check_curl_code(curl_easy_getinfo(mCurlEasyHandle, CURLINFO_SIZE_DOWNLOAD, &info->mSizeDownload)); + check_curl_code(curl_easy_getinfo(mCurlEasyHandle, CURLINFO_TOTAL_TIME, &info->mTotalTime)); + check_curl_code(curl_easy_getinfo(mCurlEasyHandle, CURLINFO_SPEED_DOWNLOAD, &info->mSpeedDownload)); } U32 LLCurl::Easy::report(CURLcode code) @@ -376,13 +457,14 @@ U32 LLCurl::Easy::report(CURLcode code) if (code == CURLE_OK) { - curl_easy_getinfo(mCurlEasyHandle, CURLINFO_RESPONSE_CODE, &responseCode); + check_curl_code(curl_easy_getinfo(mCurlEasyHandle, CURLINFO_RESPONSE_CODE, &responseCode)); //*TODO: get reason from first line of mHeaderOutput } else { responseCode = 499; responseReason = strerror(code) + " : " + mErrorBuffer; + setopt(CURLOPT_FRESH_CONNECT, TRUE); } if (mResponder) @@ -398,17 +480,20 @@ U32 LLCurl::Easy::report(CURLcode code) // Note: these all assume the caller tracks the value (i.e. keeps it persistant) void LLCurl::Easy::setopt(CURLoption option, S32 value) { - curl_easy_setopt(mCurlEasyHandle, option, value); + CURLcode result = curl_easy_setopt(mCurlEasyHandle, option, value); + check_curl_code(result); } void LLCurl::Easy::setopt(CURLoption option, void* value) { - curl_easy_setopt(mCurlEasyHandle, option, value); + CURLcode result = curl_easy_setopt(mCurlEasyHandle, option, value); + check_curl_code(result); } void LLCurl::Easy::setopt(CURLoption option, char* value) { - curl_easy_setopt(mCurlEasyHandle, option, value); + CURLcode result = curl_easy_setopt(mCurlEasyHandle, option, value); + check_curl_code(result); } // Note: this copies the string so that the caller does not have to keep it around @@ -417,7 +502,8 @@ void LLCurl::Easy::setoptString(CURLoption option, const std::string& value) char* tstring = new char[value.length()+1]; strcpy(tstring, value.c_str()); mStrings.push_back(tstring); - curl_easy_setopt(mCurlEasyHandle, option, tstring); + CURLcode result = curl_easy_setopt(mCurlEasyHandle, option, tstring); + check_curl_code(result); } void LLCurl::Easy::slist_append(const char* str) @@ -510,6 +596,9 @@ void LLCurl::Easy::prepRequest(const std::string& url, setCA(); setopt(CURLOPT_SSL_VERIFYPEER, true); + + //don't verify host name so urls with scrubbed host names will work (improves DNS performance) + setopt(CURLOPT_SSL_VERIFYHOST, 0); setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT); setoptString(CURLOPT_URL, url); @@ -586,7 +675,7 @@ LLCurl::Multi::~Multi() iter != mEasyActiveList.end(); ++iter) { Easy* easy = *iter; - curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()); + check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle())); delete easy; } mEasyActiveList.clear(); @@ -596,7 +685,7 @@ LLCurl::Multi::~Multi() for_each(mEasyFreeList.begin(), mEasyFreeList.end(), DeletePointer()); mEasyFreeList.clear(); - curl_multi_cleanup(mCurlMultiHandle); + check_curl_multi_code(curl_multi_cleanup(mCurlMultiHandle)); --gCurlMultiCount; } @@ -617,8 +706,10 @@ S32 LLCurl::Multi::perform() CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q); if (CURLM_CALL_MULTI_PERFORM != code || q == 0) { + check_curl_multi_code(code); break; } + } mQueued = q; return q; @@ -685,11 +776,12 @@ LLCurl::Easy* LLCurl::Multi::allocEasy() bool LLCurl::Multi::addEasy(Easy* easy) { CURLMcode mcode = curl_multi_add_handle(mCurlMultiHandle, easy->getCurlHandle()); - if (mcode != CURLM_OK) - { - llwarns << "Curl Error: " << curl_multi_strerror(mcode) << llendl; - return false; - } + check_curl_multi_code(mcode); + //if (mcode != CURLM_OK) + //{ + // llwarns << "Curl Error: " << curl_multi_strerror(mcode) << llendl; + // return false; + //} return true; } @@ -710,22 +802,14 @@ void LLCurl::Multi::easyFree(Easy* easy) void LLCurl::Multi::removeEasy(Easy* easy) { - curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()); + check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle())); easyFree(easy); } //static std::string LLCurl::strerror(CURLcode errorcode) { -#if LL_DARWIN - // curl_easy_strerror was added in libcurl 7.12.0. Unfortunately, the version in the Mac OS X 10.3.9 SDK is 7.10.2... - // There's a problem with the custom curl headers in our build that keeps me from #ifdefing this on the libcurl version number - // (the correct check would be #if LIBCURL_VERSION_NUM >= 0x070c00). We'll fix the header problem soon, but for now - // just punt and print the numeric error code on the Mac. - return llformat("%d", errorcode); -#else // LL_DARWIN return std::string(curl_easy_strerror(errorcode)); -#endif // LL_DARWIN } //////////////////////////////////////////////////////////////////////////// @@ -737,6 +821,7 @@ LLCurlRequest::LLCurlRequest() : mActiveRequestCount(0) { mThreadID = LLThread::currentID(); + mProcessing = FALSE; } LLCurlRequest::~LLCurlRequest() @@ -771,6 +856,11 @@ LLCurl::Easy* LLCurlRequest::allocEasy() bool LLCurlRequest::addEasy(LLCurl::Easy* easy) { llassert_always(mActiveMulti); + + if (mProcessing) + { + llerrs << "Posting to a LLCurlRequest instance from within a responder is not allowed (causes DNS timeouts)." << llendl; + } bool res = mActiveMulti->addEasy(easy); return res; } @@ -828,12 +918,41 @@ bool LLCurlRequest::post(const std::string& url, bool res = addEasy(easy); return res; } + +bool LLCurlRequest::post(const std::string& url, + const headers_t& headers, + const std::string& data, + LLCurl::ResponderPtr responder) +{ + LLCurl::Easy* easy = allocEasy(); + if (!easy) + { + return false; + } + easy->prepRequest(url, headers, responder); + + easy->getInput().write(data.data(), data.size()); + S32 bytes = easy->getInput().str().length(); + easy->setopt(CURLOPT_POST, 1); + easy->setopt(CURLOPT_POSTFIELDS, (void*)NULL); + easy->setopt(CURLOPT_POSTFIELDSIZE, bytes); + + easy->slist_append("Content-Type: application/octet-stream"); + easy->setHeaders(); + + lldebugs << "POSTING: " << bytes << " bytes." << llendl; + bool res = addEasy(easy); + return res; +} + // Note: call once per frame S32 LLCurlRequest::process() { llassert_always(mThreadID == LLThread::currentID()); S32 res = 0; + + mProcessing = TRUE; for (curlmulti_set_t::iterator iter = mMultiSet.begin(); iter != mMultiSet.end(); ) { @@ -847,6 +966,7 @@ S32 LLCurlRequest::process() delete multi; } } + mProcessing = FALSE; return res; } @@ -1076,8 +1196,12 @@ void LLCurl::initClass() // Do not change this "unless you are familiar with and mean to control // internal operations of libcurl" // - http://curl.haxx.se/libcurl/c/curl_global_init.html - curl_global_init(CURL_GLOBAL_ALL); + CURLcode code = curl_global_init(CURL_GLOBAL_ALL); + + check_curl_code(code); + Easy::sHandleMutex = new LLMutex; + #if SAFE_SSL S32 mutex_count = CRYPTO_num_locks(); for (S32 i=0; i::iterator iter = Easy::sFreeHandles.begin(); iter != Easy::sFreeHandles.end(); ++iter) + { + CURL* curl = *iter; + curl_easy_cleanup(curl); + } + + Easy::sFreeHandles.clear(); + + llassert(Easy::sActiveHandles.empty()); } const unsigned int LLCurl::MAX_REDIRECTS = 5; diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 99ac1ffdd..084408c70 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -207,6 +207,8 @@ public: void get(const std::string& url, LLCurl::ResponderPtr responder); bool getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, LLCurl::ResponderPtr responder); bool post(const std::string& url, const headers_t& headers, const LLSD& data, LLCurl::ResponderPtr responder); + bool post(const std::string& url, const headers_t& headers, const std::string& data, LLCurl::ResponderPtr responder); + S32 process(); S32 getQueued(); @@ -220,6 +222,7 @@ private: curlmulti_set_t mMultiSet; LLCurl::Multi* mActiveMulti; S32 mActiveRequestCount; + BOOL mProcessing; U32 mThreadID; // debug }; diff --git a/indra/llmessage/llsdmessagebuilder.cpp b/indra/llmessage/llsdmessagebuilder.cpp index 6e41b0389..2680dd0b7 100644 --- a/indra/llmessage/llsdmessagebuilder.cpp +++ b/indra/llmessage/llsdmessagebuilder.cpp @@ -35,6 +35,7 @@ #include "llsdmessagebuilder.h" #include "llmessagetemplate.h" +#include "llmath.h" #include "llquaternion.h" #include "llsdutil.h" #include "llsdutil_math.h" diff --git a/indra/llmessage/llservicebuilder.cpp b/indra/llmessage/llservicebuilder.cpp index 51404a35b..449848053 100644 --- a/indra/llmessage/llservicebuilder.cpp +++ b/indra/llmessage/llservicebuilder.cpp @@ -94,7 +94,7 @@ bool starts_with(const std::string& text, const char* prefix) // TODO: Build a real services.xml for windows development. // and remove the base_url logic below. -std::string LLServiceBuilder::buildServiceURI(const std::string& service_name) +std::string LLServiceBuilder::buildServiceURI(const std::string& service_name) const { std::ostringstream service_url; // Find the service builder @@ -132,7 +132,7 @@ std::string LLServiceBuilder::buildServiceURI(const std::string& service_name) std::string LLServiceBuilder::buildServiceURI( const std::string& service_name, - const LLSD& option_map) + const LLSD& option_map) const { return russ_format(buildServiceURI(service_name), option_map); } diff --git a/indra/llmessage/llservicebuilder.h b/indra/llmessage/llservicebuilder.h index 4670438bc..47476774a 100644 --- a/indra/llmessage/llservicebuilder.h +++ b/indra/llmessage/llservicebuilder.h @@ -76,7 +76,7 @@ public: * * @param service_name The name of the service you want to call. */ - std::string buildServiceURI(const std::string& service_name); + std::string buildServiceURI(const std::string& service_name) const; /** * @brief Build a service url if the url with construction parameters. @@ -88,7 +88,7 @@ public: */ std::string buildServiceURI( const std::string& service_name, - const LLSD& option_map); + const LLSD& option_map) const; public: /** diff --git a/indra/llmessage/lltemplatemessagebuilder.cpp b/indra/llmessage/lltemplatemessagebuilder.cpp index fa02456d9..6f9707ed5 100644 --- a/indra/llmessage/lltemplatemessagebuilder.cpp +++ b/indra/llmessage/lltemplatemessagebuilder.cpp @@ -35,6 +35,7 @@ #include "lltemplatemessagebuilder.h" #include "llmessagetemplate.h" +#include "llmath.h" #include "llquaternion.h" #include "u64.h" #include "v3dmath.h" diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp index c95132437..93de1b13d 100644 --- a/indra/llmessage/lltemplatemessagereader.cpp +++ b/indra/llmessage/lltemplatemessagereader.cpp @@ -36,6 +36,7 @@ #include "llfasttimer.h" #include "llmessagebuilder.h" #include "llmessagetemplate.h" +#include "llmath.h" #include "llquaternion.h" #include "message.h" #include "u64.h" diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index d0572fb4a..5a3d78452 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -2469,12 +2469,12 @@ void dump_prehash_files() " * Generated from message template version number %.3f\n" " */\n", gMessageSystem->mMessageFileVersionNumber); - fprintf(fp, "\n\nextern F32 gPrehashVersionNumber;\n\n"); + fprintf(fp, "\n\nextern F32 const gPrehashVersionNumber;\n\n"); for (i = 0; i < MESSAGE_NUMBER_OF_HASH_BUCKETS; i++) { if (!LLMessageStringTable::getInstance()->mEmpty[i] && LLMessageStringTable::getInstance()->mString[i][0] != '.') { - fprintf(fp, "extern char * _PREHASH_%s;\n", LLMessageStringTable::getInstance()->mString[i]); + fprintf(fp, "extern char const* const _PREHASH_%s;\n", LLMessageStringTable::getInstance()->mString[i]); } } fprintf(fp, "\n\n#endif\n"); @@ -2499,12 +2499,12 @@ void dump_prehash_files() gMessageSystem->mMessageFileVersionNumber); fprintf(fp, "#include \"linden_common.h\"\n"); fprintf(fp, "#include \"message.h\"\n\n"); - fprintf(fp, "\n\nF32 gPrehashVersionNumber = %.3ff;\n\n", gMessageSystem->mMessageFileVersionNumber); + fprintf(fp, "\n\nF32 const gPrehashVersionNumber = %.3ff;\n\n", gMessageSystem->mMessageFileVersionNumber); for (i = 0; i < MESSAGE_NUMBER_OF_HASH_BUCKETS; i++) { if (!LLMessageStringTable::getInstance()->mEmpty[i] && LLMessageStringTable::getInstance()->mString[i][0] != '.') { - fprintf(fp, "char * _PREHASH_%s = LLMessageStringTable::getInstance()->getString(\"%s\");\n", LLMessageStringTable::getInstance()->mString[i], LLMessageStringTable::getInstance()->mString[i]); + fprintf(fp, "char const* const _PREHASH_%s = LLMessageStringTable::getInstance()->getString(\"%s\");\n", LLMessageStringTable::getInstance()->mString[i], LLMessageStringTable::getInstance()->mString[i]); } } fclose(fp); diff --git a/indra/llmessage/sound_ids.cpp b/indra/llmessage/sound_ids.cpp index 028ef8fc1..9262a33b3 100644 --- a/indra/llmessage/sound_ids.cpp +++ b/indra/llmessage/sound_ids.cpp @@ -34,259 +34,281 @@ #include "lluuid.h" -LLUUID const SND_NULL = LLUUID::null; -LLUUID const SND_RIDE ("00000000-0000-0000-0000-000000000100"); -LLUUID const SND_SHOT ("00000000-0000-0000-0000-000000000101"); -LLUUID const SND_MORTAR ("00000000-0000-0000-0000-000000000102"); -LLUUID const SND_HIT ("00000000-0000-0000-0000-000000000103"); -LLUUID const SND_EXPLOSION ("00000000-0000-0000-0000-000000000104"); -LLUUID const SND_BOING ("00000000-0000-0000-0000-000000000105"); -LLUUID const SND_OBJECT_CREATE ("9f1bc096-3592-411e-9b0b-c447a9ff054c"); +const LLUUID SND_NULL = LLUUID::null; +const LLUUID SND_RIDE ("00000000-0000-0000-0000-000000000100"); +const LLUUID SND_SHOT ("00000000-0000-0000-0000-000000000101"); +const LLUUID SND_MORTAR ("00000000-0000-0000-0000-000000000102"); +const LLUUID SND_HIT ("00000000-0000-0000-0000-000000000103"); +const LLUUID SND_EXPLOSION ("00000000-0000-0000-0000-000000000104"); +const LLUUID SND_BOING ("00000000-0000-0000-0000-000000000105"); +const LLUUID SND_OBJECT_CREATE ("9f1bc096-3592-411e-9b0b-c447a9ff054c"); // // Different bird sounds for different states // -LLUUID const SND_CHIRP ("00000000-0000-0000-0000-000000000106"); // Flying random chirp -LLUUID const SND_CHIRP2 ("828a9526-175b-455d-8af0-0e3c0fb602b2"); // Spooked by user -LLUUID const SND_CHIRP3 ("f99772d6-1ce6-4a39-a28b-06d26c94c9e3"); // Spooked by object -LLUUID const SND_CHIRP4 ("54472ca4-7fc9-42cb-b7d5-99ad5b12bd50"); // Chasing other bird -LLUUID const SND_CHIRP5 ("2929964f-fac5-40d7-9179-2864a8fa9ace"); // Hopping random chirp -LLUUID const SND_CHIRPDEAD ("9abff1d3-863a-4e04-bd83-3834fd7fcff4"); // Hit by grenade - dead! +const LLUUID SND_CHIRP ("00000000-0000-0000-0000-000000000106"); // Flying random chirp +const LLUUID SND_CHIRP2 ("828a9526-175b-455d-8af0-0e3c0fb602b2"); // Spooked by user +const LLUUID SND_CHIRP3 ("f99772d6-1ce6-4a39-a28b-06d26c94c9e3"); // Spooked by object +const LLUUID SND_CHIRP4 ("54472ca4-7fc9-42cb-b7d5-99ad5b12bd50"); // Chasing other bird +const LLUUID SND_CHIRP5 ("2929964f-fac5-40d7-9179-2864a8fa9ace"); // Hopping random chirp +const LLUUID SND_CHIRPDEAD ("9abff1d3-863a-4e04-bd83-3834fd7fcff4"); // Hit by grenade - dead! -LLUUID const SND_MUNCH ("00000000-0000-0000-0000-000000000107"); -LLUUID const SND_PUNCH ("00000000-0000-0000-0000-000000000108"); -LLUUID const SND_SPLASH ("00000000-0000-0000-0000-000000000109"); -LLUUID const SND_CLICK ("00000000-0000-0000-0000-000000000110"); -LLUUID const SND_WHISTLE ("ab858f9a-1f44-4d39-9b33-351543d03ccb"); -LLUUID const SND_TYPING ("5e191c7b-8996-9ced-a177-b2ac32bfea06"); +const LLUUID SND_MUNCH ("00000000-0000-0000-0000-000000000107"); +const LLUUID SND_PUNCH ("00000000-0000-0000-0000-000000000108"); +const LLUUID SND_SPLASH ("00000000-0000-0000-0000-000000000109"); +const LLUUID SND_CLICK ("00000000-0000-0000-0000-000000000110"); +const LLUUID SND_WHISTLE ("ab858f9a-1f44-4d39-9b33-351543d03ccb"); +const LLUUID SND_TYPING ("5e191c7b-8996-9ced-a177-b2ac32bfea06"); -LLUUID const SND_ARROW_SHOT ("00000000-0000-0000-0000-000000000111"); -LLUUID const SND_ARROW_THUD ("00000000-0000-0000-0000-000000000112"); -LLUUID const SND_LASER_SHOT ("00000000-0000-0000-0000-000000000113"); -LLUUID const SND_JET_THRUST ("67f5e4f0-0534-4d97-bc01-f297648d20e0"); +const LLUUID SND_ARROW_SHOT ("00000000-0000-0000-0000-000000000111"); +const LLUUID SND_ARROW_THUD ("00000000-0000-0000-0000-000000000112"); +const LLUUID SND_LASER_SHOT ("00000000-0000-0000-0000-000000000113"); +const LLUUID SND_JET_THRUST ("67f5e4f0-0534-4d97-bc01-f297648d20e0"); -LLUUID const SND_SILENCE ("00000000-0000-0000-0000-000000000114"); -LLUUID const SND_BUBBLES ("00000000-0000-0000-0000-000000000115"); -LLUUID const SND_WELCOME ("00000000-0000-0000-0000-000000000116"); -LLUUID const SND_SQUISH ("00000000-0000-0000-0000-000000000117"); -LLUUID const SND_SUBPOD ("00000000-0000-0000-0000-000000000118"); -LLUUID const SND_FOOTSTEPS ("00000000-0000-0000-0000-000000000119"); -LLUUID const SND_STEP_LEFT ("00000000-0000-0000-0000-000000000124"); -LLUUID const SND_STEP_RIGHT ("00000000-0000-0000-0000-000000000125"); +const LLUUID SND_SILENCE ("00000000-0000-0000-0000-000000000114"); +const LLUUID SND_BUBBLES ("00000000-0000-0000-0000-000000000115"); +const LLUUID SND_WELCOME ("00000000-0000-0000-0000-000000000116"); +const LLUUID SND_SQUISH ("00000000-0000-0000-0000-000000000117"); +const LLUUID SND_SUBPOD ("00000000-0000-0000-0000-000000000118"); +const LLUUID SND_FOOTSTEPS ("00000000-0000-0000-0000-000000000119"); +const LLUUID SND_STEP_LEFT ("00000000-0000-0000-0000-000000000124"); +const LLUUID SND_STEP_RIGHT ("00000000-0000-0000-0000-000000000125"); -LLUUID const SND_BALL_COLLISION ("00000000-0000-0000-0000-000000000120"); +const LLUUID SND_BALL_COLLISION ("00000000-0000-0000-0000-000000000120"); -LLUUID const SND_OOOH_SCARE_ME ("00000000-0000-0000-0000-000000000121"); -LLUUID const SND_PAYBACK_TIME ("00000000-0000-0000-0000-000000000122"); -LLUUID const SND_READY_FOR_BATTLE ("00000000-0000-0000-0000-000000000123"); +const LLUUID SND_OOOH_SCARE_ME ("00000000-0000-0000-0000-000000000121"); +const LLUUID SND_PAYBACK_TIME ("00000000-0000-0000-0000-000000000122"); +const LLUUID SND_READY_FOR_BATTLE ("00000000-0000-0000-0000-000000000123"); -LLUUID const SND_FLESH_FLESH ("dce5fdd4-afe4-4ea1-822f-dd52cac46b08"); -LLUUID const SND_FLESH_PLASTIC ("51011582-fbca-4580-ae9e-1a5593f094ec"); -LLUUID const SND_FLESH_RUBBER ("68d62208-e257-4d0c-bbe2-20c9ea9760bb"); -LLUUID const SND_GLASS_FLESH ("75872e8c-bc39-451b-9b0b-042d7ba36cba"); -LLUUID const SND_GLASS_GLASS ("6a45ba0b-5775-4ea8-8513-26008a17f873"); -LLUUID const SND_GLASS_PLASTIC ("992a6d1b-8c77-40e0-9495-4098ce539694"); -LLUUID const SND_GLASS_RUBBER ("2de4da5a-faf8-46be-bac6-c4d74f1e5767"); -LLUUID const SND_GLASS_WOOD ("6e3fb0f7-6d9c-42ca-b86b-1122ff562d7d"); -LLUUID const SND_METAL_FLESH ("14209133-4961-4acc-9649-53fc38ee1667"); -LLUUID const SND_METAL_GLASS ("bc4a4348-cfcc-4e5e-908e-8a52a8915fe6"); -LLUUID const SND_METAL_METAL ("9e5c1297-6eed-40c0-825a-d9bcd86e3193"); -LLUUID const SND_METAL_PLASTIC ("e534761c-1894-4b61-b20c-658a6fb68157"); -LLUUID const SND_METAL_RUBBER ("8761f73f-6cf9-4186-8aaa-0948ed002db1"); -LLUUID const SND_METAL_WOOD ("874a26fd-142f-4173-8c5b-890cd846c74d"); -LLUUID const SND_PLASTIC_PLASTIC ("0e24a717-b97e-4b77-9c94-b59a5a88b2da"); -LLUUID const SND_RUBBER_PLASTIC ("75cf3ade-9a5b-4c4d-bb35-f9799bda7fb2"); -LLUUID const SND_RUBBER_RUBBER ("153c8bf7-fb89-4d89-b263-47e58b1b4774"); -LLUUID const SND_STONE_FLESH ("55c3e0ce-275a-46fa-82ff-e0465f5e8703"); -LLUUID const SND_STONE_GLASS ("24babf58-7156-4841-9a3f-761bdbb8e237"); -LLUUID const SND_STONE_METAL ("aca261d8-e145-4610-9e20-9eff990f2c12"); -LLUUID const SND_STONE_PLASTIC ("0642fba6-5dcf-4d62-8e7b-94dbb529d117"); -LLUUID const SND_STONE_RUBBER ("25a863e8-dc42-4e8a-a357-e76422ace9b5"); -LLUUID const SND_STONE_STONE ("9538f37c-456e-4047-81be-6435045608d4"); -LLUUID const SND_STONE_WOOD ("8c0f84c3-9afd-4396-b5f5-9bca2c911c20"); -LLUUID const SND_WOOD_FLESH ("be582e5d-b123-41a2-a150-454c39e961c8"); -LLUUID const SND_WOOD_PLASTIC ("c70141d4-ba06-41ea-bcbc-35ea81cb8335"); -LLUUID const SND_WOOD_RUBBER ("7d1826f4-24c4-4aac-8c2e-eff45df37783"); -LLUUID const SND_WOOD_WOOD ("063c97d3-033a-4e9b-98d8-05c8074922cb"); +const LLUUID SND_FLESH_FLESH ("dce5fdd4-afe4-4ea1-822f-dd52cac46b08"); +const LLUUID SND_FLESH_PLASTIC ("51011582-fbca-4580-ae9e-1a5593f094ec"); +const LLUUID SND_FLESH_RUBBER ("68d62208-e257-4d0c-bbe2-20c9ea9760bb"); +const LLUUID SND_GLASS_FLESH ("75872e8c-bc39-451b-9b0b-042d7ba36cba"); +const LLUUID SND_GLASS_GLASS ("6a45ba0b-5775-4ea8-8513-26008a17f873"); +const LLUUID SND_GLASS_PLASTIC ("992a6d1b-8c77-40e0-9495-4098ce539694"); +const LLUUID SND_GLASS_RUBBER ("2de4da5a-faf8-46be-bac6-c4d74f1e5767"); +const LLUUID SND_GLASS_WOOD ("6e3fb0f7-6d9c-42ca-b86b-1122ff562d7d"); +const LLUUID SND_METAL_FLESH ("14209133-4961-4acc-9649-53fc38ee1667"); +const LLUUID SND_METAL_GLASS ("bc4a4348-cfcc-4e5e-908e-8a52a8915fe6"); +const LLUUID SND_METAL_METAL ("9e5c1297-6eed-40c0-825a-d9bcd86e3193"); +const LLUUID SND_METAL_PLASTIC ("e534761c-1894-4b61-b20c-658a6fb68157"); +const LLUUID SND_METAL_RUBBER ("8761f73f-6cf9-4186-8aaa-0948ed002db1"); +const LLUUID SND_METAL_WOOD ("874a26fd-142f-4173-8c5b-890cd846c74d"); +const LLUUID SND_PLASTIC_PLASTIC ("0e24a717-b97e-4b77-9c94-b59a5a88b2da"); +const LLUUID SND_RUBBER_PLASTIC ("75cf3ade-9a5b-4c4d-bb35-f9799bda7fb2"); +const LLUUID SND_RUBBER_RUBBER ("153c8bf7-fb89-4d89-b263-47e58b1b4774"); +const LLUUID SND_STONE_FLESH ("55c3e0ce-275a-46fa-82ff-e0465f5e8703"); +const LLUUID SND_STONE_GLASS ("24babf58-7156-4841-9a3f-761bdbb8e237"); +const LLUUID SND_STONE_METAL ("aca261d8-e145-4610-9e20-9eff990f2c12"); +const LLUUID SND_STONE_PLASTIC ("0642fba6-5dcf-4d62-8e7b-94dbb529d117"); +const LLUUID SND_STONE_RUBBER ("25a863e8-dc42-4e8a-a357-e76422ace9b5"); +const LLUUID SND_STONE_STONE ("9538f37c-456e-4047-81be-6435045608d4"); +const LLUUID SND_STONE_WOOD ("8c0f84c3-9afd-4396-b5f5-9bca2c911c20"); +const LLUUID SND_WOOD_FLESH ("be582e5d-b123-41a2-a150-454c39e961c8"); +const LLUUID SND_WOOD_PLASTIC ("c70141d4-ba06-41ea-bcbc-35ea81cb8335"); +const LLUUID SND_WOOD_RUBBER ("7d1826f4-24c4-4aac-8c2e-eff45df37783"); +const LLUUID SND_WOOD_WOOD ("063c97d3-033a-4e9b-98d8-05c8074922cb"); -LLUUID const SND_SLIDE_FLESH_FLESH ("614eec22-f73d-4fdc-8691-a37dc5c58333"); -LLUUID const SND_SLIDE_FLESH_PLASTIC (SND_NULL); -LLUUID const SND_SLIDE_FLESH_RUBBER (SND_NULL); -LLUUID const SND_SLIDE_FLESH_FABRIC ("3678b9b9-2a0c-42b5-9c83-80b64ad6e898"); -LLUUID const SND_SLIDE_FLESH_GRAVEL ("02eaa42a-ce1a-4b6b-9c38-cd7ad0e8f4a6"); -LLUUID const SND_SLIDE_FLESH_GRAVEL_02 ("e7d3b501-79f8-4419-b842-ab6843e0f840"); -LLUUID const SND_SLIDE_FLESH_GRAVEL_03 ("4c3e8b52-6244-4e44-85a6-f4ab994418ed"); -LLUUID const SND_SLIDE_GLASS_GRAVEL ("ca491e77-5c47-4ea1-8021-b3ebbf636cab"); -LLUUID const SND_SLIDE_GLASS_GRAVEL_02 ("30794d49-91ce-48e3-a527-c06f67bd6cbe"); -LLUUID const SND_SLIDE_GLASS_GRAVEL_03 ("04c78e54-fd8d-46b6-8ab9-7678b5d6e5cb"); -LLUUID const SND_SLIDE_GLASS_FLESH (SND_NULL); -LLUUID const SND_SLIDE_GLASS_GLASS (SND_NULL); -LLUUID const SND_SLIDE_GLASS_PLASTIC (SND_NULL); -LLUUID const SND_SLIDE_GLASS_RUBBER (SND_NULL); -LLUUID const SND_SLIDE_GLASS_WOOD (SND_NULL); -LLUUID const SND_SLIDE_METAL_FABRIC ("18b66e81-2958-42d4-a373-7a5054919adc"); -LLUUID const SND_SLIDE_METAL_FLESH ("dde65837-633c-4841-af2f-62ec471bf61e"); -LLUUID const SND_SLIDE_METAL_FLESH_02 ("f3cc2cbe-1a1a-4db7-a8d2-e9c8f8fa1f4f"); -LLUUID const SND_SLIDE_METAL_GLASS ("4188be39-7b1f-4495-bf2b-83ddd82eea05"); -LLUUID const SND_SLIDE_METAL_GLASS_02 ("336faa2b-9d96-4e14-93ad-b63b60074379"); -LLUUID const SND_SLIDE_METAL_GLASS_03 ("34d912aa-cf73-4462-b7d0-dcba2c66caba"); -LLUUID const SND_SLIDE_METAL_GLASS_04 ("97ffc063-e872-4469-8e95-1450ac6bad2b"); -LLUUID const SND_SLIDE_METAL_GRAVEL ("2bbff37d-009a-4cfc-9a0d-817652c08fbe"); -LLUUID const SND_SLIDE_METAL_GRAVEL_02 ("a906a228-783b-49e7-9f0a-e20a41d0e39f"); -LLUUID const SND_SLIDE_METAL_METAL ("09461277-c691-45de-b2c5-89dfd3712f79"); -LLUUID const SND_SLIDE_METAL_METAL_02 ("e00a5d97-8fdc-46c1-bd53-7e312727466c"); -LLUUID const SND_SLIDE_METAL_METAL_03 ("8ebfa780-c440-4b52-ab65-5edf3bc15bf1"); -LLUUID const SND_SLIDE_METAL_METAL_04 ("d6d03cb2-5b16-4e31-b7d4-2a81d2a0909b"); -LLUUID const SND_SLIDE_METAL_METAL_05 ("3a46f447-916e-47de-a1e5-95d1af46bd0f"); -LLUUID const SND_SLIDE_METAL_METAL_06 ("cd423231-e70d-4fd2-ad26-f1c6cf5f0610"); -LLUUID const SND_SLIDE_METAL_PLASTIC (SND_NULL); -LLUUID const SND_SLIDE_METAL_RUBBER ("12d97bc0-3c15-4744-b6bd-77d1316eb4f0"); -LLUUID const SND_SLIDE_METAL_WOOD ("4afb6926-a73f-4cb7-85d5-0f9a40107434"); -LLUUID const SND_SLIDE_METAL_WOOD_02 ("349970bf-187d-4bcb-b2cf-e7bb6581590f"); -LLUUID const SND_SLIDE_METAL_WOOD_03 ("64bf6e87-73d4-4cb4-84f7-55cecfd97cd3"); -LLUUID const SND_SLIDE_METAL_WOOD_04 ("0dc670a9-dbe8-41bc-b8ee-4d96d99219d5"); -LLUUID const SND_SLIDE_METAL_WOOD_05 ("6e3cc57b-c9aa-4829-86a1-8e82aeaccb47"); -LLUUID const SND_SLIDE_METAL_WOOD_06 ("c1237f4c-8c88-4da1-bfbc-2af26a8d9e5a"); -LLUUID const SND_SLIDE_METAL_WOOD_07 ("0e1ec243-063b-4dcb-a903-52b8dffed3d2"); -LLUUID const SND_SLIDE_METAL_WOOD_08 ("66736d0f-533d-4007-a8ee-0f27c2034126"); -LLUUID const SND_SLIDE_PLASTIC_GRAVEL ("35092c21-5c48-4b4d-a818-3cf240af2348"); -LLUUID const SND_SLIDE_PLASTIC_GRAVEL_02("c37f5776-0020-47e8-89a0-c74cc6f5742d"); -LLUUID const SND_SLIDE_PLASTIC_GRAVEL_03("d2fc8db6-2e66-464a-8ccb-f99b61ee4987"); -LLUUID const SND_SLIDE_PLASTIC_GRAVEL_04("93cbdb10-6e82-4c0b-a547-7b3b79ac25f6"); -LLUUID const SND_SLIDE_PLASTIC_GRAVEL_05("2f6d0542-fcd1-4264-a17b-f57bf5ebf402"); -LLUUID const SND_SLIDE_PLASTIC_GRAVEL_06("5b8887d4-3be2-45a0-b25d-85af3b1e6392"); -LLUUID const SND_SLIDE_PLASTIC_PLASTIC (SND_NULL); -LLUUID const SND_SLIDE_PLASTIC_PLASTIC_02 (SND_NULL); -LLUUID const SND_SLIDE_PLASTIC_PLASTIC_03 (SND_NULL); -LLUUID const SND_SLIDE_PLASTIC_FABRIC ("7294d9ad-3e41-4373-992c-a9f21d5d66ad"); -LLUUID const SND_SLIDE_PLASTIC_FABRIC_02("58608ce1-f524-472f-b447-bbe6ce4a46e0"); -LLUUID const SND_SLIDE_PLASTIC_FABRIC_03("06ae285e-0b34-4ea6-84ab-9c6c31b414fc"); -LLUUID const SND_SLIDE_PLASTIC_FABRIC_04("211613db-0461-49bd-9554-5c14ad8b31f6"); -LLUUID const SND_SLIDE_RUBBER_PLASTIC ("a98ffa5a-e48e-4f9d-9242-b9a3210ad84a"); -LLUUID const SND_SLIDE_RUBBER_PLASTIC_02 ("d4136c40-eeaa-49c6-a982-8e5a16f5d93a"); -LLUUID const SND_SLIDE_RUBBER_PLASTIC_03 ("29ec0fb2-0b23-47b2-835b-c83cc7cf9fb0"); -LLUUID const SND_SLIDE_RUBBER_RUBBER (SND_NULL); -LLUUID const SND_SLIDE_STONE_FLESH (SND_NULL); -LLUUID const SND_SLIDE_STONE_GLASS (SND_NULL); -LLUUID const SND_SLIDE_STONE_METAL (SND_NULL); -LLUUID const SND_SLIDE_STONE_PLASTIC ("afd0bcc3-d41a-4572-9e7f-08a29eeb0b8a"); -LLUUID const SND_SLIDE_STONE_PLASTIC_02 ("881b720a-96cf-4128-bb98-5d87e03e93c7"); -LLUUID const SND_SLIDE_STONE_PLASTIC_03 ("293dac42-658a-4c5a-a7a2-6d4c5e5658b0"); -LLUUID const SND_SLIDE_STONE_RUBBER ("0724b946-6a3f-4eeb-bb50-0a3b33120974"); -LLUUID const SND_SLIDE_STONE_RUBBER_02 ("ada93d00-76e2-4bf1-9ad9-493727630717"); -LLUUID const SND_SLIDE_STONE_STONE ("ade766dc-2e75-4699-9b41-7c8e53d2b3f2"); -LLUUID const SND_SLIDE_STONE_STONE_02 ("66698375-6594-47b0-8046-c3973de1291d"); -LLUUID const SND_SLIDE_STONE_WOOD ("174ef324-ed50-4f65-9479-b4da580aeb3c"); -LLUUID const SND_SLIDE_STONE_WOOD_02 ("33d517fd-ff11-4d01-a7b5-0e3abf818dcf"); -LLUUID const SND_SLIDE_STONE_WOOD_03 ("1bac4b63-e6fd-4659-9761-991284cf4582"); -LLUUID const SND_SLIDE_STONE_WOOD_04 ("a7d28564-6821-4c01-a378-cde98fba7ba9"); -LLUUID const SND_SLIDE_WOOD_FABRIC ("22c58e74-22cd-4960-9ab7-5bf08ab824e5"); -LLUUID const SND_SLIDE_WOOD_FABRIC_02 ("0b0ed22e-4a0f-4617-a4cf-20d0f2b78ccc"); -LLUUID const SND_SLIDE_WOOD_FABRIC_03 ("42b80abb-9823-4b74-a210-326ccf23636a"); -LLUUID const SND_SLIDE_WOOD_FABRIC_04 ("8538298a-1e6b-4b69-a9ee-5e01e4a02b35"); -LLUUID const SND_SLIDE_WOOD_FLESH ("84b026f3-a11c-4366-aa7c-07edcd89b2bb"); -LLUUID const SND_SLIDE_WOOD_FLESH_02 ("2644191f-4848-47ba-8ba7-bddc0bfcb3da"); -LLUUID const SND_SLIDE_WOOD_FLESH_03 ("edb978e4-9be9-456f-b2fc-e8502bfe25be"); -LLUUID const SND_SLIDE_WOOD_FLESH_04 ("bf2b972e-f42a-46d7-b53e-5fca38f5bc61"); -LLUUID const SND_SLIDE_WOOD_GRAVEL ("d063bb4d-0eff-4403-a6cc-c6c6c073e624"); -LLUUID const SND_SLIDE_WOOD_GRAVEL_02 ("511eb679-6d93-47fa-9141-c3ef9261c919"); -LLUUID const SND_SLIDE_WOOD_GRAVEL_03 ("4ed1fd43-4707-4e5c-b7b7-21ec4e72c1ac"); -LLUUID const SND_SLIDE_WOOD_GRAVEL_04 ("99ea89b3-aa76-4b87-99c8-670365c6d8c3"); -LLUUID const SND_SLIDE_WOOD_PLASTIC ("505ca3c4-94a0-4e28-8fc1-ea72a428396b"); -LLUUID const SND_SLIDE_WOOD_PLASTIC_02 ("fc404011-df71-4ed0-8f22-b72bdd18f63c"); -LLUUID const SND_SLIDE_WOOD_PLASTIC_03 ("67dbe225-26df-4efa-8c8b-f1ef669fec45"); -LLUUID const SND_SLIDE_WOOD_RUBBER (SND_NULL); -LLUUID const SND_SLIDE_WOOD_WOOD ("3079d569-b3e8-4df4-9e09-f0d4611213ef"); -LLUUID const SND_SLIDE_WOOD_WOOD_02 ("276b093d-dbcb-4279-a89e-a54b0b416af6"); -LLUUID const SND_SLIDE_WOOD_WOOD_03 ("c3f3ca5e-2768-4081-847f-247139310fdb"); -LLUUID const SND_SLIDE_WOOD_WOOD_04 ("f08d44b8-ff87-4a98-9561-c72f1f2fec81"); -LLUUID const SND_SLIDE_WOOD_WOOD_05 ("2d8a58cf-f139-4238-8503-27d334d05c85"); -LLUUID const SND_SLIDE_WOOD_WOOD_06 ("e157ebbd-b12d-4225-aa7c-d47b026a7687"); -LLUUID const SND_SLIDE_WOOD_WOOD_07 ("35e17956-e7b4-478c-b274-e37db8a166b2"); -LLUUID const SND_SLIDE_WOOD_WOOD_08 ("e606fc65-0643-4964-9979-ff964fa6a62c"); +const LLUUID SND_SLIDE_FLESH_FLESH ("614eec22-f73d-4fdc-8691-a37dc5c58333"); +const LLUUID SND_SLIDE_FLESH_PLASTIC (SND_NULL); +const LLUUID SND_SLIDE_FLESH_RUBBER (SND_NULL); +const LLUUID SND_SLIDE_FLESH_FABRIC ("3678b9b9-2a0c-42b5-9c83-80b64ad6e898"); +const LLUUID SND_SLIDE_FLESH_GRAVEL ("02eaa42a-ce1a-4b6b-9c38-cd7ad0e8f4a6"); +const LLUUID SND_SLIDE_FLESH_GRAVEL_02 ("e7d3b501-79f8-4419-b842-ab6843e0f840"); +const LLUUID SND_SLIDE_FLESH_GRAVEL_03 ("4c3e8b52-6244-4e44-85a6-f4ab994418ed"); +const LLUUID SND_SLIDE_GLASS_GRAVEL ("ca491e77-5c47-4ea1-8021-b3ebbf636cab"); +const LLUUID SND_SLIDE_GLASS_GRAVEL_02 ("30794d49-91ce-48e3-a527-c06f67bd6cbe"); +const LLUUID SND_SLIDE_GLASS_GRAVEL_03 ("04c78e54-fd8d-46b6-8ab9-7678b5d6e5cb"); +const LLUUID SND_SLIDE_GLASS_FLESH (SND_NULL); +const LLUUID SND_SLIDE_GLASS_GLASS (SND_NULL); +const LLUUID SND_SLIDE_GLASS_PLASTIC (SND_NULL); +const LLUUID SND_SLIDE_GLASS_RUBBER (SND_NULL); +const LLUUID SND_SLIDE_GLASS_WOOD (SND_NULL); +const LLUUID SND_SLIDE_METAL_FABRIC ("18b66e81-2958-42d4-a373-7a5054919adc"); +const LLUUID SND_SLIDE_METAL_FLESH ("dde65837-633c-4841-af2f-62ec471bf61e"); +const LLUUID SND_SLIDE_METAL_FLESH_02 ("f3cc2cbe-1a1a-4db7-a8d2-e9c8f8fa1f4f"); +const LLUUID SND_SLIDE_METAL_GLASS ("4188be39-7b1f-4495-bf2b-83ddd82eea05"); +const LLUUID SND_SLIDE_METAL_GLASS_02 ("336faa2b-9d96-4e14-93ad-b63b60074379"); +const LLUUID SND_SLIDE_METAL_GLASS_03 ("34d912aa-cf73-4462-b7d0-dcba2c66caba"); +const LLUUID SND_SLIDE_METAL_GLASS_04 ("97ffc063-e872-4469-8e95-1450ac6bad2b"); +const LLUUID SND_SLIDE_METAL_GRAVEL ("2bbff37d-009a-4cfc-9a0d-817652c08fbe"); +const LLUUID SND_SLIDE_METAL_GRAVEL_02 ("a906a228-783b-49e7-9f0a-e20a41d0e39f"); +const LLUUID SND_SLIDE_METAL_METAL ("09461277-c691-45de-b2c5-89dfd3712f79"); +const LLUUID SND_SLIDE_METAL_METAL_02 ("e00a5d97-8fdc-46c1-bd53-7e312727466c"); +const LLUUID SND_SLIDE_METAL_METAL_03 ("8ebfa780-c440-4b52-ab65-5edf3bc15bf1"); +const LLUUID SND_SLIDE_METAL_METAL_04 ("d6d03cb2-5b16-4e31-b7d4-2a81d2a0909b"); +const LLUUID SND_SLIDE_METAL_METAL_05 ("3a46f447-916e-47de-a1e5-95d1af46bd0f"); +const LLUUID SND_SLIDE_METAL_METAL_06 ("cd423231-e70d-4fd2-ad26-f1c6cf5f0610"); +const LLUUID SND_SLIDE_METAL_PLASTIC (SND_NULL); +const LLUUID SND_SLIDE_METAL_RUBBER ("12d97bc0-3c15-4744-b6bd-77d1316eb4f0"); +const LLUUID SND_SLIDE_METAL_WOOD ("4afb6926-a73f-4cb7-85d5-0f9a40107434"); +const LLUUID SND_SLIDE_METAL_WOOD_02 ("349970bf-187d-4bcb-b2cf-e7bb6581590f"); +const LLUUID SND_SLIDE_METAL_WOOD_03 ("64bf6e87-73d4-4cb4-84f7-55cecfd97cd3"); +const LLUUID SND_SLIDE_METAL_WOOD_04 ("0dc670a9-dbe8-41bc-b8ee-4d96d99219d5"); +const LLUUID SND_SLIDE_METAL_WOOD_05 ("6e3cc57b-c9aa-4829-86a1-8e82aeaccb47"); +const LLUUID SND_SLIDE_METAL_WOOD_06 ("c1237f4c-8c88-4da1-bfbc-2af26a8d9e5a"); +const LLUUID SND_SLIDE_METAL_WOOD_07 ("0e1ec243-063b-4dcb-a903-52b8dffed3d2"); +const LLUUID SND_SLIDE_METAL_WOOD_08 ("66736d0f-533d-4007-a8ee-0f27c2034126"); +const LLUUID SND_SLIDE_PLASTIC_GRAVEL ("35092c21-5c48-4b4d-a818-3cf240af2348"); +const LLUUID SND_SLIDE_PLASTIC_GRAVEL_02("c37f5776-0020-47e8-89a0-c74cc6f5742d"); +const LLUUID SND_SLIDE_PLASTIC_GRAVEL_03("d2fc8db6-2e66-464a-8ccb-f99b61ee4987"); +const LLUUID SND_SLIDE_PLASTIC_GRAVEL_04("93cbdb10-6e82-4c0b-a547-7b3b79ac25f6"); +const LLUUID SND_SLIDE_PLASTIC_GRAVEL_05("2f6d0542-fcd1-4264-a17b-f57bf5ebf402"); +const LLUUID SND_SLIDE_PLASTIC_GRAVEL_06("5b8887d4-3be2-45a0-b25d-85af3b1e6392"); +const LLUUID SND_SLIDE_PLASTIC_PLASTIC (SND_NULL); +const LLUUID SND_SLIDE_PLASTIC_PLASTIC_02 (SND_NULL); +const LLUUID SND_SLIDE_PLASTIC_PLASTIC_03 (SND_NULL); +const LLUUID SND_SLIDE_PLASTIC_FABRIC ("7294d9ad-3e41-4373-992c-a9f21d5d66ad"); +const LLUUID SND_SLIDE_PLASTIC_FABRIC_02("58608ce1-f524-472f-b447-bbe6ce4a46e0"); +const LLUUID SND_SLIDE_PLASTIC_FABRIC_03("06ae285e-0b34-4ea6-84ab-9c6c31b414fc"); +const LLUUID SND_SLIDE_PLASTIC_FABRIC_04("211613db-0461-49bd-9554-5c14ad8b31f6"); +const LLUUID SND_SLIDE_RUBBER_PLASTIC ("a98ffa5a-e48e-4f9d-9242-b9a3210ad84a"); +const LLUUID SND_SLIDE_RUBBER_PLASTIC_02 ("d4136c40-eeaa-49c6-a982-8e5a16f5d93a"); +const LLUUID SND_SLIDE_RUBBER_PLASTIC_03 ("29ec0fb2-0b23-47b2-835b-c83cc7cf9fb0"); +const LLUUID SND_SLIDE_RUBBER_RUBBER (SND_NULL); +const LLUUID SND_SLIDE_STONE_FLESH (SND_NULL); +const LLUUID SND_SLIDE_STONE_GLASS (SND_NULL); +const LLUUID SND_SLIDE_STONE_METAL (SND_NULL); +const LLUUID SND_SLIDE_STONE_PLASTIC ("afd0bcc3-d41a-4572-9e7f-08a29eeb0b8a"); +const LLUUID SND_SLIDE_STONE_PLASTIC_02 ("881b720a-96cf-4128-bb98-5d87e03e93c7"); +const LLUUID SND_SLIDE_STONE_PLASTIC_03 ("293dac42-658a-4c5a-a7a2-6d4c5e5658b0"); +const LLUUID SND_SLIDE_STONE_RUBBER ("0724b946-6a3f-4eeb-bb50-0a3b33120974"); +const LLUUID SND_SLIDE_STONE_RUBBER_02 ("ada93d00-76e2-4bf1-9ad9-493727630717"); +const LLUUID SND_SLIDE_STONE_STONE ("ade766dc-2e75-4699-9b41-7c8e53d2b3f2"); +const LLUUID SND_SLIDE_STONE_STONE_02 ("66698375-6594-47b0-8046-c3973de1291d"); +const LLUUID SND_SLIDE_STONE_WOOD ("174ef324-ed50-4f65-9479-b4da580aeb3c"); +const LLUUID SND_SLIDE_STONE_WOOD_02 ("33d517fd-ff11-4d01-a7b5-0e3abf818dcf"); +const LLUUID SND_SLIDE_STONE_WOOD_03 ("1bac4b63-e6fd-4659-9761-991284cf4582"); +const LLUUID SND_SLIDE_STONE_WOOD_04 ("a7d28564-6821-4c01-a378-cde98fba7ba9"); +const LLUUID SND_SLIDE_WOOD_FABRIC ("22c58e74-22cd-4960-9ab7-5bf08ab824e5"); +const LLUUID SND_SLIDE_WOOD_FABRIC_02 ("0b0ed22e-4a0f-4617-a4cf-20d0f2b78ccc"); +const LLUUID SND_SLIDE_WOOD_FABRIC_03 ("42b80abb-9823-4b74-a210-326ccf23636a"); +const LLUUID SND_SLIDE_WOOD_FABRIC_04 ("8538298a-1e6b-4b69-a9ee-5e01e4a02b35"); +const LLUUID SND_SLIDE_WOOD_FLESH ("84b026f3-a11c-4366-aa7c-07edcd89b2bb"); +const LLUUID SND_SLIDE_WOOD_FLESH_02 ("2644191f-4848-47ba-8ba7-bddc0bfcb3da"); +const LLUUID SND_SLIDE_WOOD_FLESH_03 ("edb978e4-9be9-456f-b2fc-e8502bfe25be"); +const LLUUID SND_SLIDE_WOOD_FLESH_04 ("bf2b972e-f42a-46d7-b53e-5fca38f5bc61"); +const LLUUID SND_SLIDE_WOOD_GRAVEL ("d063bb4d-0eff-4403-a6cc-c6c6c073e624"); +const LLUUID SND_SLIDE_WOOD_GRAVEL_02 ("511eb679-6d93-47fa-9141-c3ef9261c919"); +const LLUUID SND_SLIDE_WOOD_GRAVEL_03 ("4ed1fd43-4707-4e5c-b7b7-21ec4e72c1ac"); +const LLUUID SND_SLIDE_WOOD_GRAVEL_04 ("99ea89b3-aa76-4b87-99c8-670365c6d8c3"); +const LLUUID SND_SLIDE_WOOD_PLASTIC ("505ca3c4-94a0-4e28-8fc1-ea72a428396b"); +const LLUUID SND_SLIDE_WOOD_PLASTIC_02 ("fc404011-df71-4ed0-8f22-b72bdd18f63c"); +const LLUUID SND_SLIDE_WOOD_PLASTIC_03 ("67dbe225-26df-4efa-8c8b-f1ef669fec45"); +const LLUUID SND_SLIDE_WOOD_RUBBER (SND_NULL); +const LLUUID SND_SLIDE_WOOD_WOOD ("3079d569-b3e8-4df4-9e09-f0d4611213ef"); +const LLUUID SND_SLIDE_WOOD_WOOD_02 ("276b093d-dbcb-4279-a89e-a54b0b416af6"); +const LLUUID SND_SLIDE_WOOD_WOOD_03 ("c3f3ca5e-2768-4081-847f-247139310fdb"); +const LLUUID SND_SLIDE_WOOD_WOOD_04 ("f08d44b8-ff87-4a98-9561-c72f1f2fec81"); +const LLUUID SND_SLIDE_WOOD_WOOD_05 ("2d8a58cf-f139-4238-8503-27d334d05c85"); +const LLUUID SND_SLIDE_WOOD_WOOD_06 ("e157ebbd-b12d-4225-aa7c-d47b026a7687"); +const LLUUID SND_SLIDE_WOOD_WOOD_07 ("35e17956-e7b4-478c-b274-e37db8a166b2"); +const LLUUID SND_SLIDE_WOOD_WOOD_08 ("e606fc65-0643-4964-9979-ff964fa6a62c"); -LLUUID const SND_ROLL_FLESH_FLESH (SND_NULL); -LLUUID const SND_ROLL_FLESH_PLASTIC ("89a0be4c-848d-4a6e-8886-298f56c2cff4"); -LLUUID const SND_ROLL_FLESH_PLASTIC_02 ("beb06343-1aa1-4af2-b320-5d2ec31c53b1"); -LLUUID const SND_ROLL_FLESH_RUBBER (SND_NULL); -LLUUID const SND_ROLL_GLASS_GRAVEL ("ba795c74-7e09-4572-b495-e09886a46b86"); -LLUUID const SND_ROLL_GLASS_GRAVEL_02 ("4c93c3b7-14cb-4d9b-a7df-628ad935f1f2"); -LLUUID const SND_ROLL_GLASS_FLESH (SND_NULL); -LLUUID const SND_ROLL_GLASS_GLASS (SND_NULL); -LLUUID const SND_ROLL_GLASS_PLASTIC (SND_NULL); -LLUUID const SND_ROLL_GLASS_RUBBER (SND_NULL); -LLUUID const SND_ROLL_GLASS_WOOD ("d40b1f48-a061-4f6e-b18f-4326a3dd5c29"); -LLUUID const SND_ROLL_GLASS_WOOD_02 ("78cd407a-bb36-4163-ba09-20f2e6d9d44b"); -LLUUID const SND_ROLL_GRAVEL_GRAVEL ("c7354cc3-6df5-4738-8dbb-b28a6ac46a05"); -LLUUID const SND_ROLL_GRAVEL_GRAVEL_02 ("01d194c4-72a6-47df-81a5-8db430faff87"); -LLUUID const SND_ROLL_METAL_FABRIC ("ce6e6564-20fd-48e4-81e2-cd3f81c00a3e"); -LLUUID const SND_ROLL_METAL_FABRIC_02 ("fc4d0065-32f6-4bb0-9f3f-f4737eb27163"); -LLUUID const SND_ROLL_METAL_FLESH (SND_NULL); -LLUUID const SND_ROLL_METAL_GLASS ("63d530bb-a41f-402b-aa1f-be6b11959809"); -LLUUID const SND_ROLL_METAL_GLASS_02 ("f62642c2-6db5-4faa-8b77-939067d837c3"); -LLUUID const SND_ROLL_METAL_GLASS_03 ("db5b5a15-2817-4cd7-9f0b-9ad49b5e52c8"); -LLUUID const SND_ROLL_METAL_GRAVEL ("447164e3-9646-4c1a-a16d-606892891466"); -LLUUID const SND_ROLL_METAL_METAL ("c3c22cf3-5d1f-4cc3-b4b5-708b9f65979c"); -LLUUID const SND_ROLL_METAL_METAL_02 ("d8386277-a1ea-460e-b6fd-bb285c323bf1"); -LLUUID const SND_ROLL_METAL_METAL_03 ("69ee1f02-f9cd-4c8b-aedd-39a2d6705680"); -LLUUID const SND_ROLL_METAL_METAL_04 ("5cc6b5fd-26ce-47ad-b21d-3a7c190dd375"); -LLUUID const SND_ROLL_METAL_PLASTIC ("c6a9bbf6-df15-4713-9f84-7237fce4051e"); -LLUUID const SND_ROLL_METAL_PLASTIC_01 ("0fedb59b-2dbb-4cec-b6cc-8559ec027749"); -LLUUID const SND_ROLL_METAL_RUBBER (SND_NULL); -LLUUID const SND_ROLL_METAL_WOOD ("1d76af57-01b1-4c73-9a1d-69523bfa50ea"); -LLUUID const SND_ROLL_METAL_WOOD_02 ("78aa4e71-8e7c-4b90-a561-3ebdc639f99b"); -LLUUID const SND_ROLL_METAL_WOOD_03 ("777d95bf-962f-48fa-93bf-8c1806557d72"); -LLUUID const SND_ROLL_METAL_WOOD_04 ("1833da76-45e2-4a8b-97da-d17413e056c9"); -LLUUID const SND_ROLL_METAL_WOOD_05 ("b13e1232-3d8d-42e9-92ec-b30f9f823962"); -LLUUID const SND_ROLL_PLASTIC_FABRIC ("616a1f03-209f-4c55-b264-83a000b6ef0a"); -LLUUID const SND_ROLL_PLASTIC_PLASTIC ("873f3d82-00b2-4082-9c69-7aef3461dba1"); -LLUUID const SND_ROLL_PLASTIC_PLASTIC_02 ("cc39879f-ebc8-4405-a4fc-8342f5bed31e"); -LLUUID const SND_ROLL_RUBBER_PLASTIC (SND_NULL); -LLUUID const SND_ROLL_RUBBER_RUBBER (SND_NULL); -LLUUID const SND_ROLL_STONE_FLESH (SND_NULL); -LLUUID const SND_ROLL_STONE_GLASS (SND_NULL); -LLUUID const SND_ROLL_STONE_METAL (SND_NULL); -LLUUID const SND_ROLL_STONE_PLASTIC ("155f65a8-cae7-476e-a58b-fd362be7fd0e"); -LLUUID const SND_ROLL_STONE_RUBBER (SND_NULL); -LLUUID const SND_ROLL_STONE_STONE ("67d56e3f-6ed5-4658-9418-14f020c38b11"); -LLUUID const SND_ROLL_STONE_STONE_02 ("43d99d10-d75b-4246-accf-4ceb2c909aa7"); -LLUUID const SND_ROLL_STONE_STONE_03 ("f04e83ff-eed7-4e99-8f45-eb97e4e1d3b7"); -LLUUID const SND_ROLL_STONE_STONE_04 ("10fcc5ad-fa89-48d6-b774-986b580c1efc"); -LLUUID const SND_ROLL_STONE_STONE_05 ("3d86f5a3-1a91-49d9-b99f-8521a7422497"); -LLUUID const SND_ROLL_STONE_WOOD ("53e46fb7-6c21-4fe1-bffe-0567475d48fa"); -LLUUID const SND_ROLL_STONE_WOOD_02 ("5eba8c9a-a014-4299-87f1-315c45ec795b"); -LLUUID const SND_ROLL_STONE_WOOD_03 ("ea6c05fc-6e9c-4526-8a20-bc47810bb549"); -LLUUID const SND_ROLL_STONE_WOOD_04 ("64618cbf-3f42-4728-8094-e77807545efb"); -LLUUID const SND_ROLL_WOOD_FLESH ("26ee185d-6fc3-49f8-89ba-51cab04cfc42"); -LLUUID const SND_ROLL_WOOD_FLESH_02 ("334faa25-1e80-4c99-b29f-4c9c2a3d079d"); -LLUUID const SND_ROLL_WOOD_FLESH_03 ("2f876626-4dce-4f71-a91e-a25302edfab7"); -LLUUID const SND_ROLL_WOOD_FLESH_04 ("d6877aac-07fc-4931-bcde-585f223802ad"); -LLUUID const SND_ROLL_WOOD_GRAVEL ("2a23ebb5-a4a2-4f1f-8d75-7384239354aa"); -LLUUID const SND_ROLL_WOOD_GRAVEL_02 ("208bf26d-f097-450c-95c4-9d26317c613c"); -LLUUID const SND_ROLL_WOOD_GRAVEL_03 ("a26ecaf4-92c6-4e32-9864-56b7c70cab8e"); -LLUUID const SND_ROLL_WOOD_PLASTIC ("71c1000a-9f16-4cc3-8ede-ec4aa3bf5723"); -LLUUID const SND_ROLL_WOOD_PLASTIC_02 ("7bc20ba6-1e6d-4eea-83ad-c5cc3ae0e409"); -LLUUID const SND_ROLL_WOOD_RUBBER (SND_NULL); -LLUUID const SND_ROLL_WOOD_WOOD ("2cc8eec4-bb4a-4ba8-b783-71526ec708e8"); -LLUUID const SND_ROLL_WOOD_WOOD_02 ("0a1f8070-a11a-4b4c-b260-5ffb6acb0a5d"); -LLUUID const SND_ROLL_WOOD_WOOD_03 ("160bef64-da9c-4be8-b07b-a5060b501700"); -LLUUID const SND_ROLL_WOOD_WOOD_04 ("1c62ea16-cc60-48ed-829a-68b8f4cf0c1c"); -LLUUID const SND_ROLL_WOOD_WOOD_05 ("be9cc8fe-b920-4bf5-8924-453088cbc03f"); -LLUUID const SND_ROLL_WOOD_WOOD_06 ("a76cfe60-56b0-43b1-8f31-93e56947d78b"); -LLUUID const SND_ROLL_WOOD_WOOD_07 ("0c6aa481-b5bc-4573-ae83-8e16ff27e750"); -LLUUID const SND_ROLL_WOOD_WOOD_08 ("214ab2c7-871a-451b-b0db-4c5677199011"); -LLUUID const SND_ROLL_WOOD_WOOD_09 ("0086e4db-3ac6-4545-b414-6f359bedd9a5"); +const LLUUID SND_ROLL_FLESH_FLESH (SND_NULL); +const LLUUID SND_ROLL_FLESH_PLASTIC ("89a0be4c-848d-4a6e-8886-298f56c2cff4"); +const LLUUID SND_ROLL_FLESH_PLASTIC_02 ("beb06343-1aa1-4af2-b320-5d2ec31c53b1"); +const LLUUID SND_ROLL_FLESH_RUBBER (SND_NULL); +const LLUUID SND_ROLL_GLASS_GRAVEL ("ba795c74-7e09-4572-b495-e09886a46b86"); +const LLUUID SND_ROLL_GLASS_GRAVEL_02 ("4c93c3b7-14cb-4d9b-a7df-628ad935f1f2"); +const LLUUID SND_ROLL_GLASS_FLESH (SND_NULL); +const LLUUID SND_ROLL_GLASS_GLASS (SND_NULL); +const LLUUID SND_ROLL_GLASS_PLASTIC (SND_NULL); +const LLUUID SND_ROLL_GLASS_RUBBER (SND_NULL); +const LLUUID SND_ROLL_GLASS_WOOD ("d40b1f48-a061-4f6e-b18f-4326a3dd5c29"); +const LLUUID SND_ROLL_GLASS_WOOD_02 ("78cd407a-bb36-4163-ba09-20f2e6d9d44b"); +const LLUUID SND_ROLL_GRAVEL_GRAVEL ("c7354cc3-6df5-4738-8dbb-b28a6ac46a05"); +const LLUUID SND_ROLL_GRAVEL_GRAVEL_02 ("01d194c4-72a6-47df-81a5-8db430faff87"); +const LLUUID SND_ROLL_METAL_FABRIC ("ce6e6564-20fd-48e4-81e2-cd3f81c00a3e"); +const LLUUID SND_ROLL_METAL_FABRIC_02 ("fc4d0065-32f6-4bb0-9f3f-f4737eb27163"); +const LLUUID SND_ROLL_METAL_FLESH (SND_NULL); +const LLUUID SND_ROLL_METAL_GLASS ("63d530bb-a41f-402b-aa1f-be6b11959809"); +const LLUUID SND_ROLL_METAL_GLASS_02 ("f62642c2-6db5-4faa-8b77-939067d837c3"); +const LLUUID SND_ROLL_METAL_GLASS_03 ("db5b5a15-2817-4cd7-9f0b-9ad49b5e52c8"); +const LLUUID SND_ROLL_METAL_GRAVEL ("447164e3-9646-4c1a-a16d-606892891466"); +const LLUUID SND_ROLL_METAL_METAL ("c3c22cf3-5d1f-4cc3-b4b5-708b9f65979c"); +const LLUUID SND_ROLL_METAL_METAL_02 ("d8386277-a1ea-460e-b6fd-bb285c323bf1"); +const LLUUID SND_ROLL_METAL_METAL_03 ("69ee1f02-f9cd-4c8b-aedd-39a2d6705680"); +const LLUUID SND_ROLL_METAL_METAL_04 ("5cc6b5fd-26ce-47ad-b21d-3a7c190dd375"); +const LLUUID SND_ROLL_METAL_PLASTIC ("c6a9bbf6-df15-4713-9f84-7237fce4051e"); +const LLUUID SND_ROLL_METAL_PLASTIC_01 ("0fedb59b-2dbb-4cec-b6cc-8559ec027749"); +const LLUUID SND_ROLL_METAL_RUBBER (SND_NULL); +const LLUUID SND_ROLL_METAL_WOOD ("1d76af57-01b1-4c73-9a1d-69523bfa50ea"); +const LLUUID SND_ROLL_METAL_WOOD_02 ("78aa4e71-8e7c-4b90-a561-3ebdc639f99b"); +const LLUUID SND_ROLL_METAL_WOOD_03 ("777d95bf-962f-48fa-93bf-8c1806557d72"); +const LLUUID SND_ROLL_METAL_WOOD_04 ("1833da76-45e2-4a8b-97da-d17413e056c9"); +const LLUUID SND_ROLL_METAL_WOOD_05 ("b13e1232-3d8d-42e9-92ec-b30f9f823962"); +const LLUUID SND_ROLL_PLASTIC_FABRIC ("616a1f03-209f-4c55-b264-83a000b6ef0a"); +const LLUUID SND_ROLL_PLASTIC_PLASTIC ("873f3d82-00b2-4082-9c69-7aef3461dba1"); +const LLUUID SND_ROLL_PLASTIC_PLASTIC_02 ("cc39879f-ebc8-4405-a4fc-8342f5bed31e"); +const LLUUID SND_ROLL_RUBBER_PLASTIC (SND_NULL); +const LLUUID SND_ROLL_RUBBER_RUBBER (SND_NULL); +const LLUUID SND_ROLL_STONE_FLESH (SND_NULL); +const LLUUID SND_ROLL_STONE_GLASS (SND_NULL); +const LLUUID SND_ROLL_STONE_METAL (SND_NULL); +const LLUUID SND_ROLL_STONE_PLASTIC ("155f65a8-cae7-476e-a58b-fd362be7fd0e"); +const LLUUID SND_ROLL_STONE_RUBBER (SND_NULL); +const LLUUID SND_ROLL_STONE_STONE ("67d56e3f-6ed5-4658-9418-14f020c38b11"); +const LLUUID SND_ROLL_STONE_STONE_02 ("43d99d10-d75b-4246-accf-4ceb2c909aa7"); +const LLUUID SND_ROLL_STONE_STONE_03 ("f04e83ff-eed7-4e99-8f45-eb97e4e1d3b7"); +const LLUUID SND_ROLL_STONE_STONE_04 ("10fcc5ad-fa89-48d6-b774-986b580c1efc"); +const LLUUID SND_ROLL_STONE_STONE_05 ("3d86f5a3-1a91-49d9-b99f-8521a7422497"); +const LLUUID SND_ROLL_STONE_WOOD ("53e46fb7-6c21-4fe1-bffe-0567475d48fa"); +const LLUUID SND_ROLL_STONE_WOOD_02 ("5eba8c9a-a014-4299-87f1-315c45ec795b"); +const LLUUID SND_ROLL_STONE_WOOD_03 ("ea6c05fc-6e9c-4526-8a20-bc47810bb549"); +const LLUUID SND_ROLL_STONE_WOOD_04 ("64618cbf-3f42-4728-8094-e77807545efb"); +const LLUUID SND_ROLL_WOOD_FLESH ("26ee185d-6fc3-49f8-89ba-51cab04cfc42"); +const LLUUID SND_ROLL_WOOD_FLESH_02 ("334faa25-1e80-4c99-b29f-4c9c2a3d079d"); +const LLUUID SND_ROLL_WOOD_FLESH_03 ("2f876626-4dce-4f71-a91e-a25302edfab7"); +const LLUUID SND_ROLL_WOOD_FLESH_04 ("d6877aac-07fc-4931-bcde-585f223802ad"); +const LLUUID SND_ROLL_WOOD_GRAVEL ("2a23ebb5-a4a2-4f1f-8d75-7384239354aa"); +const LLUUID SND_ROLL_WOOD_GRAVEL_02 ("208bf26d-f097-450c-95c4-9d26317c613c"); +const LLUUID SND_ROLL_WOOD_GRAVEL_03 ("a26ecaf4-92c6-4e32-9864-56b7c70cab8e"); +const LLUUID SND_ROLL_WOOD_PLASTIC ("71c1000a-9f16-4cc3-8ede-ec4aa3bf5723"); +const LLUUID SND_ROLL_WOOD_PLASTIC_02 ("7bc20ba6-1e6d-4eea-83ad-c5cc3ae0e409"); +const LLUUID SND_ROLL_WOOD_RUBBER (SND_NULL); +const LLUUID SND_ROLL_WOOD_WOOD ("2cc8eec4-bb4a-4ba8-b783-71526ec708e8"); +const LLUUID SND_ROLL_WOOD_WOOD_02 ("0a1f8070-a11a-4b4c-b260-5ffb6acb0a5d"); +const LLUUID SND_ROLL_WOOD_WOOD_03 ("160bef64-da9c-4be8-b07b-a5060b501700"); +const LLUUID SND_ROLL_WOOD_WOOD_04 ("1c62ea16-cc60-48ed-829a-68b8f4cf0c1c"); +const LLUUID SND_ROLL_WOOD_WOOD_05 ("be9cc8fe-b920-4bf5-8924-453088cbc03f"); +const LLUUID SND_ROLL_WOOD_WOOD_06 ("a76cfe60-56b0-43b1-8f31-93e56947d78b"); +const LLUUID SND_ROLL_WOOD_WOOD_07 ("0c6aa481-b5bc-4573-ae83-8e16ff27e750"); +const LLUUID SND_ROLL_WOOD_WOOD_08 ("214ab2c7-871a-451b-b0db-4c5677199011"); +const LLUUID SND_ROLL_WOOD_WOOD_09 ("0086e4db-3ac6-4545-b414-6f359bedd9a5"); -LLUUID const SND_SLIDE_STONE_STONE_01 ("2a7dcbd1-d3e6-4767-8432-8322648e7b9d"); +const LLUUID SND_SLIDE_STONE_STONE_01 ("2a7dcbd1-d3e6-4767-8432-8322648e7b9d"); -LLUUID const SND_STONE_DIRT_01 ("97727335-392c-4338-ac4b-23a7883279c2"); -LLUUID const SND_STONE_DIRT_02 ("cbe75eb2-3375-41d8-9e3f-2ae46b4164ed"); -LLUUID const SND_STONE_DIRT_03 ("31e236ee-001b-4c8e-ad6c-c2074cb64357"); -LLUUID const SND_STONE_DIRT_04 ("c8091652-e04b-4a11-84ba-15dba06e7a1b"); +const LLUUID SND_STONE_DIRT_01 ("97727335-392c-4338-ac4b-23a7883279c2"); +const LLUUID SND_STONE_DIRT_02 ("cbe75eb2-3375-41d8-9e3f-2ae46b4164ed"); +const LLUUID SND_STONE_DIRT_03 ("31e236ee-001b-4c8e-ad6c-c2074cb64357"); +const LLUUID SND_STONE_DIRT_04 ("c8091652-e04b-4a11-84ba-15dba06e7a1b"); -LLUUID const SND_STONE_STONE_02 ("ba4ef5ac-7435-4240-b826-c24ba8fa5a78"); -LLUUID const SND_STONE_STONE_04 ("ea296329-0f09-4993-af1b-e6784bab1dc9"); +const LLUUID SND_STONE_STONE_02 ("ba4ef5ac-7435-4240-b826-c24ba8fa5a78"); +const LLUUID SND_STONE_STONE_04 ("ea296329-0f09-4993-af1b-e6784bab1dc9"); + + + +// extra guids +#if 0 +const LLUUID SND_ ("a839b8ac-b0af-4ba9-9fde-188754744e02"); +const LLUUID SND_ ("20165fa8-836f-4993-85dc-1529172dcd14"); +const LLUUID SND_ ("fba8e17b-a4b3-4693-9fce-c14800f8a349"); +const LLUUID SND_ ("2d48db8b-7260-4b02-ad2a-b2c6bee60e94"); +const LLUUID SND_ ("956d344b-1808-4d8b-88b1-cbc82b7a96a1"); +const LLUUID SND_ ("b8303cc6-f0b4-4c6f-a199-81f87aba342e"); +const LLUUID SND_ ("fbf7cd0c-bc8f-4cba-9c19-11f4dd03a06b"); +const LLUUID SND_ ("85047f7d-933a-4ce5-a7b5-34670243e1ab"); +const LLUUID SND_ ("0f81acf7-6a2e-4490-957f-c7b0eda00559"); +const LLUUID SND_ ("5631a6a1-79b4-4de8-bccf-1880b6882da1"); +const LLUUID SND_ ("43c87a6b-ffb2-437b-89a0-9deba890a4fc"); +const LLUUID SND_ ("58878d1d-3156-4d01-ac3c-0c4fb99f4d53"); +const LLUUID SND_ ("9a83f321-44bf-40f6-b006-46c085515345"); +const LLUUID SND_ ("ff144533-33ab-40f2-bac8-39c34699ecc4"); +const LLUUID SND_ ("09018e87-d52c-4cd5-9805-015f413319e7"); +const LLUUID SND_ ("17d4c057-7edd-401e-9589-d5b9fe981bf2"); +#endif diff --git a/indra/llmessage/sound_ids.h b/indra/llmessage/sound_ids.h index aa50a2b88..f67fdd2aa 100644 --- a/indra/llmessage/sound_ids.h +++ b/indra/llmessage/sound_ids.h @@ -39,9 +39,9 @@ class LLUUID; extern const LLUUID SND_NULL; -extern LLUUID const SND_RIDE; -extern LLUUID const SND_SHOT; -extern LLUUID const SND_MORTAR; +extern const LLUUID SND_RIDE; +extern const LLUUID SND_SHOT; +extern const LLUUID SND_MORTAR; extern const LLUUID SND_HIT; extern const LLUUID SND_EXPLOSION; extern const LLUUID SND_BOING; @@ -58,237 +58,238 @@ extern const LLUUID SND_CHIRPDEAD; // Hit by grenade - dead! extern const LLUUID SND_MUNCH; extern const LLUUID SND_PUNCH; -extern LLUUID const SND_SPLASH; -extern LLUUID const SND_CLICK; -extern LLUUID const SND_WHISTLE; -extern LLUUID const SND_TYPING; +extern const LLUUID SND_SPLASH; +extern const LLUUID SND_CLICK; +extern const LLUUID SND_WHISTLE; +extern const LLUUID SND_TYPING; -extern LLUUID const SND_ARROW_SHOT; -extern LLUUID const SND_ARROW_THUD; -extern LLUUID const SND_LASER_SHOT; -extern LLUUID const SND_JET_THRUST; +extern const LLUUID SND_ARROW_SHOT; +extern const LLUUID SND_ARROW_THUD; +extern const LLUUID SND_LASER_SHOT; +extern const LLUUID SND_JET_THRUST; -extern LLUUID const SND_SILENCE; -extern LLUUID const SND_BUBBLES; -extern LLUUID const SND_WELCOME; -extern LLUUID const SND_SQUISH; -extern LLUUID const SND_SUBPOD; -extern LLUUID const SND_FOOTSTEPS; -extern LLUUID const SND_STEP_LEFT; -extern LLUUID const SND_STEP_RIGHT; +extern const LLUUID SND_SILENCE; +extern const LLUUID SND_BUBBLES; +extern const LLUUID SND_WELCOME; +extern const LLUUID SND_SQUISH; +extern const LLUUID SND_SUBPOD; +extern const LLUUID SND_FOOTSTEPS; +extern const LLUUID SND_STEP_LEFT; +extern const LLUUID SND_STEP_RIGHT; -extern LLUUID const SND_BALL_COLLISION; +extern const LLUUID SND_BALL_COLLISION; -extern LLUUID const SND_OOOH_SCARE_ME; -extern LLUUID const SND_PAYBACK_TIME; -extern LLUUID const SND_READY_FOR_BATTLE; +extern const LLUUID SND_OOOH_SCARE_ME; +extern const LLUUID SND_PAYBACK_TIME; +extern const LLUUID SND_READY_FOR_BATTLE; -extern LLUUID const SND_FLESH_FLESH; -extern LLUUID const SND_FLESH_PLASTIC; -extern LLUUID const SND_FLESH_RUBBER; -extern LLUUID const SND_GLASS_FLESH; -extern LLUUID const SND_GLASS_GLASS; -extern LLUUID const SND_GLASS_PLASTIC; -extern LLUUID const SND_GLASS_RUBBER; -extern LLUUID const SND_GLASS_WOOD; -extern LLUUID const SND_METAL_FLESH; -extern LLUUID const SND_METAL_GLASS; -extern LLUUID const SND_METAL_METAL; -extern LLUUID const SND_METAL_PLASTIC; -extern LLUUID const SND_METAL_RUBBER; -extern LLUUID const SND_METAL_WOOD; -extern LLUUID const SND_PLASTIC_PLASTIC; -extern LLUUID const SND_RUBBER_PLASTIC; -extern LLUUID const SND_RUBBER_RUBBER; -extern LLUUID const SND_STONE_FLESH; -extern LLUUID const SND_STONE_GLASS; -extern LLUUID const SND_STONE_METAL; -extern LLUUID const SND_STONE_PLASTIC; -extern LLUUID const SND_STONE_RUBBER; -extern LLUUID const SND_STONE_STONE; -extern LLUUID const SND_STONE_WOOD; -extern LLUUID const SND_WOOD_FLESH; -extern LLUUID const SND_WOOD_PLASTIC; -extern LLUUID const SND_WOOD_RUBBER; -extern LLUUID const SND_WOOD_WOOD; - -extern LLUUID const SND_SLIDE_FLESH_FLESH; -extern LLUUID const SND_SLIDE_FLESH_PLASTIC; -extern LLUUID const SND_SLIDE_FLESH_RUBBER; -extern LLUUID const SND_SLIDE_FLESH_FABRIC; -extern LLUUID const SND_SLIDE_FLESH_GRAVEL; -extern LLUUID const SND_SLIDE_FLESH_GRAVEL_02; -extern LLUUID const SND_SLIDE_FLESH_GRAVEL_03; -extern LLUUID const SND_SLIDE_GLASS_GRAVEL; -extern LLUUID const SND_SLIDE_GLASS_GRAVEL_02; -extern LLUUID const SND_SLIDE_GLASS_GRAVEL_03; -extern LLUUID const SND_SLIDE_GLASS_FLESH; -extern LLUUID const SND_SLIDE_GLASS_GLASS; -extern LLUUID const SND_SLIDE_GLASS_PLASTIC; -extern LLUUID const SND_SLIDE_GLASS_RUBBER; -extern LLUUID const SND_SLIDE_GLASS_WOOD; -extern LLUUID const SND_SLIDE_METAL_FABRIC; -extern LLUUID const SND_SLIDE_METAL_FLESH; -extern LLUUID const SND_SLIDE_METAL_FLESH_02; -extern LLUUID const SND_SLIDE_METAL_GLASS; -extern LLUUID const SND_SLIDE_METAL_GLASS_02; -extern LLUUID const SND_SLIDE_METAL_GLASS_03; -extern LLUUID const SND_SLIDE_METAL_GLASS_04; -extern LLUUID const SND_SLIDE_METAL_GRAVEL; -extern LLUUID const SND_SLIDE_METAL_GRAVEL_02; -extern LLUUID const SND_SLIDE_METAL_METAL; -extern LLUUID const SND_SLIDE_METAL_METAL_02; -extern LLUUID const SND_SLIDE_METAL_METAL_03; -extern LLUUID const SND_SLIDE_METAL_METAL_04; -extern LLUUID const SND_SLIDE_METAL_METAL_05; -extern LLUUID const SND_SLIDE_METAL_METAL_06; -extern LLUUID const SND_SLIDE_METAL_PLASTIC; -extern LLUUID const SND_SLIDE_METAL_RUBBER; -extern LLUUID const SND_SLIDE_METAL_WOOD; -extern LLUUID const SND_SLIDE_METAL_WOOD_02; -extern LLUUID const SND_SLIDE_METAL_WOOD_03; -extern LLUUID const SND_SLIDE_METAL_WOOD_04; -extern LLUUID const SND_SLIDE_METAL_WOOD_05; -extern LLUUID const SND_SLIDE_METAL_WOOD_06; -extern LLUUID const SND_SLIDE_METAL_WOOD_07; -extern LLUUID const SND_SLIDE_METAL_WOOD_08; -extern LLUUID const SND_SLIDE_PLASTIC_GRAVEL; -extern LLUUID const SND_SLIDE_PLASTIC_GRAVEL_02; -extern LLUUID const SND_SLIDE_PLASTIC_GRAVEL_03; -extern LLUUID const SND_SLIDE_PLASTIC_GRAVEL_04; -extern LLUUID const SND_SLIDE_PLASTIC_GRAVEL_05; -extern LLUUID const SND_SLIDE_PLASTIC_GRAVEL_06; -extern LLUUID const SND_SLIDE_PLASTIC_PLASTIC; -extern LLUUID const SND_SLIDE_PLASTIC_PLASTIC_02; -extern LLUUID const SND_SLIDE_PLASTIC_PLASTIC_03; -extern LLUUID const SND_SLIDE_PLASTIC_FABRIC; -extern LLUUID const SND_SLIDE_PLASTIC_FABRIC_02; -extern LLUUID const SND_SLIDE_PLASTIC_FABRIC_03; -extern LLUUID const SND_SLIDE_PLASTIC_FABRIC_04; -extern LLUUID const SND_SLIDE_RUBBER_PLASTIC; -extern LLUUID const SND_SLIDE_RUBBER_PLASTIC_02; -extern LLUUID const SND_SLIDE_RUBBER_PLASTIC_03; -extern LLUUID const SND_SLIDE_RUBBER_RUBBER; -extern LLUUID const SND_SLIDE_STONE_FLESH; -extern LLUUID const SND_SLIDE_STONE_GLASS; -extern LLUUID const SND_SLIDE_STONE_METAL; -extern LLUUID const SND_SLIDE_STONE_PLASTIC; -extern LLUUID const SND_SLIDE_STONE_PLASTIC_02; -extern LLUUID const SND_SLIDE_STONE_PLASTIC_03; -extern LLUUID const SND_SLIDE_STONE_RUBBER; -extern LLUUID const SND_SLIDE_STONE_RUBBER_02; -extern LLUUID const SND_SLIDE_STONE_STONE; -extern LLUUID const SND_SLIDE_STONE_STONE_02; -extern LLUUID const SND_SLIDE_STONE_WOOD; -extern LLUUID const SND_SLIDE_STONE_WOOD_02; -extern LLUUID const SND_SLIDE_STONE_WOOD_03; -extern LLUUID const SND_SLIDE_STONE_WOOD_04; -extern LLUUID const SND_SLIDE_WOOD_FABRIC; -extern LLUUID const SND_SLIDE_WOOD_FABRIC_02; -extern LLUUID const SND_SLIDE_WOOD_FABRIC_03; -extern LLUUID const SND_SLIDE_WOOD_FABRIC_04; -extern LLUUID const SND_SLIDE_WOOD_FLESH; -extern LLUUID const SND_SLIDE_WOOD_FLESH_02; -extern LLUUID const SND_SLIDE_WOOD_FLESH_03; -extern LLUUID const SND_SLIDE_WOOD_FLESH_04; -extern LLUUID const SND_SLIDE_WOOD_GRAVEL; -extern LLUUID const SND_SLIDE_WOOD_GRAVEL_02; -extern LLUUID const SND_SLIDE_WOOD_GRAVEL_03; -extern LLUUID const SND_SLIDE_WOOD_GRAVEL_04; -extern LLUUID const SND_SLIDE_WOOD_PLASTIC; -extern LLUUID const SND_SLIDE_WOOD_PLASTIC_02; -extern LLUUID const SND_SLIDE_WOOD_PLASTIC_03; -extern LLUUID const SND_SLIDE_WOOD_RUBBER; -extern LLUUID const SND_SLIDE_WOOD_WOOD; -extern LLUUID const SND_SLIDE_WOOD_WOOD_02; -extern LLUUID const SND_SLIDE_WOOD_WOOD_03; -extern LLUUID const SND_SLIDE_WOOD_WOOD_04; -extern LLUUID const SND_SLIDE_WOOD_WOOD_05; -extern LLUUID const SND_SLIDE_WOOD_WOOD_06; -extern LLUUID const SND_SLIDE_WOOD_WOOD_07; -extern LLUUID const SND_SLIDE_WOOD_WOOD_08; +extern const LLUUID SND_FLESH_FLESH; +extern const LLUUID SND_FLESH_PLASTIC; +extern const LLUUID SND_FLESH_RUBBER; +extern const LLUUID SND_GLASS_FLESH; +extern const LLUUID SND_GLASS_GLASS; +extern const LLUUID SND_GLASS_PLASTIC; +extern const LLUUID SND_GLASS_RUBBER; +extern const LLUUID SND_GLASS_WOOD; +extern const LLUUID SND_METAL_FLESH; +extern const LLUUID SND_METAL_GLASS; +extern const LLUUID SND_METAL_METAL; +extern const LLUUID SND_METAL_PLASTIC; +extern const LLUUID SND_METAL_RUBBER; +extern const LLUUID SND_METAL_WOOD; +extern const LLUUID SND_PLASTIC_PLASTIC; +extern const LLUUID SND_RUBBER_PLASTIC; +extern const LLUUID SND_RUBBER_RUBBER; +extern const LLUUID SND_STONE_FLESH; +extern const LLUUID SND_STONE_GLASS; +extern const LLUUID SND_STONE_METAL; +extern const LLUUID SND_STONE_PLASTIC; +extern const LLUUID SND_STONE_RUBBER; +extern const LLUUID SND_STONE_STONE; +extern const LLUUID SND_STONE_WOOD; +extern const LLUUID SND_WOOD_FLESH; +extern const LLUUID SND_WOOD_PLASTIC; +extern const LLUUID SND_WOOD_RUBBER; +extern const LLUUID SND_WOOD_WOOD; -extern LLUUID const SND_ROLL_FLESH_FLESH; -extern LLUUID const SND_ROLL_FLESH_PLASTIC; -extern LLUUID const SND_ROLL_FLESH_PLASTIC_02; -extern LLUUID const SND_ROLL_FLESH_RUBBER; -extern LLUUID const SND_ROLL_GLASS_GRAVEL; -extern LLUUID const SND_ROLL_GLASS_GRAVEL_02; -extern LLUUID const SND_ROLL_GLASS_FLESH; -extern LLUUID const SND_ROLL_GLASS_GLASS; -extern LLUUID const SND_ROLL_GLASS_PLASTIC; -extern LLUUID const SND_ROLL_GLASS_RUBBER; -extern LLUUID const SND_ROLL_GLASS_WOOD; -extern LLUUID const SND_ROLL_GLASS_WOOD_02; -extern LLUUID const SND_ROLL_GRAVEL_GRAVEL; -extern LLUUID const SND_ROLL_GRAVEL_GRAVEL_02; -extern LLUUID const SND_ROLL_METAL_FABRIC; -extern LLUUID const SND_ROLL_METAL_FABRIC_02; -extern LLUUID const SND_ROLL_METAL_FLESH; -extern LLUUID const SND_ROLL_METAL_GLASS; -extern LLUUID const SND_ROLL_METAL_GLASS_02; -extern LLUUID const SND_ROLL_METAL_GLASS_03; -extern LLUUID const SND_ROLL_METAL_GRAVEL; -extern LLUUID const SND_ROLL_METAL_METAL; -extern LLUUID const SND_ROLL_METAL_METAL_02; -extern LLUUID const SND_ROLL_METAL_METAL_03; -extern LLUUID const SND_ROLL_METAL_METAL_04; -extern LLUUID const SND_ROLL_METAL_PLASTIC; -extern LLUUID const SND_ROLL_METAL_PLASTIC_01; -extern LLUUID const SND_ROLL_METAL_RUBBER; -extern LLUUID const SND_ROLL_METAL_WOOD; -extern LLUUID const SND_ROLL_METAL_WOOD_02; -extern LLUUID const SND_ROLL_METAL_WOOD_03; -extern LLUUID const SND_ROLL_METAL_WOOD_04; -extern LLUUID const SND_ROLL_METAL_WOOD_05; -extern LLUUID const SND_ROLL_PLASTIC_FABRIC; -extern LLUUID const SND_ROLL_PLASTIC_PLASTIC; -extern LLUUID const SND_ROLL_PLASTIC_PLASTIC_02; -extern LLUUID const SND_ROLL_RUBBER_PLASTIC; -extern LLUUID const SND_ROLL_RUBBER_RUBBER; -extern LLUUID const SND_ROLL_STONE_FLESH; -extern LLUUID const SND_ROLL_STONE_GLASS; -extern LLUUID const SND_ROLL_STONE_METAL; -extern LLUUID const SND_ROLL_STONE_PLASTIC; -extern LLUUID const SND_ROLL_STONE_RUBBER; -extern LLUUID const SND_ROLL_STONE_STONE; -extern LLUUID const SND_ROLL_STONE_STONE_02; -extern LLUUID const SND_ROLL_STONE_STONE_03; -extern LLUUID const SND_ROLL_STONE_STONE_04; -extern LLUUID const SND_ROLL_STONE_STONE_05; -extern LLUUID const SND_ROLL_STONE_WOOD; -extern LLUUID const SND_ROLL_STONE_WOOD_02; -extern LLUUID const SND_ROLL_STONE_WOOD_03; -extern LLUUID const SND_ROLL_STONE_WOOD_04; -extern LLUUID const SND_ROLL_WOOD_FLESH; -extern LLUUID const SND_ROLL_WOOD_FLESH_02; -extern LLUUID const SND_ROLL_WOOD_FLESH_03; -extern LLUUID const SND_ROLL_WOOD_FLESH_04; -extern LLUUID const SND_ROLL_WOOD_GRAVEL; -extern LLUUID const SND_ROLL_WOOD_GRAVEL_02; -extern LLUUID const SND_ROLL_WOOD_GRAVEL_03; -extern LLUUID const SND_ROLL_WOOD_PLASTIC; -extern LLUUID const SND_ROLL_WOOD_PLASTIC_02; -extern LLUUID const SND_ROLL_WOOD_RUBBER; -extern LLUUID const SND_ROLL_WOOD_WOOD; -extern LLUUID const SND_ROLL_WOOD_WOOD_02; -extern LLUUID const SND_ROLL_WOOD_WOOD_03; -extern LLUUID const SND_ROLL_WOOD_WOOD_04; -extern LLUUID const SND_ROLL_WOOD_WOOD_05; -extern LLUUID const SND_ROLL_WOOD_WOOD_06; -extern LLUUID const SND_ROLL_WOOD_WOOD_07; -extern LLUUID const SND_ROLL_WOOD_WOOD_08; -extern LLUUID const SND_ROLL_WOOD_WOOD_09; +extern const LLUUID SND_SLIDE_FLESH_FLESH; +extern const LLUUID SND_SLIDE_FLESH_PLASTIC; +extern const LLUUID SND_SLIDE_FLESH_RUBBER; +extern const LLUUID SND_SLIDE_FLESH_FABRIC; +extern const LLUUID SND_SLIDE_FLESH_GRAVEL; +extern const LLUUID SND_SLIDE_FLESH_GRAVEL_02; +extern const LLUUID SND_SLIDE_FLESH_GRAVEL_03; +extern const LLUUID SND_SLIDE_GLASS_GRAVEL; +extern const LLUUID SND_SLIDE_GLASS_GRAVEL_02; +extern const LLUUID SND_SLIDE_GLASS_GRAVEL_03; +extern const LLUUID SND_SLIDE_GLASS_FLESH; +extern const LLUUID SND_SLIDE_GLASS_GLASS; +extern const LLUUID SND_SLIDE_GLASS_PLASTIC; +extern const LLUUID SND_SLIDE_GLASS_RUBBER; +extern const LLUUID SND_SLIDE_GLASS_WOOD; +extern const LLUUID SND_SLIDE_METAL_FABRIC; +extern const LLUUID SND_SLIDE_METAL_FLESH; +extern const LLUUID SND_SLIDE_METAL_FLESH_02; +extern const LLUUID SND_SLIDE_METAL_GLASS; +extern const LLUUID SND_SLIDE_METAL_GLASS_02; +extern const LLUUID SND_SLIDE_METAL_GLASS_03; +extern const LLUUID SND_SLIDE_METAL_GLASS_04; +extern const LLUUID SND_SLIDE_METAL_GRAVEL; +extern const LLUUID SND_SLIDE_METAL_GRAVEL_02; +extern const LLUUID SND_SLIDE_METAL_METAL; +extern const LLUUID SND_SLIDE_METAL_METAL_02; +extern const LLUUID SND_SLIDE_METAL_METAL_03; +extern const LLUUID SND_SLIDE_METAL_METAL_04; +extern const LLUUID SND_SLIDE_METAL_METAL_05; +extern const LLUUID SND_SLIDE_METAL_METAL_06; +extern const LLUUID SND_SLIDE_METAL_PLASTIC; +extern const LLUUID SND_SLIDE_METAL_RUBBER; +extern const LLUUID SND_SLIDE_METAL_WOOD; +extern const LLUUID SND_SLIDE_METAL_WOOD_02; +extern const LLUUID SND_SLIDE_METAL_WOOD_03; +extern const LLUUID SND_SLIDE_METAL_WOOD_04; +extern const LLUUID SND_SLIDE_METAL_WOOD_05; +extern const LLUUID SND_SLIDE_METAL_WOOD_06; +extern const LLUUID SND_SLIDE_METAL_WOOD_07; +extern const LLUUID SND_SLIDE_METAL_WOOD_08; +extern const LLUUID SND_SLIDE_PLASTIC_GRAVEL; +extern const LLUUID SND_SLIDE_PLASTIC_GRAVEL_02; +extern const LLUUID SND_SLIDE_PLASTIC_GRAVEL_03; +extern const LLUUID SND_SLIDE_PLASTIC_GRAVEL_04; +extern const LLUUID SND_SLIDE_PLASTIC_GRAVEL_05; +extern const LLUUID SND_SLIDE_PLASTIC_GRAVEL_06; +extern const LLUUID SND_SLIDE_PLASTIC_PLASTIC; +extern const LLUUID SND_SLIDE_PLASTIC_PLASTIC_02; +extern const LLUUID SND_SLIDE_PLASTIC_PLASTIC_03; +extern const LLUUID SND_SLIDE_PLASTIC_FABRIC; +extern const LLUUID SND_SLIDE_PLASTIC_FABRIC_02; +extern const LLUUID SND_SLIDE_PLASTIC_FABRIC_03; +extern const LLUUID SND_SLIDE_PLASTIC_FABRIC_04; +extern const LLUUID SND_SLIDE_RUBBER_PLASTIC; +extern const LLUUID SND_SLIDE_RUBBER_PLASTIC_02; +extern const LLUUID SND_SLIDE_RUBBER_PLASTIC_03; +extern const LLUUID SND_SLIDE_RUBBER_RUBBER; +extern const LLUUID SND_SLIDE_STONE_FLESH; +extern const LLUUID SND_SLIDE_STONE_GLASS; +extern const LLUUID SND_SLIDE_STONE_METAL; +extern const LLUUID SND_SLIDE_STONE_PLASTIC; +extern const LLUUID SND_SLIDE_STONE_PLASTIC_02; +extern const LLUUID SND_SLIDE_STONE_PLASTIC_03; +extern const LLUUID SND_SLIDE_STONE_RUBBER; +extern const LLUUID SND_SLIDE_STONE_RUBBER_02; +extern const LLUUID SND_SLIDE_STONE_STONE; +extern const LLUUID SND_SLIDE_STONE_STONE_02; +extern const LLUUID SND_SLIDE_STONE_WOOD; +extern const LLUUID SND_SLIDE_STONE_WOOD_02; +extern const LLUUID SND_SLIDE_STONE_WOOD_03; +extern const LLUUID SND_SLIDE_STONE_WOOD_04; +extern const LLUUID SND_SLIDE_WOOD_FABRIC; +extern const LLUUID SND_SLIDE_WOOD_FABRIC_02; +extern const LLUUID SND_SLIDE_WOOD_FABRIC_03; +extern const LLUUID SND_SLIDE_WOOD_FABRIC_04; +extern const LLUUID SND_SLIDE_WOOD_FLESH; +extern const LLUUID SND_SLIDE_WOOD_FLESH_02; +extern const LLUUID SND_SLIDE_WOOD_FLESH_03; +extern const LLUUID SND_SLIDE_WOOD_FLESH_04; +extern const LLUUID SND_SLIDE_WOOD_GRAVEL; +extern const LLUUID SND_SLIDE_WOOD_GRAVEL_02; +extern const LLUUID SND_SLIDE_WOOD_GRAVEL_03; +extern const LLUUID SND_SLIDE_WOOD_GRAVEL_04; +extern const LLUUID SND_SLIDE_WOOD_PLASTIC; +extern const LLUUID SND_SLIDE_WOOD_PLASTIC_02; +extern const LLUUID SND_SLIDE_WOOD_PLASTIC_03; +extern const LLUUID SND_SLIDE_WOOD_RUBBER; +extern const LLUUID SND_SLIDE_WOOD_WOOD; +extern const LLUUID SND_SLIDE_WOOD_WOOD_02; +extern const LLUUID SND_SLIDE_WOOD_WOOD_03; +extern const LLUUID SND_SLIDE_WOOD_WOOD_04; +extern const LLUUID SND_SLIDE_WOOD_WOOD_05; +extern const LLUUID SND_SLIDE_WOOD_WOOD_06; +extern const LLUUID SND_SLIDE_WOOD_WOOD_07; +extern const LLUUID SND_SLIDE_WOOD_WOOD_08; -extern LLUUID const SND_SLIDE_STONE_STONE_01; -extern LLUUID const SND_STONE_DIRT_01; -extern LLUUID const SND_STONE_DIRT_02; -extern LLUUID const SND_STONE_DIRT_03; -extern LLUUID const SND_STONE_DIRT_04; +extern const LLUUID SND_ROLL_FLESH_FLESH; +extern const LLUUID SND_ROLL_FLESH_PLASTIC; +extern const LLUUID SND_ROLL_FLESH_PLASTIC_02; +extern const LLUUID SND_ROLL_FLESH_RUBBER; +extern const LLUUID SND_ROLL_GLASS_GRAVEL; +extern const LLUUID SND_ROLL_GLASS_GRAVEL_02; +extern const LLUUID SND_ROLL_GLASS_FLESH; +extern const LLUUID SND_ROLL_GLASS_GLASS; +extern const LLUUID SND_ROLL_GLASS_PLASTIC; +extern const LLUUID SND_ROLL_GLASS_RUBBER; +extern const LLUUID SND_ROLL_GLASS_WOOD; +extern const LLUUID SND_ROLL_GLASS_WOOD_02; +extern const LLUUID SND_ROLL_GRAVEL_GRAVEL; +extern const LLUUID SND_ROLL_GRAVEL_GRAVEL_02; +extern const LLUUID SND_ROLL_METAL_FABRIC; +extern const LLUUID SND_ROLL_METAL_FABRIC_02; +extern const LLUUID SND_ROLL_METAL_FLESH; +extern const LLUUID SND_ROLL_METAL_GLASS; +extern const LLUUID SND_ROLL_METAL_GLASS_02; +extern const LLUUID SND_ROLL_METAL_GLASS_03; +extern const LLUUID SND_ROLL_METAL_GRAVEL; +extern const LLUUID SND_ROLL_METAL_METAL; +extern const LLUUID SND_ROLL_METAL_METAL_02; +extern const LLUUID SND_ROLL_METAL_METAL_03; +extern const LLUUID SND_ROLL_METAL_METAL_04; +extern const LLUUID SND_ROLL_METAL_PLASTIC; +extern const LLUUID SND_ROLL_METAL_PLASTIC_01; +extern const LLUUID SND_ROLL_METAL_RUBBER; +extern const LLUUID SND_ROLL_METAL_WOOD; +extern const LLUUID SND_ROLL_METAL_WOOD_02; +extern const LLUUID SND_ROLL_METAL_WOOD_03; +extern const LLUUID SND_ROLL_METAL_WOOD_04; +extern const LLUUID SND_ROLL_METAL_WOOD_05; +extern const LLUUID SND_ROLL_PLASTIC_FABRIC; +extern const LLUUID SND_ROLL_PLASTIC_PLASTIC; +extern const LLUUID SND_ROLL_PLASTIC_PLASTIC_02; +extern const LLUUID SND_ROLL_RUBBER_PLASTIC; +extern const LLUUID SND_ROLL_RUBBER_RUBBER; +extern const LLUUID SND_ROLL_STONE_FLESH; +extern const LLUUID SND_ROLL_STONE_GLASS; +extern const LLUUID SND_ROLL_STONE_METAL; +extern const LLUUID SND_ROLL_STONE_PLASTIC; +extern const LLUUID SND_ROLL_STONE_RUBBER; +extern const LLUUID SND_ROLL_STONE_STONE; +extern const LLUUID SND_ROLL_STONE_STONE_02; +extern const LLUUID SND_ROLL_STONE_STONE_03; +extern const LLUUID SND_ROLL_STONE_STONE_04; +extern const LLUUID SND_ROLL_STONE_STONE_05; +extern const LLUUID SND_ROLL_STONE_WOOD; +extern const LLUUID SND_ROLL_STONE_WOOD_02; +extern const LLUUID SND_ROLL_STONE_WOOD_03; +extern const LLUUID SND_ROLL_STONE_WOOD_04; +extern const LLUUID SND_ROLL_WOOD_FLESH; +extern const LLUUID SND_ROLL_WOOD_FLESH_02; +extern const LLUUID SND_ROLL_WOOD_FLESH_03; +extern const LLUUID SND_ROLL_WOOD_FLESH_04; +extern const LLUUID SND_ROLL_WOOD_GRAVEL; +extern const LLUUID SND_ROLL_WOOD_GRAVEL_02; +extern const LLUUID SND_ROLL_WOOD_GRAVEL_03; +extern const LLUUID SND_ROLL_WOOD_PLASTIC; +extern const LLUUID SND_ROLL_WOOD_PLASTIC_02; +extern const LLUUID SND_ROLL_WOOD_RUBBER; +extern const LLUUID SND_ROLL_WOOD_WOOD; +extern const LLUUID SND_ROLL_WOOD_WOOD_02; +extern const LLUUID SND_ROLL_WOOD_WOOD_03; +extern const LLUUID SND_ROLL_WOOD_WOOD_04; +extern const LLUUID SND_ROLL_WOOD_WOOD_05; +extern const LLUUID SND_ROLL_WOOD_WOOD_06; +extern const LLUUID SND_ROLL_WOOD_WOOD_07; +extern const LLUUID SND_ROLL_WOOD_WOOD_08; +extern const LLUUID SND_ROLL_WOOD_WOOD_09; -extern LLUUID const SND_STONE_STONE_02; -extern LLUUID const SND_STONE_STONE_04; +extern const LLUUID SND_SLIDE_STONE_STONE_01; + +extern const LLUUID SND_STONE_DIRT_01; +extern const LLUUID SND_STONE_DIRT_02; +extern const LLUUID SND_STONE_DIRT_03; +extern const LLUUID SND_STONE_DIRT_04; + +extern const LLUUID SND_STONE_STONE_02; +extern const LLUUID SND_STONE_STONE_04; #endif diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 9bbb07583..97cf8e107 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1236,12 +1236,12 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const return FALSE; } -S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name) +S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name) { return(unpackTEMessage(mesgsys,block_name,-1)); } -S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, const S32 block_num) +S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num) { // use a negative block_num to indicate a single-block read (a non-variable block) S32 retval = 0; @@ -1515,6 +1515,8 @@ BOOL LLNetworkData::isValid(U16 param_type, U32 size) return (size == 16); case PARAMS_SCULPT: return (size == 17); + case PARAMS_LIGHT_IMAGE: + return (size == 28); } return FALSE; @@ -1847,3 +1849,78 @@ bool LLSculptParams::fromLLSD(LLSD& sd) return false; } +//============================================================================ + +LLLightImageParams::LLLightImageParams() +{ + mType = PARAMS_LIGHT_IMAGE; + mParams.setVec(F_PI*0.5f, 0.f, 0.f); +} + +BOOL LLLightImageParams::pack(LLDataPacker &dp) const +{ + dp.packUUID(mLightTexture, "texture"); + dp.packVector3(mParams, "params"); + + return TRUE; +} + +BOOL LLLightImageParams::unpack(LLDataPacker &dp) +{ + dp.unpackUUID(mLightTexture, "texture"); + dp.unpackVector3(mParams, "params"); + + return TRUE; +} + +bool LLLightImageParams::operator==(const LLNetworkData& data) const +{ + if (data.mType != PARAMS_LIGHT_IMAGE) + { + return false; + } + + const LLLightImageParams *param = (const LLLightImageParams*)&data; + if ( (param->mLightTexture != mLightTexture) ) + { + return false; + } + + if ( (param->mParams != mParams ) ) + { + return false; + } + + return true; +} + +void LLLightImageParams::copy(const LLNetworkData& data) +{ + const LLLightImageParams *param = (LLLightImageParams*)&data; + mLightTexture = param->mLightTexture; + mParams = param->mParams; +} + + + +LLSD LLLightImageParams::asLLSD() const +{ + LLSD sd; + + sd["texture"] = mLightTexture; + sd["params"] = mParams.getValue(); + + return sd; +} + +bool LLLightImageParams::fromLLSD(LLSD& sd) +{ + if (sd.has("texture")) + { + setLightTexture( sd["texture"] ); + setParams( LLVector3( sd["params"] ) ); + return true; + } + + return false; +} diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 03769a87a..c9b035db3 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -107,7 +107,8 @@ public: { PARAMS_FLEXIBLE = 0x10, PARAMS_LIGHT = 0x20, - PARAMS_SCULPT = 0x30 + PARAMS_SCULPT = 0x30, + PARAMS_LIGHT_IMAGE = 0x40, }; public: @@ -267,6 +268,29 @@ public: U8 getSculptType() const { return mSculptType; } }; +class LLLightImageParams : public LLNetworkData +{ +protected: + LLUUID mLightTexture; + LLVector3 mParams; + +public: + LLLightImageParams(); + /*virtual*/ BOOL pack(LLDataPacker &dp) const; + /*virtual*/ BOOL unpack(LLDataPacker &dp); + /*virtual*/ bool operator==(const LLNetworkData& data) const; + /*virtual*/ void copy(const LLNetworkData& data); + LLSD asLLSD() const; + operator LLSD() const { return asLLSD(); } + bool fromLLSD(LLSD& sd); + + void setLightTexture(const LLUUID& id) { mLightTexture = id; } + LLUUID getLightTexture() const { return mLightTexture; } + bool isLightSpotlight() const { return mLightTexture.notNull(); } + void setParams(const LLVector3& params) { mParams = params; } + LLVector3 getParams() const { return mParams; } + +}; class LLPrimitive : public LLXform @@ -340,8 +364,8 @@ public: S32 unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 data_size, U8 face_count, EMsgVariableType type); BOOL packTEMessage(LLMessageSystem *mesgsys, int shield = 0, std::string client_str = "") const; BOOL packTEMessage(LLDataPacker &dp) const; - S32 unpackTEMessage(LLMessageSystem *mesgsys, char *block_name); - S32 unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, const S32 block_num); // Variable num of blocks + S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name); + S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num); // Variable num of blocks BOOL unpackTEMessage(LLDataPacker &dp); #ifdef CHECK_FOR_FINITE diff --git a/indra/llprimitive/llvolumemessage.cpp b/indra/llprimitive/llvolumemessage.cpp index dcfecb140..273ed1b7e 100644 --- a/indra/llprimitive/llvolumemessage.cpp +++ b/indra/llprimitive/llvolumemessage.cpp @@ -100,7 +100,7 @@ bool LLVolumeMessage::packProfileParams( bool LLVolumeMessage::unpackProfileParams( LLProfileParams* params, LLMessageSystem* mesgsys, - char* block_name, + char const* block_name, S32 block_num) { bool ok = true; @@ -328,7 +328,7 @@ bool LLVolumeMessage::packPathParams( bool LLVolumeMessage::unpackPathParams( LLPathParams* params, LLMessageSystem* mesgsys, - char* block_name, + char const* block_name, S32 block_num) { U8 curve; @@ -528,7 +528,7 @@ bool LLVolumeMessage::packVolumeParams(const LLVolumeParams* params, LLDataPacke bool LLVolumeMessage::unpackVolumeParams( LLVolumeParams* params, LLMessageSystem* mesgsys, - char* block_name, + char const* block_name, S32 block_num) { bool ok = true; diff --git a/indra/llprimitive/llvolumemessage.h b/indra/llprimitive/llvolumemessage.h index 514c7007a..aa88577ac 100644 --- a/indra/llprimitive/llvolumemessage.h +++ b/indra/llprimitive/llvolumemessage.h @@ -55,7 +55,7 @@ protected: static bool unpackProfileParams( LLProfileParams* params, LLMessageSystem* mesgsys, - char* block_name, + char const* block_name, S32 block_num = 0); static bool unpackProfileParams(LLProfileParams* params, LLDataPacker& dp); @@ -66,7 +66,7 @@ protected: static bool unpackPathParams( LLPathParams* params, LLMessageSystem* mesgsys, - char* block_name, + char const* block_name, S32 block_num = 0); static bool unpackPathParams(LLPathParams* params, LLDataPacker& dp); @@ -89,7 +89,7 @@ public: static bool unpackVolumeParams( LLVolumeParams* params, LLMessageSystem* mesgsys, - char* block_name, + char const* block_name, S32 block_num = 0); static bool unpackVolumeParams(LLVolumeParams* params, LLDataPacker &dp); }; diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index d708398b2..e34b7f305 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -64,7 +64,6 @@ LLMatrix4 gGLObliqueProjectionInverse; #define LL_GL_NAME_POOLING 0 -LLGLNamePool::pool_list_t LLGLNamePool::sInstances; std::list LLGLUpdate::sGLQ; #if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS @@ -291,6 +290,7 @@ LLGLManager::LLGLManager() : mHasVertexShader(FALSE), mHasFragmentShader(FALSE), mHasOcclusionQuery(FALSE), + mHasOcclusionQuery2(FALSE), mHasPointParameters(FALSE), mHasDrawBuffers(FALSE), mHasTextureRectangle(FALSE), @@ -623,6 +623,7 @@ void LLGLManager::initExtensions() mHasARBEnvCombine = ExtensionExists("GL_ARB_texture_env_combine", gGLHExts.mSysExts); mHasCompressedTextures = glh_init_extensions("GL_ARB_texture_compression"); mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts); + mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts); mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts); mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts); // mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad @@ -741,6 +742,10 @@ void LLGLManager::initExtensions() { LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query" << LL_ENDL; } + if (!mHasOcclusionQuery2) + { + LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query2" << LL_ENDL; + } if (!mHasPointParameters) { LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_point_parameters" << LL_ENDL; @@ -1620,12 +1625,17 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor } } -LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& modelview, const glh::matrix4f& projection) +LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& modelview, const glh::matrix4f& projection, bool apply) { - mModelview = modelview; - mProjection = projection; + mApply = apply; - setPlane(p.mV[0], p.mV[1], p.mV[2], p.mV[3]); + if (mApply) + { + mModelview = modelview; + mProjection = projection; + + setPlane(p[0], p[1], p[2], p[3]); + } } void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d) @@ -1656,31 +1666,20 @@ void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d) LLGLUserClipPlane::~LLGLUserClipPlane() { - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); + if (mApply) + { + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + } } LLGLNamePool::LLGLNamePool() { } -void LLGLNamePool::registerPool(LLGLNamePool* pool) -{ - pool_list_t::iterator iter = std::find(sInstances.begin(), sInstances.end(), pool); - if (iter == sInstances.end()) - { - sInstances.push_back(pool); - } -} - LLGLNamePool::~LLGLNamePool() { - pool_list_t::iterator iter = std::find(sInstances.begin(), sInstances.end(), this); - if (iter != sInstances.end()) - { - sInstances.erase(iter); - } } void LLGLNamePool::upkeep() @@ -1748,20 +1747,22 @@ void LLGLNamePool::release(GLuint name) //static void LLGLNamePool::upkeepPools() { - for (pool_list_t::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) + tracker_t::LLInstanceTrackerScopedGuard guard; + for (tracker_t::instance_iter iter = guard.beginInstances(); iter != guard.endInstances(); ++iter) { - LLGLNamePool* pool = *iter; - pool->upkeep(); + LLGLNamePool & pool = *iter; + pool.upkeep(); } } //static void LLGLNamePool::cleanupPools() { - for (pool_list_t::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) + tracker_t::LLInstanceTrackerScopedGuard guard; + for (tracker_t::instance_iter iter = guard.beginInstances(); iter != guard.endInstances(); ++iter) { - LLGLNamePool* pool = *iter; - pool->cleanup(); + LLGLNamePool & pool = *iter; + pool.cleanup(); } } @@ -1844,11 +1845,15 @@ void LLGLDepthTest::checkState() } } } -LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P) + +LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P, U32 layer) { + + F32 depth = 0.99999f - 0.0001f * layer; + for (U32 i = 0; i < 4; i++) { - P.element(2, i) = P.element(3, i) * 0.99999f; + P.element(2, i) = P.element(3, i) * depth; } glMatrixMode(GL_PROJECTION); diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index da4bde75f..217b6f26e 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -46,6 +46,7 @@ #include "v4math.h" #include "llplane.h" #include "llgltypes.h" +#include "llinstancetracker.h" #include "llglheaders.h" #include "glh/glh_linear.h" @@ -88,6 +89,7 @@ public: BOOL mHasVertexShader; BOOL mHasFragmentShader; BOOL mHasOcclusionQuery; + BOOL mHasOcclusionQuery2; BOOL mHasPointParameters; BOOL mHasDrawBuffers; BOOL mHasDepthClamp; @@ -292,12 +294,14 @@ class LLGLUserClipPlane { public: - LLGLUserClipPlane(const LLPlane& plane, const glh::matrix4f& modelview, const glh::matrix4f& projection); + LLGLUserClipPlane(const LLPlane& plane, const glh::matrix4f& modelview, const glh::matrix4f& projection, bool apply = true); ~LLGLUserClipPlane(); void setPlane(F32 a, F32 b, F32 c, F32 d); private: + bool mApply; + glh::matrix4f mProjection; glh::matrix4f mModelview; }; @@ -313,7 +317,7 @@ private: class LLGLSquashToFarClip { public: - LLGLSquashToFarClip(glh::matrix4f projection); + LLGLSquashToFarClip(glh::matrix4f projection, U32 layer = 0); ~LLGLSquashToFarClip(); }; @@ -321,9 +325,11 @@ public: Generic pooling scheme for things which use GL names (used for occlusion queries and vertex buffer objects). Prevents thrashing of GL name caches by avoiding calls to glGenFoo and glDeleteFoo. */ -class LLGLNamePool +class LLGLNamePool : public LLInstanceTracker { public: + typedef LLInstanceTracker tracker_t; + struct NameEntry { GLuint name; @@ -350,13 +356,11 @@ public: GLuint allocate(); void release(GLuint name); - static void registerPool(LLGLNamePool* pool); static void upkeepPools(); static void cleanupPools(); protected: typedef std::vector pool_list_t; - static pool_list_t sInstances; virtual GLuint allocateName() = 0; virtual void releaseName(GLuint name) = 0; diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 057b025d9..4f767e50e 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -717,10 +717,21 @@ GLint LLGLSLShader::getUniformLocation(const string& uniform) return iter->second; } } - return -1; } +GLint LLGLSLShader::getAttribLocation(U32 attrib) +{ + if (attrib < mAttribute.size()) + { + return mAttribute[attrib]; + } + else + { + return -1; + } +} + void LLGLSLShader::uniform1i(const string& uniform, GLint v) { GLint location = getUniformLocation(uniform); diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 1f46a7b4f..3c47e7504 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -109,7 +109,7 @@ public: void vertexAttrib4fv(U32 index, GLfloat* v); GLint getUniformLocation(const std::string& uniform); - + GLint getAttribLocation(U32 attrib); GLint mapUniformTextureChannel(GLint location, GLenum type); diff --git a/indra/llrender/llglstates.h b/indra/llrender/llglstates.h index 9ade49e4e..e26aead67 100644 --- a/indra/llrender/llglstates.h +++ b/indra/llrender/llglstates.h @@ -262,25 +262,4 @@ public: //---------------------------------------------------------------------------- - -class LLGLSBlendFunc : public LLGLSPipeline { -protected: - GLint mSavedSrc, mSavedDst; - LLGLEnable mBlend; - -public: - LLGLSBlendFunc(GLenum srcFunc, GLenum dstFunc) : - mBlend(GL_BLEND) - { - glGetIntegerv(GL_BLEND_SRC, &mSavedSrc); - glGetIntegerv(GL_BLEND_DST, &mSavedDst); - glBlendFunc(srcFunc, dstFunc); - } - - ~LLGLSBlendFunc(void) { - glBlendFunc(mSavedSrc, mSavedDst); - } -}; - - #endif diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 5bc77f437..3eca7daea 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -45,10 +45,12 @@ LLRender gGL; // Handy copies of last good GL matrices F64 gGLModelView[16]; F64 gGLLastModelView[16]; +F64 gGLLastProjection[16]; F64 gGLProjection[16]; S32 gGLViewport[4]; static const U32 LL_NUM_TEXTURE_LAYERS = 8; +static const U32 LL_NUM_LIGHT_UNITS = 8; static GLenum sGLTextureType[] = { @@ -144,7 +146,7 @@ void LLTexUnit::activate(void) { if (mIndex < 0) return; - if (gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty) + if ((S32)gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty) { glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); gGL.mCurrTextureUnitIndex = mIndex; @@ -729,6 +731,130 @@ void LLTexUnit::debugTextureUnit(void) } } +LLLightState::LLLightState(S32 index) +: mIndex(index), + mEnabled(false), + mConstantAtten(1.f), + mLinearAtten(0.f), + mQuadraticAtten(0.f), + mSpotExponent(0.f), + mSpotCutoff(180.f) +{ + if (mIndex == 0) + { + mDiffuse.set(1,1,1,1); + mSpecular.set(1,1,1,1); + } + + mAmbient.set(0,0,0,1); + mPosition.set(0,0,1,0); + mSpotDirection.set(0,0,-1); + +} + +void LLLightState::enable() +{ + if (!mEnabled) + { + glEnable(GL_LIGHT0+mIndex); + mEnabled = true; + } +} + +void LLLightState::disable() +{ + if (mEnabled) + { + glDisable(GL_LIGHT0+mIndex); + mEnabled = false; + } +} + +void LLLightState::setDiffuse(const LLColor4& diffuse) +{ + if (mDiffuse != diffuse) + { + mDiffuse = diffuse; + glLightfv(GL_LIGHT0+mIndex, GL_DIFFUSE, mDiffuse.mV); + } +} + +void LLLightState::setAmbient(const LLColor4& ambient) +{ + if (mAmbient != ambient) + { + mAmbient = ambient; + glLightfv(GL_LIGHT0+mIndex, GL_AMBIENT, mAmbient.mV); + } +} + +void LLLightState::setSpecular(const LLColor4& specular) +{ + if (mSpecular != specular) + { + mSpecular = specular; + glLightfv(GL_LIGHT0+mIndex, GL_SPECULAR, mSpecular.mV); + } +} + +void LLLightState::setPosition(const LLVector4& position) +{ + //always set position because modelview matrix may have changed + mPosition = position; + glLightfv(GL_LIGHT0+mIndex, GL_POSITION, mPosition.mV); +} + +void LLLightState::setConstantAttenuation(const F32& atten) +{ + if (mConstantAtten != atten) + { + mConstantAtten = atten; + glLightf(GL_LIGHT0+mIndex, GL_CONSTANT_ATTENUATION, atten); + } +} + +void LLLightState::setLinearAttenuation(const F32& atten) +{ + if (mLinearAtten != atten) + { + mLinearAtten = atten; + glLightf(GL_LIGHT0+mIndex, GL_LINEAR_ATTENUATION, atten); + } +} + +void LLLightState::setQuadraticAttenuation(const F32& atten) +{ + if (mQuadraticAtten != atten) + { + mQuadraticAtten = atten; + glLightf(GL_LIGHT0+mIndex, GL_QUADRATIC_ATTENUATION, atten); + } +} + +void LLLightState::setSpotExponent(const F32& exponent) +{ + if (mSpotExponent != exponent) + { + mSpotExponent = exponent; + glLightf(GL_LIGHT0+mIndex, GL_SPOT_EXPONENT, exponent); + } +} + +void LLLightState::setSpotCutoff(const F32& cutoff) +{ + if (mSpotCutoff != cutoff) + { + mSpotCutoff = cutoff; + glLightf(GL_LIGHT0+mIndex, GL_SPOT_CUTOFF, cutoff); + } +} + +void LLLightState::setSpotDirection(const LLVector3& direction) +{ + //always set direction because modelview matrix may have changed + mSpotDirection = direction; + glLightfv(GL_LIGHT0+mIndex, GL_SPOT_DIRECTION, direction.mV); +} LLRender::LLRender() : mDirty(false), @@ -750,6 +876,11 @@ LLRender::LLRender() } mDummyTexUnit = new LLTexUnit(-1); + for (U32 i = 0; i < LL_NUM_LIGHT_UNITS; ++i) + { + mLightState.push_back(new LLLightState(i)); + } + for (U32 i = 0; i < 4; i++) { mCurrColorMask[i] = true; @@ -777,6 +908,12 @@ void LLRender::shutdown() mTexUnits.clear(); delete mDummyTexUnit; mDummyTexUnit = NULL; + + for (U32 i = 0; i < mLightState.size(); ++i) + { + delete mLightState[i]; + } + mLightState.clear(); } void LLRender::refreshState(void) @@ -954,6 +1091,16 @@ LLTexUnit* LLRender::getTexUnit(U32 index) } } +LLLightState* LLRender::getLight(U32 index) +{ + if (index < mLightState.size()) + { + return mLightState[index]; + } + + return NULL; +} + bool LLRender::verifyTexUnitActive(U32 unitToVerify) { if (mCurrTextureUnitIndex == unitToVerify) diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index ab0935bbe..6dd4db9e5 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -43,6 +43,7 @@ #include "v2math.h" #include "v3math.h" #include "v4coloru.h" +#include "v4math.h" #include "llstrider.h" #include "llmemory.h" #include "llglheaders.h" @@ -218,6 +219,40 @@ protected: void setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha = false); }; +class LLLightState +{ +public: + LLLightState(S32 index); + + void enable(); + void disable(); + void setDiffuse(const LLColor4& diffuse); + void setAmbient(const LLColor4& ambient); + void setSpecular(const LLColor4& specular); + void setPosition(const LLVector4& position); + void setConstantAttenuation(const F32& atten); + void setLinearAttenuation(const F32& atten); + void setQuadraticAttenuation(const F32& atten); + void setSpotExponent(const F32& exponent); + void setSpotCutoff(const F32& cutoff); + void setSpotDirection(const LLVector3& direction); + +protected: + S32 mIndex; + bool mEnabled; + LLColor4 mDiffuse; + LLColor4 mAmbient; + LLColor4 mSpecular; + LLVector4 mPosition; + LLVector3 mSpotDirection; + + F32 mConstantAtten; + F32 mLinearAtten; + F32 mQuadraticAtten; + + F32 mSpotExponent; + F32 mSpotCutoff; +}; class LLRender { friend class LLTexUnit; @@ -324,6 +359,8 @@ public: void blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor, eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor); + LLLightState* getLight(U32 index); + LLTexUnit* getTexUnit(U32 index); U32 getCurrentTexUnitIndex(void) const { return mCurrTextureUnitIndex; } @@ -358,6 +395,7 @@ private: LLStrider mColorsp; std::vector mTexUnits; LLTexUnit* mDummyTexUnit; + std::vector mLightState; eBlendFactor mCurrBlendColorSFactor; eBlendFactor mCurrBlendColorDFactor; @@ -369,6 +407,7 @@ private: extern F64 gGLModelView[16]; extern F64 gGLLastModelView[16]; +extern F64 gGLLastProjection[16]; extern F64 gGLProjection[16]; extern S32 gGLViewport[4]; diff --git a/indra/llrender/llrendersphere.cpp b/indra/llrender/llrendersphere.cpp index e22b75392..212963f27 100644 --- a/indra/llrender/llrendersphere.cpp +++ b/indra/llrender/llrendersphere.cpp @@ -68,45 +68,6 @@ void drawSolidSphere(GLdouble radius, GLint slices, GLint stacks) } -// lat = 0 is Z-axis -// lon = 0, lat = 90 at X-axis -void lat2xyz(LLVector3 * result, F32 lat, F32 lon) -{ - // Convert a latitude and longitude to x,y,z on a normal sphere and return it in result - F32 r; - result->mV[VX] = (F32) (cos(lon * DEG_TO_RAD) * sin(lat * DEG_TO_RAD)); - result->mV[VY] = (F32) (sin(lon * DEG_TO_RAD) * sin(lat * DEG_TO_RAD)); - r = (F32) pow(result->mV[VX] * result->mV[VX] + result->mV[VY] * result->mV[VY], 0.5f); - if (r == 1.0f) - { - result->mV[VZ] = 0.0f; - } - else - { - result->mV[VZ] = (F32) pow(1 - r*r, 0.5f); - if (lat > 90.01) - { - result->mV[VZ] *= -1.0; - } - } -} - -void lat2xyz_rad(LLVector3 * result, F32 lat, F32 lon) -{ - // Convert a latitude and longitude to x,y,z on a normal sphere and return it in result - F32 r; - result->mV[VX] = (F32) (cos(lon) * sin(lat)); - result->mV[VY] = (F32) (sin(lon) * sin(lat)); - r = (F32) pow(result->mV[VX] * result->mV[VX] + result->mV[VY] * result->mV[VY], 0.5f); - if (r == 1.0f) - result->mV[VZ] = 0.0f; - else - { - result->mV[VZ] = (F32) pow(1 - r*r, 0.5f); - if (lat > F_PI_BY_TWO) result->mV[VZ] *= -1.0; - } -} - // A couple thoughts on sphere drawing: // 1) You need more slices than stacks, but little less than 2:1 // 2) At low LOD, setting stacks to an odd number avoids a "band" around the equator, making things look smoother @@ -181,3 +142,50 @@ void LLRenderSphere::render() { glCallList(mDList[0]); } + +inline LLVector3 polar_to_cart(F32 latitude, F32 longitude) +{ + return LLVector3(sin(F_TWO_PI * latitude) * cos(F_TWO_PI * longitude), + sin(F_TWO_PI * latitude) * sin(F_TWO_PI * longitude), + cos(F_TWO_PI * latitude)); +} + + +void LLRenderSphere::renderGGL() +{ + S32 const LATITUDE_SLICES = 20; + S32 const LONGITUDE_SLICES = 30; + + if (mSpherePoints.empty()) + { + mSpherePoints.resize(LATITUDE_SLICES + 1); + for (S32 lat_i = 0; lat_i < LATITUDE_SLICES + 1; lat_i++) + { + mSpherePoints[lat_i].resize(LONGITUDE_SLICES + 1); + for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES + 1; lon_i++) + { + F32 lat = (F32)lat_i / LATITUDE_SLICES; + F32 lon = (F32)lon_i / LONGITUDE_SLICES; + + mSpherePoints[lat_i][lon_i] = polar_to_cart(lat, lon); + } + } + } + + gGL.begin(LLRender::TRIANGLES); + + for (S32 lat_i = 0; lat_i < LATITUDE_SLICES; lat_i++) + { + for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES; lon_i++) + { + gGL.vertex3fv(mSpherePoints[lat_i][lon_i].mV); + gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV); + gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV); + + gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV); + gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV); + gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i+1].mV); + } + } + gGL.end(); +} diff --git a/indra/llrender/llrendersphere.h b/indra/llrender/llrendersphere.h index 617ee3e12..ebc71b614 100644 --- a/indra/llrender/llrendersphere.h +++ b/indra/llrender/llrendersphere.h @@ -52,6 +52,10 @@ public: void cleanupGL(); void render(F32 pixel_area); // of a box of size 1.0 at that position void render(); // render at highest LOD + void renderGGL(); // render using LLRender + +private: + std::vector< std::vector > mSpherePoints; }; extern LLRenderSphere gSphere; diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 106b93a21..cced3c408 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -46,16 +46,14 @@ void check_framebuffer_status() { case GL_FRAMEBUFFER_COMPLETE_EXT: break; - case GL_FRAMEBUFFER_UNSUPPORTED_EXT: - llerrs << "WTF?" << llendl; - break; default: - llerrs << "WTF?" << llendl; + llerrs <<"check_framebuffer_status failed" << llendl; + break; } } } -BOOL LLRenderTarget::sUseFBO = FALSE; +bool LLRenderTarget::sUseFBO = false; LLRenderTarget::LLRenderTarget() : mResX(0), @@ -64,8 +62,8 @@ LLRenderTarget::LLRenderTarget() : mFBO(0), mDepth(0), mStencil(0), - mUseDepth(FALSE), - mRenderDepth(FALSE), + mUseDepth(false), + mRenderDepth(false), mUsage(LLTexUnit::TT_TEXTURE), mSamples(0), mSampleBuffer(NULL) @@ -83,7 +81,7 @@ void LLRenderTarget::setSampleBuffer(LLMultisampleBuffer* buffer) mSampleBuffer = buffer; } -void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo) +void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo) { stop_glerror(); mResX = resx; @@ -226,6 +224,7 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target) stop_glerror(); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth); stop_glerror(); + target.mStencil = true; } else { @@ -245,18 +244,6 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target) void LLRenderTarget::release() { - if (mFBO) - { - glDeleteFramebuffersEXT(1, (GLuint *) &mFBO); - mFBO = 0; - } - - if (mTex.size() > 0) - { - LLImageGL::deleteTextures(mTex.size(), &mTex[0]); - mTex.clear(); - } - if (mDepth) { if (mStencil) @@ -271,7 +258,33 @@ void LLRenderTarget::release() } mDepth = 0; } + else if (mUseDepth && mFBO) + { //detach shared depth buffer + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); + if (mStencil) + { //attached as a renderbuffer + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0); + mStencil = false; + } + else + { //attached as a texture + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), 0, 0); + } + mUseDepth = false; + } + if (mFBO) + { + glDeleteFramebuffersEXT(1, (GLuint *) &mFBO); + mFBO = 0; + } + + if (mTex.size() > 0) + { + LLImageGL::deleteTextures(mTex.size(), &mTex[0]); + mTex.clear(); + } mSampleBuffer = NULL; } @@ -351,19 +364,19 @@ U32 LLRenderTarget::getTexture(U32 attachment) const { llerrs << "Invalid attachment index." << llendl; } + if (mTex.empty()) + { + return 0; + } return mTex[attachment]; } void LLRenderTarget::bindTexture(U32 index, S32 channel) { - if (index > mTex.size()-1) - { - llerrs << "Invalid attachment index." << llendl; - } - gGL.getTexUnit(channel)->bindManual(mUsage, mTex[index]); + gGL.getTexUnit(channel)->bindManual(mUsage, getTexture(index)); } -void LLRenderTarget::flush(BOOL fetch_depth) +void LLRenderTarget::flush(bool fetch_depth) { gGL.flush(); if (!mFBO) @@ -439,6 +452,10 @@ void LLRenderTarget::flush(BOOL fetch_depth) void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1, S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter) { + GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE; + + LLGLDepthTest depth(write_depth, write_depth); + gGL.flush(); if (!source.mFBO || !mFBO) { @@ -494,6 +511,10 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0 llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl; } { + GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE; + + LLGLDepthTest depth(write_depth, write_depth); + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source.mSampleBuffer ? source.mSampleBuffer->mFBO : source.mFBO); stop_glerror(); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); @@ -513,9 +534,9 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0 } } -BOOL LLRenderTarget::isComplete() const +bool LLRenderTarget::isComplete() const { - return (!mTex.empty() || mDepth) ? TRUE : FALSE; + return (!mTex.empty() || mDepth) ? true : false; } void LLRenderTarget::getViewport(S32* viewport) @@ -536,10 +557,10 @@ LLMultisampleBuffer::LLMultisampleBuffer() LLMultisampleBuffer::~LLMultisampleBuffer() { - releaseSampleBuffer(); + release(); } -void LLMultisampleBuffer::releaseSampleBuffer() +void LLMultisampleBuffer::release() { if (mFBO) { @@ -588,12 +609,12 @@ void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref) } -void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo ) +void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo ) { allocate(resx,resy,color_fmt,depth,stencil,usage,use_fbo,2); } -void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo, U32 samples ) +void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, U32 samples ) { stop_glerror(); mResX = resx; @@ -603,7 +624,7 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth mUseDepth = depth; mStencil = stencil; - releaseSampleBuffer(); + release(); if (!gGLManager.mHasFramebufferMultisample) { @@ -640,11 +661,9 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth { glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth); } - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } stop_glerror(); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); stop_glerror(); } @@ -683,11 +702,9 @@ void LLMultisampleBuffer::addColorAttachment(U32 color_fmt) { case GL_FRAMEBUFFER_COMPLETE_EXT: break; - case GL_FRAMEBUFFER_UNSUPPORTED_EXT: - llerrs << "WTF?" << llendl; - break; default: - llerrs << "WTF?" << llendl; + llerrs << "WTF? " << std::hex << status << llendl; + break; } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index 9ad4ec3a4..f264276ff 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -69,7 +69,7 @@ class LLRenderTarget { public: //whether or not to use FBO implementation - static BOOL sUseFBO; + static bool sUseFBO; LLRenderTarget(); virtual ~LLRenderTarget(); @@ -77,7 +77,7 @@ public: //allocate resources for rendering //must be called before use //multiple calls will release previously allocated resources - void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, BOOL use_fbo = FALSE); + void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = FALSE); //provide this render target with a multisample resource. void setSampleBuffer(LLMultisampleBuffer* buffer); @@ -94,7 +94,7 @@ public: //free any allocated resources //safe to call redundantly - void release(); + virtual void release(); //bind target for rendering //applies appropriate viewport @@ -121,7 +121,7 @@ public: U32 getTexture(U32 attachment = 0) const; U32 getDepth(void) const { return mDepth; } - BOOL hasStencil() const { return mStencil; } + bool hasStencil() const { return mStencil; } void bindTexture(U32 index, S32 channel); @@ -131,7 +131,7 @@ public: // call bindTarget once, do all your rendering, call flush once // if fetch_depth is TRUE, every effort will be made to copy the depth buffer into // the current depth texture. A depth texture will be allocated if needed. - void flush(BOOL fetch_depth = FALSE); + void flush(bool fetch_depth = FALSE); void copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1, S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter); @@ -142,7 +142,7 @@ public: //Returns TRUE if target is ready to be rendered into. //That is, if the target has been allocated with at least //one renderable attachment (i.e. color buffer, depth buffer). - BOOL isComplete() const; + bool isComplete() const; protected: friend class LLMultisampleBuffer; @@ -151,9 +151,9 @@ protected: std::vector mTex; U32 mFBO; U32 mDepth; - BOOL mStencil; - BOOL mUseDepth; - BOOL mRenderDepth; + bool mStencil; + bool mUseDepth; + bool mRenderDepth; LLTexUnit::eTextureType mUsage; U32 mSamples; LLMultisampleBuffer* mSampleBuffer; @@ -166,12 +166,12 @@ public: LLMultisampleBuffer(); virtual ~LLMultisampleBuffer(); - void releaseSampleBuffer(); + virtual void release(); virtual void bindTarget(); void bindTarget(LLRenderTarget* ref); - virtual void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo); - void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo, U32 samples); + virtual void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo); + void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, U32 samples); virtual void addColorAttachment(U32 color_fmt); virtual void allocateDepth(); }; diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 810d9fa2c..2cb357920 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -226,7 +226,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) else if (features->isFullbright) { - if (features->hasWaterFog) + if (features->isShiny && features->hasWaterFog) + { + if (!shader->attachObject("lighting/lightFullbrightShinyWaterF.glsl")) + { + return FALSE; + } + } + else if (features->hasWaterFog) { if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl")) { diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 8108eeee8..933f5cd35 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -67,6 +67,8 @@ U32 LLVertexBuffer::sAllocatedBytes = 0; BOOL LLVertexBuffer::sMapped = FALSE; BOOL LLVertexBuffer::sUseStreamDraw = TRUE; BOOL LLVertexBuffer::sOmitBlank = FALSE; +BOOL LLVertexBuffer::sPreferStreamDraw = FALSE; +S32 LLVertexBuffer::sWeight4Loc = -1; std::vector LLVertexBuffer::sDeleteList; @@ -88,15 +90,16 @@ void LLVBOPool::releaseName(GLuint name) S32 LLVertexBuffer::sTypeOffsets[LLVertexBuffer::TYPE_MAX] = { - sizeof(LLVector3), // TYPE_VERTEX, - sizeof(LLVector3), // TYPE_NORMAL, + sizeof(LLVector4), // TYPE_VERTEX, + sizeof(LLVector4), // TYPE_NORMAL, sizeof(LLVector2), // TYPE_TEXCOORD0, sizeof(LLVector2), // TYPE_TEXCOORD1, sizeof(LLVector2), // TYPE_TEXCOORD2, sizeof(LLVector2), // TYPE_TEXCOORD3, sizeof(LLColor4U), // TYPE_COLOR, - sizeof(LLVector3), // TYPE_BINORMAL, + sizeof(LLVector4), // TYPE_BINORMAL, sizeof(F32), // TYPE_WEIGHT, + sizeof(LLVector4), // TYPE_WEIGHT4, sizeof(LLVector4), // TYPE_CLOTHWEIGHT, }; @@ -156,11 +159,11 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) } else { //was disabled - if (data_mask & mask[i]) + if (data_mask & mask[i] && i > 0) { //needs to be enabled glEnableClientState(array[i]); } - else if (gDebugGL && glIsEnabled(array[i])) + else if (gDebugGL && i > 0 && glIsEnabled(array[i])) { //needs to be disabled, make sure it was (DEBUG TEMPORARY) llerrs << "Bad client state! " << array[i] << " enabled." << llendl; } @@ -209,23 +212,69 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) glClientActiveTextureARB(GL_TEXTURE0_ARB); } + if (sLastMask & MAP_WEIGHT4) + { + if (sWeight4Loc < 0) + { + llerrs << "Weighting disabled but vertex buffer still bound!" << llendl; + } + + if (!(data_mask & MAP_WEIGHT4)) + { //disable 4-component skin weight + glDisableVertexAttribArrayARB(sWeight4Loc); + } + } + else if (data_mask & MAP_WEIGHT4) + { + if (sWeight4Loc >= 0) + { //enable 4-component skin weight + glEnableVertexAttribArrayARB(sWeight4Loc); + } + } + + sLastMask = data_mask; } } +//static +void LLVertexBuffer::drawArrays(U32 mode, const std::vector& pos, const std::vector& norm) +{ + U32 count = pos.size(); + llassert(norm.size() >= pos.size()); + + unbind(); + + setupClientArrays(MAP_VERTEX | MAP_NORMAL); + + glVertexPointer(3, GL_FLOAT, 0, pos[0].mV); + glNormalPointer(GL_FLOAT, 0, norm[0].mV); + + glDrawArrays(sGLMode[mode], 0, count); +} + +void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const +{ + if (start >= (U32) mRequestedNumVerts || + end >= (U32) mRequestedNumVerts) + { + llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "] vs " << mRequestedNumVerts << llendl; + } + + llassert(mRequestedNumIndices >= 0); + + if (indices_offset >= (U32) mRequestedNumIndices || + indices_offset + count > (U32) mRequestedNumIndices) + { + llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; + } +} + void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const { - if (start >= (U32) mRequestedNumVerts || - end >= (U32) mRequestedNumVerts) - { - llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "]" << llendl; - } + validateRange(start, end, count, indices_offset); - if (indices_offset >= (U32) mRequestedNumIndices || - indices_offset + count > (U32) mRequestedNumIndices) - { - llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; - } + llassert(mRequestedNumVerts >= 0); if (mGLIndices != sGLRenderIndices) { @@ -243,16 +292,19 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi return; } + U16* idx = ((U16*) getIndicesPointer())+indices_offset; + stop_glerror(); glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, - ((U16*) getIndicesPointer()) + indices_offset); + idx); stop_glerror(); } void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const { + llassert(mRequestedNumIndices >= 0); if (indices_offset >= (U32) mRequestedNumIndices || - indices_offset + count > (U32) mRequestedNumIndices) + indices_offset + count > (U32) mRequestedNumIndices) { llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; } @@ -281,6 +333,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const { + llassert(mRequestedNumVerts >= 0); if (first >= (U32) mRequestedNumVerts || first + count > (U32) mRequestedNumVerts) { @@ -317,12 +370,8 @@ void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping) { llinfos << "VBO is disabled." << llendl ; } - + sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ; - LLGLNamePool::registerPool(&sDynamicVBOPool); - LLGLNamePool::registerPool(&sDynamicIBOPool); - LLGLNamePool::registerPool(&sStreamVBOPool); - LLGLNamePool::registerPool(&sStreamIBOPool); } //static @@ -395,6 +444,11 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : { mUsage = 0; } + + if (mUsage == GL_DYNAMIC_DRAW_ARB && sPreferStreamDraw) + { + mUsage = GL_STREAM_DRAW_ARB; + } S32 stride = calcStride(typemask, mOffsets); @@ -431,6 +485,8 @@ LLVertexBuffer::~LLVertexBuffer() destroyGLBuffer(); destroyGLIndices(); sCount--; + + llassert_always(!mMappedData && !mMappedIndexData) ; }; //---------------------------------------------------------------------------- @@ -679,6 +735,11 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + if (nverts < 0 || nindices < 0 || + nverts > 65536) + { + llerrs << "Bad vertex buffer allocation: " << nverts << " : " << nindices << llendl; + } updateNumVerts(nverts); updateNumIndices(nindices); @@ -697,6 +758,9 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) { + llassert(newnverts >= 0); + llassert(newnindices >= 0); + mRequestedNumVerts = newnverts; mRequestedNumIndices = newnindices; @@ -1129,6 +1193,12 @@ bool LLVertexBuffer::getWeightStrider(LLStrider& strider, S32 index) { return VertexBufferStrider::get(*this, strider, index); } + +bool LLVertexBuffer::getWeight4Strider(LLStrider& strider, S32 index) +{ + return VertexBufferStrider::get(*this, strider, index); +} + bool LLVertexBuffer::getClothWeightStrider(LLStrider& strider, S32 index) { return VertexBufferStrider::get(*this, strider, index); @@ -1382,6 +1452,12 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const { glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, stride, (void*)(base + mOffsets[TYPE_WEIGHT])); } + + if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1) + { + glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, stride, (void*)(base+mOffsets[TYPE_WEIGHT4])); + } + if (data_mask & MAP_CLOTHWEIGHT) { glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, stride, (void*)(base + mOffsets[TYPE_CLOTHWEIGHT])); diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 99c016f29..76080558c 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -64,23 +64,38 @@ protected: virtual void releaseName(GLuint name); }; + //============================================================================ // base class class LLVertexBuffer : public LLRefCount { public: + LLVertexBuffer(const LLVertexBuffer& rhs) + { + *this = rhs; + } + + const LLVertexBuffer& operator=(const LLVertexBuffer& rhs) + { + llerrs << "Illegal operation!" << llendl; + return *this; + } static LLVBOPool sStreamVBOPool; static LLVBOPool sDynamicVBOPool; static LLVBOPool sStreamIBOPool; static LLVBOPool sDynamicIBOPool; + static S32 sWeight4Loc; + static BOOL sUseStreamDraw; static BOOL sOmitBlank; - + static BOOL sPreferStreamDraw; + static void initClass(bool use_vbo, bool no_vbo_mapping); static void cleanupClass(); static void setupClientArrays(U32 data_mask); + static void drawArrays(U32 mode, const std::vector& pos, const std::vector& norm); static void clientCopy(F64 max_time = 0.005); //copy data from client to GL static void unbind(); //unbind any bound vertex buffer @@ -101,6 +116,7 @@ public: // These use VertexAttribPointer and should possibly be made generic TYPE_BINORMAL, TYPE_WEIGHT, + TYPE_WEIGHT4, TYPE_CLOTHWEIGHT, TYPE_MAX, TYPE_INDEX, @@ -116,6 +132,7 @@ public: // These use VertexAttribPointer and should possibly be made generic MAP_BINORMAL = (1<& strider, S32 index=0); bool getColorStrider(LLStrider& strider, S32 index=0); bool getWeightStrider(LLStrider& strider, S32 index=0); + bool getWeight4Strider(LLStrider& strider, S32 index=0); bool getClothWeightStrider(LLStrider& strider, S32 index=0); BOOL isEmpty() const { return mEmpty; } @@ -199,6 +217,11 @@ public: void drawArrays(U32 mode, U32 offset, U32 count) const; void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const; + //for debugging, validate data in given range is valid + void validateRange(U32 start, U32 end, U32 count, U32 offset) const; + + + protected: S32 mNumVerts; // Number of vertices allocated S32 mNumIndices; // Number of indices allocated @@ -246,12 +269,12 @@ public: static BOOL sDisableVBOMapping; //disable glMapBufferARB static BOOL sEnableVBOs; - static BOOL sVBOActive; - static BOOL sIBOActive; static S32 sTypeOffsets[TYPE_MAX]; static U32 sGLMode[LLRender::NUM_MODES]; static U32 sGLRenderBuffer; static U32 sGLRenderIndices; + static BOOL sVBOActive; + static BOOL sIBOActive; static U32 sLastMask; static U32 sAllocatedBytes; static U32 sBindCount; diff --git a/indra/llui/lldelayeduidelete.h b/indra/llui/lldelayeduidelete.h index 2f08ee8fa..043e6972e 100644 --- a/indra/llui/lldelayeduidelete.h +++ b/indra/llui/lldelayeduidelete.h @@ -1,7 +1,7 @@ // #ifndef LL_LLDELAYEDUIDELETE_H #define LL_LLDELAYEDUIDELETE_H -#include "lltimer.h" +#include "lleventtimer.h" #include "llview.h" class LLDeleteJob { diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 6bd4e4f22..13ca40cf9 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -908,8 +908,7 @@ mParent(parent) else { LLNotificationChannelPtr p = LLNotifications::instance().getChannel(parent); - LLStandardSignal::slot_type f = boost::bind(&LLNotificationChannelBase::updateItem, this, _1); - p->connectChanged(f); + p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1)); } } @@ -1010,16 +1009,18 @@ bool LLNotifications::uniqueFilter(LLNotificationPtr pNotif) bool LLNotifications::uniqueHandler(const LLSD& payload) { + std::string cmd = payload["sigtype"]; + LLNotificationPtr pNotif = LLNotifications::instance().find(payload["id"].asUUID()); if (pNotif && pNotif->hasUniquenessConstraints()) { - if (payload["sigtype"].asString() == "add") + if (cmd == "add") { // not a duplicate according to uniqueness criteria, so we keep it // and store it for future uniqueness checks mUniqueNotifications.insert(std::make_pair(pNotif->getName(), pNotif)); } - else if (payload["sigtype"].asString() == "delete") + else if (cmd == "delete") { mUniqueNotifications.erase(pNotif->getName()); } @@ -1425,6 +1426,8 @@ LLNotificationPtr LLNotifications::add(const LLNotification::Params& p) void LLNotifications::add(const LLNotificationPtr pNotif) { + if (pNotif == NULL) return; + // first see if we already have it -- if so, that's a problem LLNotificationSet::iterator it=mItems.find(pNotif); if (it != mItems.end()) @@ -1437,6 +1440,8 @@ void LLNotifications::add(const LLNotificationPtr pNotif) void LLNotifications::cancel(LLNotificationPtr pNotif) { + if (pNotif == NULL || pNotif->isCancelled()) return; + LLNotificationSet::iterator it=mItems.find(pNotif); if (it == mItems.end()) { diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index bb379121c..4b325f54d 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -96,6 +96,7 @@ // we want to minimize external dependencies, but this one is important #include "llsd.h" +#include "llinstancetracker.h" // and we need this to manage the notification callbacks #include "llfunctorregistry.h" diff --git a/indra/llui/llui.h b/indra/llui/llui.h index c7b7446a0..abc9a298b 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -602,62 +602,6 @@ public: virtual void cleanUp() = 0; }; -// This mix-in class adds support for tracking all instances of the specificed class parameter T -// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup -// If KEY is not provided, then instances are stored in a simple list -template -class LLInstanceTracker : boost::noncopyable -{ -public: - typedef typename std::map::iterator instance_iter; - typedef typename std::map::const_iterator instance_const_iter; - - static T* getInstance(KEY k) { instance_iter found = sInstances.find(k); return (found == sInstances.end()) ? NULL : found->second; } - - static instance_iter beginInstances() { return sInstances.begin(); } - static instance_iter endInstances() { return sInstances.end(); } - static S32 instanceCount() { return sInstances.size(); } -protected: - LLInstanceTracker(KEY key) { add(key); } - virtual ~LLInstanceTracker() { remove(); } - virtual void setKey(KEY key) { remove(); add(key); } - virtual const KEY& getKey() const { return mKey; } - -private: - void add(KEY key) - { - mKey = key; - sInstances[key] = static_cast(this); - } - void remove() { sInstances.erase(mKey); } - -private: - - KEY mKey; - static std::map sInstances; -}; - -template -class LLInstanceTracker : boost::noncopyable -{ -public: - typedef typename std::set::iterator instance_iter; - typedef typename std::set::const_iterator instance_const_iter; - - static instance_iter instancesBegin() { return sInstances.begin(); } - static instance_iter instancesEnd() { return sInstances.end(); } - static S32 instanceCount() { return sInstances.size(); } - -protected: - LLInstanceTracker() { sInstances.insert(static_cast(this)); } - virtual ~LLInstanceTracker() { sInstances.erase(static_cast(this)); } - - static std::set sInstances; -}; - -template std::map LLInstanceTracker::sInstances; -template std::set LLInstanceTracker::sInstances; - class LLCallbackRegistry { public: diff --git a/indra/newview/app_settings/high_graphics.xml b/indra/newview/app_settings/high_graphics.xml index 6368f7099..2e939f47e 100644 --- a/indra/newview/app_settings/high_graphics.xml +++ b/indra/newview/app_settings/high_graphics.xml @@ -13,7 +13,7 @@ - + diff --git a/indra/newview/app_settings/low_graphics.xml b/indra/newview/app_settings/low_graphics.xml index 3f67a70d7..79b25003f 100644 --- a/indra/newview/app_settings/low_graphics.xml +++ b/indra/newview/app_settings/low_graphics.xml @@ -13,7 +13,7 @@ - + diff --git a/indra/newview/app_settings/mid_graphics.xml b/indra/newview/app_settings/mid_graphics.xml index 12da77da4..4660d0cd4 100644 --- a/indra/newview/app_settings/mid_graphics.xml +++ b/indra/newview/app_settings/mid_graphics.xml @@ -13,7 +13,7 @@ - + diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 944b1fef0..44f05bd68 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -8925,7 +8925,7 @@ Type S32 Value - 35 + 12 RenderAvatarPhysicsLODFactor @@ -8960,24 +8960,22 @@ Value 1 - RenderShadowGaussian - - Comment - Gaussian coefficients for the two shadow/SSAO blurring passes (z component unused). - Persist - 1 - Type - Vector3 - Value - - 2.0 - 2.0 - 0.0 - - - RenderShadowNearDist - - Comment + + RenderLocalLights + + Comment + Whether or not to render local lights. + Persist + 1 + Type + Boolean + Value + 1 + + + RenderShadowNearDist + + Comment Near clip plane of shadow camera (affects precision of depth shadows). Persist 1 @@ -9000,11 +8998,74 @@ Vector3 Value - 4.0 - 8.0 - 24.0 + 1.0 + 12.0 + 32.0 - + + RenderShadowSplitExponent + + Comment + Near clip plane split distances for shadow map frusta (x=perspective, y=ortho, z=transition rate). + Persist + 1 + Type + Vector3 + Value + + 3.0 + 3.0 + 2.0 + + + RenderShadowOrthoClipPlanes + + Comment + Near clip plane split distances for orthographic shadow map frusta. + Persist + 1 + Type + Vector3 + Value + + 4.0 + 8.0 + 24.0 + + + RenderShadowProjOffset + + Comment + Amount to scale distance to virtual origin of shadow perspective projection. + Persist + 1 + Type + F32 + Value + 2.0 + + RenderShadowSlopeThreshold + + Comment + Cutoff slope value for points to affect perspective shadow generation + Persist + 1 + Type + F32 + Value + 0.0 + + RenderShadowProjExponent + + Comment + Exponent applied to transition between ortho and perspective shadow projections based on viewing angle and light vector. + Persist + 1 + Type + F32 + Value + 0.5 + RenderSSAOScale Comment @@ -9025,7 +9086,7 @@ Type U32 Value - 60 + 200 RenderSSAOFactor @@ -9048,7 +9109,7 @@ Vector3 Value - 0.40 + 0.80 1.00 0.00 @@ -9073,7 +9134,7 @@ Type F32 Value - 128 + 64 RenderCubeMap @@ -9163,7 +9224,175 @@ Value 0 - RenderDeferredAlphaSoften + + RenderGIRange + + Comment + Distance to cut off GI effect. + Persist + 1 + Type + F32 + Value + 96 + + + RenderGILuminance + + Comment + Luminance factor of global illumination contribution. + Persist + 1 + Type + F32 + Value + 0.075 + + + RenderGIBrightness + + Comment + Brightness factor of global illumination contribution. + Persist + 1 + Type + F32 + Value + 0.3 + + + RenderGINoise + + Comment + Noise of position sampling for GI photon mapping. + Persist + 1 + Type + F32 + Value + 0.7 + + + RenderGIAttenuation + + Comment + Distance attenuation factor for indirect lighting. + Persist + 1 + Type + F32 + Value + 0.1 + + + RenderGIBlurBrightness + + Comment + Brightness factor of global illumination blur effect. + Persist + 1 + Type + F32 + Value + 1.025 + + + RenderGIBlurEdgeWeight + + Comment + Edge weight for GI soften filter (sharpness). + Persist + 1 + Type + F32 + Value + 0.8 + + + RenderGIBlurIncrement + + Comment + Increment of scale for each pass of global illumination blur effect. + Persist + 1 + Type + F32 + Value + 0.8 + + + RenderLuminanceScale + + Comment + Luminance value scalar for darkening effect. + Persist + 1 + Type + F32 + Value + 1.0 + + + RenderSunLuminanceScale + + Comment + Sun Luminance value scalar for darkening effect. + Persist + 1 + Type + F32 + Value + 1.0 + + + RenderSunLuminanceOffset + + Comment + Sun Luminance value offset for darkening effect. + Persist + 1 + Type + F32 + Value + 0 + + + RenderLuminanceDetail + + Comment + Mipmap level to use for luminance + Persist + 1 + Type + F32 + Value + 16.0 + + + RenderEdgeDepthCutoff + + Comment + Cutoff for depth difference that amounts to an edge. + Persist + 1 + Type + F32 + Value + 0.01 + + RenderEdgeNormCutoff + + Comment + Cutoff for normal difference that amounts to an edge. + Persist + 1 + Type + F32 + Value + 0.25 + + + RenderDeferredAlphaSoften Comment Scalar for softening alpha surfaces (for soft particles). @@ -9185,9 +9414,249 @@ Value 4 - RenderDeferred - - Comment + RenderDeferredSpotShadowBias + + Comment + Bias value for spot shadows (prevent shadow acne). + Persist + 1 + Type + F32 + Value + -64.0 + + RenderDeferredSpotShadowOffset + + Comment + Offset value for spot shadows (prevent shadow acne). + Persist + 1 + Type + F32 + Value + 0.8 + + + RenderShadowBias + + Comment + Bias value for shadows (prevent shadow acne). + Persist + 1 + Type + F32 + Value + -0.008 + + RenderShadowOffset + + Comment + Offset value for shadows (prevent shadow acne). + Persist + 1 + Type + F32 + Value + 0.01 + + + RenderShadowBiasError + + Comment + Error scale for shadow bias (based on altitude). + Persist + 1 + Type + F32 + Value + 0 + + RenderShadowOffsetError + + Comment + Error scale for shadow offset (based on altitude). + Persist + 1 + Type + F32 + Value + 0 + + + RenderSpotLightsInNondeferred + + Comment + Whether to support projectors as spotlights when Lighting and Shadows is disabled + Persist + 1 + Type + Boolean + Value + 0 + + + RenderSpotShadowBias + + Comment + Bias value for shadows (prevent shadow acne). + Persist + 1 + Type + F32 + Value + 0.0 + + RenderSpotShadowOffset + + Comment + Offset value for shadows (prevent shadow acne). + Persist + 1 + Type + F32 + Value + 0.04 + + + RenderShadowResolutionScale + + Comment + Scale of shadow map resolution vs. screen resolution + Persist + 1 + Type + F32 + Value + 1.0 + + + RenderDeferredTreeShadowBias + + Comment + Bias value for tree shadows (prevent shadow acne). + Persist + 1 + Type + F32 + Value + 1.0 + + RenderDeferredTreeShadowOffset + + Comment + Offset value for tree shadows (prevent shadow acne). + Persist + 1 + Type + F32 + Value + 1.0 + + + RenderHoverGlowEnable + + Comment + Show glow effect when hovering on interactive objects. + Persist + 1 + Type + Boolean + Value + 0 + + + RenderHighlightFadeTime + + Comment + Transition time for mouseover highlights. + Persist + 1 + Type + F32 + Value + 0.1 + + + RenderHighlightBrightness + + Comment + Brightness of mouseover highlights. + Persist + 1 + Type + F32 + Value + 4.0 + + + RenderHighlightThickness + + Comment + Thickness of mouseover highlights. + Persist + 1 + Type + F32 + Value + 0.6 + + + RenderHighlightColor + + Comment + Brightness of mouseover highlights. + Persist + 1 + Type + Color4 + Value + + 0.4 + 0.98 + 0.93 + 1.0 + + + + RenderSpecularResX + + Comment + Spec map resolution. + Persist + 1 + Type + U32 + Value + 128 + + + RenderSpecularResY + + Comment + Spec map resolution. + Persist + 1 + Type + U32 + Value + 128 + + + RenderSpecularExponent + + Comment + Specular exponent for generating spec map + Persist + 1 + Type + F32 + Value + 8 + + + RenderDeferred + + Comment Use deferred rendering pipeline. Persist 1 @@ -9196,19 +9665,93 @@ Value 0 - RenderDeferredSunShadow - - Comment - Generate shadows from the sun. - Persist - 1 - Type - Boolean - Value - 1 - - RenderDeferredSunWash - + + RenderDeferredGI + + Comment + Enable GI in deferred renderer. + Persist + 1 + Type + Boolean + Value + 0 + + + RenderDeferredSun + + Comment + Execute sunlight shader in deferred renderer. + Persist + 1 + Type + Boolean + Value + 1 + + + RenderDeferredAtmospheric + + Comment + Execute atmospheric shader in deferred renderer. + Persist + 1 + Type + Boolean + Value + 1 + + + RenderDeferredSSAO + + Comment + Execute screen space ambient occlusion shader in deferred renderer. + Persist + 1 + Type + Boolean + Value + 1 + + + RenderDeferredBlurLight + + Comment + Execute shadow softening shader in deferred renderer. + Persist + 1 + Type + Boolean + Value + 1 + + + RenderDeferredLocalLights + + Comment + Execute local lighting shader in deferred renderer. + Persist + 1 + Type + Boolean + Value + 1 + + + RenderDeferredFullscreenLights + + Comment + Execute local lighting shader in deferred renderer. + Persist + 1 + Type + Boolean + Value + 1 + + + RenderDeferredSunWash + Comment Amount local lights are washed out by sun. Persist @@ -9228,20 +9771,59 @@ F32 Value -0.0001 - - RenderShadowBlurSize - - Comment - Scale of shadow softening kernel. - Persist - 1 - Type - F32 - Value - 0.7 - - RenderShadowBlurSamples - + + RenderShadowErrorCutoff + + Comment + Cutoff error value to use ortho instead of perspective projection. + Persist + 1 + Type + F32 + Value + 5.0 + + RenderShadowFOVCutoff + + Comment + Cutoff FOV to use ortho instead of perspective projection. + Persist + 1 + Type + F32 + Value + 1.1 + + + RenderShadowGaussian + + Comment + Gaussian coefficients for the two shadow/SSAO blurring passes (z component unused). + Persist + 1 + Type + Vector3 + Value + + 3.0 + 2.0 + 0.0 + + + + RenderShadowBlurSize + + Comment + Scale of shadow softening kernel. + Persist + 1 + Type + F32 + Value + 1.4 + + RenderShadowBlurSamples + Comment Number of samples to take for each pass of shadow blur (value range 1-16). Actual number of samples is value * 2 - 1. Persist @@ -9251,6 +9833,104 @@ Value 5 + RenderShadowBlurDistFactor + + Comment + Distance scaler for shadow blur. + Persist + 1 + Type + F32 + Value + 0.1 + + + RenderGIAmbiance + + Comment + Ambiance factor of global illumination contribution. + Persist + 1 + Type + F32 + Value + 0.5 + + + RenderGIMinRenderSize + + Comment + Minimum size of objects to put into GI source map. + Persist + 1 + Type + F32 + Value + 0.5 + + + RenderGIBlurColorCurve + + Comment + Color curve for GI softening kernel + Persist + 1 + Type + Vector3 + Value + + 1.0 + 0.6 + 0.02 + + + + RenderGIBlurPasses + + Comment + Scale of GI softening kernel. + Persist + 1 + Type + U32 + Value + 4 + + + RenderGIBlurSize + + Comment + Scale of GI softening kernel. + Persist + 1 + Type + F32 + Value + 4.0 + + RenderGIBlurSamples + + Comment + Number of samples to take for each pass of GI blur (value range 1-16). Actual number of samples is value * 2 - 1. + Persist + 1 + Type + U32 + Value + 16 + + RenderGIBlurDistFactor + + Comment + Distance scaler for GI blur. + Persist + 1 + Type + F32 + Value + 0.0 + + RenderDynamicLOD Comment @@ -9320,7 +10000,7 @@ RenderFastAlpha Comment - Use lossy alpha rendering optimization (opaque/nonexistent small alpha faces). + Use alpha masks where appropriate. Persist 1 Type @@ -9600,17 +10280,6 @@ Value 0 - RenderLightingDetail - - Comment - Amount of detail for lighting objects/avatars/terrain (0=sun/moon only, 1=enable local lights) - Persist - 1 - Type - S32 - Value - 1 - RenderMaxPartCount Comment @@ -9787,6 +10456,18 @@ Value 2 + RenderShadowDetail + + Comment + Detail of shadows. + Persist + 1 + Type + S32 + Value + 0 + + RenderReflectionRes Comment @@ -9897,6 +10578,17 @@ Value 1.0 + RenderTransparentWater + + Comment + Render water as transparent. Setting to false renders water as opaque with a simple texture applied. + Persist + 1 + Type + Boolean + Value + 1 + RenderTreeLODFactor Comment @@ -10007,6 +10699,17 @@ Value 1 + RenderPreferStreamDraw + + Comment + Use GL_STREAM_DRAW in place of GL_DYNAMIC_DRAW + Persist + 1 + Type + Boolean + Value + 0 + RenderVolumeLODFactor Comment @@ -10051,28 +10754,6 @@ Value 512 - RenderWaterReflections - - Comment - Reflect the environment in the water. - Persist - 1 - Type - Boolean - Value - 0 - - RenderWaterVoidCulling - - Comment - Cull void water objects when off-screen. - Persist - 1 - Type - Boolean - Value - 1 - RotateRight Comment diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl index b6cc7f771..431c7f8e1 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 void default_lighting(); diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl index 292dbfdab..9057560e6 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 attribute vec4 weight; //1 diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl index ee3410d73..7b36d03c3 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); mat4 getSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl b/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl index 4d93c1944..cc49fe9f7 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 void default_lighting(); diff --git a/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl b/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl index b3c988a92..af9c28a6e 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol); void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl index 201930041..0b9943479 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl index 12d8f9d2f..801a8e06d 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 mat4 getSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index 7c8d238d2..22cae7a34 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -4,18 +4,15 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable uniform sampler2D diffuseMap; -uniform sampler2DShadow shadowMap0; -uniform sampler2DShadow shadowMap1; -uniform sampler2DShadow shadowMap2; -uniform sampler2DShadow shadowMap3; -uniform sampler2D noiseMap; -uniform sampler2DRect positionMap; +uniform sampler2DRect depthMap; -uniform mat4 shadow_matrix[4]; +uniform mat4 shadow_matrix[6]; uniform vec4 shadow_clip; uniform vec2 screen_res; @@ -26,63 +23,45 @@ varying vec3 vary_ambient; varying vec3 vary_directional; varying vec3 vary_fragcoord; varying vec3 vary_position; +varying vec3 vary_pointlight_col; -uniform float alpha_soften; +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} void main() { vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; frag *= screen_res; - vec3 samp_pos = texture2DRect(positionMap, frag).xyz; - - float shadow = 1.0; vec4 pos = vec4(vary_position, 1.0); - if (pos.z > -shadow_clip.w) - { - if (pos.z < -shadow_clip.z) - { - vec4 lpos = shadow_matrix[3]*pos; - shadow = shadow2DProj(shadowMap3, lpos).x; - shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); - } - else if (pos.z < -shadow_clip.y) - { - vec4 lpos = shadow_matrix[2]*pos; - shadow = shadow2DProj(shadowMap2, lpos).x; - } - else if (pos.z < -shadow_clip.x) - { - vec4 lpos = shadow_matrix[1]*pos; - shadow = shadow2DProj(shadowMap1, lpos).x; - } - else - { - vec4 lpos = shadow_matrix[0]*pos; - shadow = shadow2DProj(shadowMap0, lpos).x; - } - } + vec4 diff= texture2D(diffuseMap, gl_TexCoord[0].xy); - vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, gl_Color.a); - vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * col; + vec4 col = vec4(vary_ambient + vary_directional.rgb, gl_Color.a); + vec4 color = diff * col; color.rgb = atmosLighting(color.rgb); color.rgb = scaleSoftClip(color.rgb); - /*if (samp_pos.z != 0.0) - { - float dist_factor = alpha_soften; - float a = gl_Color.a; - a *= a; - dist_factor *= 1.0/(1.0-a); - color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0); - }*/ - + color.rgb += diff.rgb * vary_pointlight_col.rgb; + //gl_FragColor = gl_Color; gl_FragColor = color; //gl_FragColor = vec4(1,0,1,1); + //gl_FragColor = vec4(1,0,1,1)*shadow; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index 9f130ee42..d1c678f30 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -5,11 +5,12 @@ * $License$ */ +#version 120 + vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); void calcAtmospherics(vec3 inPositionEye); float calcDirectionalLight(vec3 n, vec3 l); -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); vec3 atmosAmbient(vec3 light); vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -20,8 +21,37 @@ varying vec3 vary_ambient; varying vec3 vary_directional; varying vec3 vary_fragcoord; varying vec3 vary_position; +varying vec3 vary_light; +varying vec3 vary_pointlight_col; uniform float near_clip; +uniform float shadow_offset; +uniform float shadow_bias; + +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +{ + //get light vector + vec3 lv = lp.xyz-v; + + //get distance + float d = length(lv); + + //normalize light vector + lv *= 1.0/d; + + //distance attenuation + float dist2 = d*d/(la*la); + float da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 + + //angular attenuation + da *= calcDirectionalLight(n, lv); + + return da; +} void main() { @@ -32,32 +62,37 @@ void main() vec4 pos = (gl_ModelViewMatrix * gl_Vertex); vec3 norm = normalize(gl_NormalMatrix * gl_Normal); - vary_position = pos.xyz; + + float dp_directional_light = max(0.0, dot(norm, gl_LightSource[0].position.xyz)); + vary_position = pos.xyz + gl_LightSource[0].position.xyz * (1.0-dp_directional_light)*shadow_offset; calcAtmospherics(pos.xyz); //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); - + vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a); + + // Collect normal lights + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation, gl_LightSource[2].specular.a); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation, gl_LightSource[3].specular.a); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation, gl_LightSource[4].specular.a); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].quadraticAttenuation, gl_LightSource[5].specular.a); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].quadraticAttenuation, gl_LightSource[6].specular.a); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].quadraticAttenuation, gl_LightSource[7].specular.a); + + vary_pointlight_col = col.rgb*gl_Color.rgb; + + col.rgb = vec3(0,0,0); // Add windlight lights col.rgb = atmosAmbient(vec3(0.)); - col.rgb = scaleUpLight(col.rgb); - - // Collect normal lights (need to be divided by two, as we later multiply by 2) - col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); - col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); - col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); - col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation); - col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation); - col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation); - col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); - col.rgb = scaleDownLight(col.rgb); + + vary_light = gl_LightSource[0].position.xyz; vary_ambient = col.rgb*gl_Color.rgb; vary_directional.rgb = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); - col.rgb = min(col.rgb*gl_Color.rgb, 1.0); + col.rgb = col.rgb*gl_Color.rgb; gl_FrontColor = col; diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl index 6c94f5c5a..ff64a6b0c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl @@ -12,7 +12,7 @@ uniform sampler2DShadow shadowMap2; uniform sampler2DShadow shadowMap3; uniform sampler2D noiseMap; -uniform mat4 shadow_matrix[4]; +uniform mat4 shadow_matrix[6]; uniform vec4 shadow_clip; vec3 atmosLighting(vec3 light); diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl index c1988d3c7..7fc763fa0 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl @@ -4,13 +4,15 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); mat4 getSkinnedTransform(); void calcAtmospherics(vec3 inPositionEye); float calcDirectionalLight(vec3 n, vec3 l); -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight); vec3 atmosAmbient(vec3 light); vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -47,23 +49,22 @@ void main() calcAtmospherics(pos.xyz); //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); - vec4 col; - col.a = gl_Color.a; - - // Add windlight lights - col.rgb = atmosAmbient(vec3(0.)); - col.rgb = scaleUpLight(col.rgb); + + vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a); // Collect normal lights (need to be divided by two, as we later multiply by 2) - col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); - col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); - col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); - col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation); - col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation); - col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation); + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a); col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); col.rgb = scaleDownLight(col.rgb); + // Add windlight lights + col.rgb += atmosAmbient(vec3(0.)); + vary_ambient = col.rgb*gl_Color.rgb; vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index b5daef03e..e2a36719c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -4,11 +4,12 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; varying vec3 vary_normal; -varying vec4 vary_position; void main() { @@ -21,7 +22,7 @@ void main() gl_FragData[0] = vec4(diff.rgb, 0.0); gl_FragData[1] = vec4(0,0,0,0); - gl_FragData[2] = vec4(normalize(vary_normal), 0.0); - gl_FragData[3] = vary_position; + vec3 nvn = normalize(vary_normal); + gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl index 3f60d4a71..61574d0be 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl @@ -4,13 +4,15 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; void main() { - //gl_FragColor = vec4(1,1,1,gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy)); //This should not compile! - gl_FragColor = vec4(1,1,1,texture2D(diffuseMap, gl_TexCoord[0].xy).a * gl_Color.a); + //gl_FragColor = vec4(1,1,1,gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy).a); + gl_FragColor = vec4(1,1,1,1); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl index 14da6b1ad..49ddd2b19 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 mat4 getSkinnedTransform(); @@ -28,8 +30,7 @@ void main() norm = normalize(norm); pos = gl_ProjectionMatrix * pos; - //smash geometry against near clip plane - pos.z = max(pos.z, -1.0); + pos.z = max(pos.z, -pos.w+0.01); gl_Position = pos; gl_FrontColor = gl_Color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl index 12a7ff7f2..3465cef2b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl @@ -4,13 +4,14 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 mat4 getSkinnedTransform(); attribute vec4 weight; varying vec3 vary_normal; -varying vec4 vary_position; void main() { @@ -30,7 +31,6 @@ void main() norm.z = dot(trans[2].xyz, gl_Normal); norm = normalize(norm); - vary_position = pos; vary_normal = norm; gl_Position = gl_ProjectionMatrix * pos; diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index 3c6700a87..6e732fa54 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -4,45 +4,80 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable -uniform sampler2DRect positionMap; +uniform sampler2DRect depthMap; uniform sampler2DRect normalMap; uniform sampler2DRect lightMap; +uniform float dist_factor; uniform float blur_size; uniform vec2 delta; -uniform vec3 kern[32]; -uniform int kern_length; +uniform vec3 kern[4]; uniform float kern_scale; varying vec2 vary_fragcoord; +uniform mat4 inv_proj; +uniform vec2 screen_res; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + void main() { vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz; - vec3 pos = texture2DRect(positionMap, vary_fragcoord.xy).xyz; - vec2 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rg; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + vec3 pos = getPosition(vary_fragcoord.xy).xyz; + vec4 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rgba; vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy); - vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free' - vec2 col = defined_weight * ccol; + dlt /= max(-pos.z*dist_factor, 1.0); - for (int i = 1; i < kern_length; i++) + vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free' + vec4 col = defined_weight.xyxx * ccol; + + for (int i = 1; i < 4; i++) { vec2 tc = vary_fragcoord.xy + kern[i].z*dlt; - vec3 samppos = texture2DRect(positionMap, tc).xyz; + vec3 samppos = getPosition(tc).xyz; float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane if (d*d <= 0.003) { - col += texture2DRect(lightMap, tc).rg*kern[i].xy; + col += texture2DRect(lightMap, tc)*kern[i].xyxx; + defined_weight += kern[i].xy; + } + } + for (int i = 1; i < 4; i++) + { + vec2 tc = vary_fragcoord.xy - kern[i].z*dlt; + vec3 samppos = getPosition(tc).xyz; + float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane + if (d*d <= 0.003) + { + col += texture2DRect(lightMap, tc)*kern[i].xyxx; defined_weight += kern[i].xy; } } - col /= defined_weight; - gl_FragColor = vec4(col.r, col.g, 0.0, 1.0); + + col /= defined_weight.xyxx; + + gl_FragColor = col; } + diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl index b7f07e570..3f2d7d7b1 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 varying vec2 vary_fragcoord; uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl index a8712bc8c..7a423f394 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; uniform sampler2D bumpMap; @@ -11,19 +13,19 @@ uniform sampler2D bumpMap; varying vec3 vary_mat0; varying vec3 vary_mat1; varying vec3 vary_mat2; -varying vec4 vary_position; void main() { - vec3 col = texture2D(diffuseMap, gl_TexCoord[0].xy).rgb; + vec3 col = gl_Color.rgb * texture2D(diffuseMap, gl_TexCoord[0].xy).rgb; vec3 norm = texture2D(bumpMap, gl_TexCoord[0].xy).rgb * 2.0 - 1.0; vec3 tnorm = vec3(dot(norm,vary_mat0), - dot(norm,vary_mat1), - dot(norm,vary_mat2)); + dot(norm,vary_mat1), + dot(norm,vary_mat2)); - gl_FragData[0].rgb = gl_Color.rgb*col; - gl_FragData[1] = vec4(col*(gl_Color.a*1.5), gl_Color.a); - gl_FragData[2] = vec4(normalize(tnorm), 0.0); - gl_FragData[3] = vary_position; + gl_FragData[0] = vec4(col, 0.0); + gl_FragData[1] = gl_Color.aaaa; // spec + //gl_FragData[1] = vec4(vec3(gl_Color.a), gl_Color.a+(1.0-gl_Color.a)*gl_Color.a); // spec - from former class3 - maybe better, but not so well tested + vec3 nvn = normalize(tnorm); + gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl index ba180922c..c83f781e2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl @@ -4,11 +4,12 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 varying vec3 vary_mat0; varying vec3 vary_mat1; varying vec3 vary_mat2; -varying vec4 vary_position; void main() { @@ -16,8 +17,6 @@ void main() gl_Position = ftransform(); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - vary_position = gl_ModelViewMatrix * gl_Vertex; - vec3 n = normalize(gl_NormalMatrix * gl_Normal); vec3 b = normalize(gl_NormalMatrix * gl_MultiTexCoord2.xyz); vec3 t = cross(b, n); diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index f2ba2df69..451195f97 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -4,17 +4,19 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; varying vec3 vary_normal; -varying vec4 vary_position; void main() { - vec3 col = texture2D(diffuseMap, gl_TexCoord[0].xy).rgb; - gl_FragData[0] = vec4(gl_Color.rgb*col, 1.0); - gl_FragData[1] = vec4(col*(gl_Color.a*1.5), gl_Color.a); - gl_FragData[2] = vec4(normalize(vary_normal), 0.0); - gl_FragData[3] = vary_position; + vec3 col = gl_Color.rgb * texture2D(diffuseMap, gl_TexCoord[0].xy).rgb; + gl_FragData[0] = vec4(col, 0.0); + gl_FragData[1] = gl_Color.aaaa; // spec + //gl_FragData[1] = vec4(vec3(gl_Color.a), gl_Color.a+(1.0-gl_Color.a)*gl_Color.a); // spec - from former class3 - maybe better, but not so well tested + vec3 nvn = normalize(vary_normal); + gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl index 3413a7f9d..af0314a75 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl @@ -2,20 +2,19 @@ * @file diffuseV.glsl * * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $/LicenseInfo$ */ + +#version 120 varying vec3 vary_normal; -varying vec4 vary_position; void main() { //transform vertex - gl_Position = ftransform(); + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - vary_position = gl_ModelViewMatrix * gl_Vertex; - vary_normal = normalize(gl_NormalMatrix * gl_Normal); gl_FrontColor = gl_Color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index 2a811c589..342987739 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -1,21 +1,18 @@ /** * @file fullbrightF.glsl * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable uniform sampler2D diffuseMap; -uniform sampler2DShadow shadowMap0; -uniform sampler2DShadow shadowMap1; -uniform sampler2DShadow shadowMap2; -uniform sampler2DShadow shadowMap3; +uniform sampler2DRect depthMap; uniform sampler2D noiseMap; -uniform sampler2DRect positionMap; -uniform mat4 shadow_matrix[4]; uniform vec4 shadow_clip; uniform vec2 screen_res; @@ -28,14 +25,27 @@ varying vec4 vary_position; varying vec3 vary_normal; varying vec3 vary_fragcoord; -uniform float alpha_soften; +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} void main() { vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; frag *= screen_res; - vec3 samp_pos = texture2DRect(positionMap, frag).xyz; + vec3 samp_pos = getPosition(frag).xyz; float shadow = 1.0; vec4 pos = vary_position; @@ -46,15 +56,6 @@ void main() color.rgb = fullbrightScaleSoftClip(color.rgb); - if (samp_pos.z != 0.0) - { - float dist_factor = alpha_soften; - float a = gl_Color.a; - a *= a; - dist_factor *= 1.0/(1.0-a); - color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0); - } - //gl_FragColor = gl_Color; gl_FragColor = color; //gl_FragColor = vec4(1,0,1,1); diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl index 6381a1ced..94f653541 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 void calcAtmospherics(vec3 inPositionEye); @@ -12,12 +14,12 @@ vec3 atmosAffectDirectionalLight(float lightIntensity); vec3 scaleDownLight(vec3 light); vec3 scaleUpLight(vec3 light); -varying vec4 vary_position; varying vec3 vary_ambient; varying vec3 vary_directional; varying vec3 vary_normal; varying vec3 vary_fragcoord; uniform float near_clip; +varying vec4 vary_position; void main() { diff --git a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl new file mode 100644 index 000000000..75b555e8a --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl @@ -0,0 +1,168 @@ +/** + * @file giF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2D noiseMap; + +uniform sampler2D diffuseGIMap; +uniform sampler2D normalGIMap; +uniform sampler2D depthGIMap; + +uniform sampler2D lightFunc; + +// Inputs +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +uniform mat4 inv_proj; +uniform mat4 gi_mat; //gPipeline.mGIMatrix - eye space to sun space +uniform mat4 gi_mat_proj; //gPipeline.mGIMatrixProj - eye space to projected sun space +uniform mat4 gi_norm_mat; //gPipeline.mGINormalMatrix - eye space normal to sun space normal matrix +uniform mat4 gi_inv_proj; //gPipeline.mGIInvProj - projected sun space to sun space +uniform float gi_radius; +uniform float gi_intensity; +uniform int gi_samples; +uniform vec2 gi_kern[25]; +uniform vec2 gi_scale; +uniform vec3 gi_quad; +uniform vec3 gi_spec; +uniform float gi_direction_weight; +uniform float gi_light_offset; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +vec4 getGIPosition(vec2 gi_tc) +{ + float depth = texture2D(depthGIMap, gi_tc).a; + vec2 sc = gi_tc*2.0; + sc -= vec2(1.0, 1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = gi_inv_proj*ndc; + pos.xyz /= pos.w; + pos.w = 1.0; + return pos; +} + +vec3 giAmbient(vec3 pos, vec3 norm) +{ + vec4 gi_c = gi_mat_proj * vec4(pos, 1.0); + gi_c.xyz /= gi_c.w; + + vec4 gi_pos = gi_mat*vec4(pos,1.0); + vec3 gi_norm = (gi_norm_mat*vec4(norm,1.0)).xyz; + gi_norm = normalize(gi_norm); + + vec2 tcx = gi_norm.xy; + vec2 tcy = gi_norm.yx; + + vec4 eye_pos = gi_mat*vec4(0,0,0,1.0); + + vec3 eye_dir = normalize(gi_pos.xyz-eye_pos.xyz/eye_pos.w); + + //vec3 eye_dir = vec3(0,0,-1); + //eye_dir = (gi_norm_mat*vec4(eye_dir, 1.0)).xyz; + //eye_dir = normalize(eye_dir); + + //float round_x = gi_scale.x; + //float round_y = gi_scale.y; + + vec3 debug = texture2D(normalGIMap, gi_c.xy).rgb*0.5+0.5; + debug.xz = vec2(0.0,0.0); + //debug = fract(debug); + + float round_x = 1.0/64.0; + float round_y = 1.0/64.0; + + //gi_c.x = floor(gi_c.x/round_x+0.5)*round_x; + //gi_c.y = floor(gi_c.y/round_y+0.5)*round_y; + + float fda = 0.0; + vec3 fdiff = vec3(0,0,0); + + vec3 rcol = vec3(0,0,0); + + float fsa = 0.0; + + for (int i = -1; i < 2; i+=2 ) + { + for (int j = -1; j < 2; j+=2) + { + vec2 tc = vec2(i, j)*0.75; + vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0+tc*0.5).xyz; + //tc += gi_norm.xy*nz.z; + tc += nz.xy*2.0; + tc /= gi_samples; + tc += gi_c.xy; + + vec3 lnorm = -normalize(texture2D(normalGIMap, tc.xy).xyz*2.0-1.0); + vec3 lpos = getGIPosition(tc.xy).xyz; + + vec3 at = lpos-gi_pos.xyz; + float dist = dot(at,at); + float da = clamp(1.0/(gi_spec.x*dist), 0.0, 1.0); + + if (da > 0.0) + { + //add angular attenuation + vec3 ldir = at; + float ang_atten = clamp(dot(ldir, gi_norm), 0.0, 1.0); + + float ld = -dot(ldir, lnorm); + + if (ang_atten > 0.0 && ld < 0.0) + { + vec3 diff = texture2D(diffuseGIMap, tc.xy).xyz; + da = da*ang_atten; + fda += da; + fdiff += diff*da; + } + } + } + } + + fdiff /= max(gi_spec.y*fda, gi_quad.z); + fdiff = clamp(fdiff, vec3(0), vec3(1)); + + vec3 ret = fda*fdiff; + //ret = ret*ret*gi_quad.x+ret*gi_quad.y+gi_quad.z; + + //fda *= nz.z; + + //rcol.rgb *= gi_intensity; + //return rcol.rgb+vary_AmblitColor.rgb*0.25; + //return vec4(debug, 0.0); + //return vec4(fda*fdiff, 0.0); + return clamp(ret,vec3(0.0), vec3(1.0)); + //return debug.xyz; +} + +void main() +{ + vec2 pos_screen = vary_fragcoord.xy; + vec4 pos = getPosition(pos_screen); + vec3 norm = texture2DRect(normalMap, pos_screen).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + + gl_FragData[0].xyz = giAmbient(pos, norm); +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/giV.glsl b/indra/newview/app_settings/shaders/class1/deferred/giV.glsl new file mode 100644 index 000000000..8dc1410ea --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/giV.glsl @@ -0,0 +1,24 @@ +/** + * @file giV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; + vec4 tex = gl_MultiTexCoord0; + tex.w = 1.0; + + gl_FrontColor = gl_Color; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl index 4e3e635f1..6b3bfcf2a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl @@ -4,18 +4,17 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; uniform sampler2D normalMap; uniform sampler2D specularMap; -varying vec4 vary_position; - void main() { vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy); - gl_FragData[0] = vec4(col.rgb, col.a <= 0.5 ? 0.0 : 0.005); + gl_FragData[0] = vec4(col.rgb, col.a * 0.005); gl_FragData[1] = texture2D(specularMap, gl_TexCoord[0].xy); - gl_FragData[2] = vec4(texture2D(normalMap, gl_TexCoord[0].xy).xyz, vary_position.z); - gl_FragData[3] = vary_position; + gl_FragData[2] = vec4(texture2D(normalMap, gl_TexCoord[0].xy).xyz, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl index 9c5ae3154..d90c4478c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl @@ -4,8 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ - -varying vec4 vary_position; + +#version 120 void main() { @@ -13,7 +13,5 @@ void main() gl_Position = ftransform(); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - vary_position = gl_ModelViewMatrix * gl_Vertex; - gl_FrontColor = gl_Color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl new file mode 100644 index 000000000..78df54d5d --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl @@ -0,0 +1,17 @@ +/** + * @file luminanceF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +uniform sampler2DRect diffuseMap; + +varying vec2 vary_fragcoord; + +void main() +{ + gl_FragColor = texture2DRect(diffuseMap, vary_fragcoord.xy); +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl new file mode 100644 index 000000000..0c820bfc6 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl @@ -0,0 +1,23 @@ +/** + * @file giV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + + +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; + + gl_FrontColor = gl_Color; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index c8248b294..42f5f3dba 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -5,15 +5,18 @@ * $License$ */ +#version 120 + #extension GL_ARB_texture_rectangle : enable +uniform sampler2DRect depthMap; uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; -uniform sampler2DRect positionMap; uniform sampler2DRect normalMap; uniform samplerCube environmentMap; -uniform sampler2DRect lightMap; uniform sampler2D noiseMap; +uniform sampler2D lightFunc; + uniform vec3 env_mat[3]; uniform float sun_wash; @@ -23,24 +26,50 @@ uniform int light_count; uniform vec4 light[16]; uniform vec4 light_col[16]; -varying vec3 vary_fragcoord; +varying vec4 vary_fragcoord; uniform vec2 screen_res; +uniform float far_z; + +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + void main() { vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res; - vec3 pos = texture2DRect(positionMap, frag.xy).xyz; - vec3 norm = normalize(texture2DRect(normalMap, frag.xy).xyz); + vec3 pos = getPosition(frag.xy).xyz; + if (pos.z < far_z) + { + discard; + } + + vec3 norm = texture2DRect(normalMap, frag.xy).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + norm = normalize(norm); vec4 spec = texture2DRect(specularRect, frag.xy); vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb; float noise = texture2D(noiseMap, frag.xy/128.0).b; vec3 out_col = vec3(0,0,0); + vec3 npos = normalize(-pos); for (int i = 0; i < light_count; ++i) { vec3 lv = light[i].xyz-pos; float dist2 = dot(lv,lv); - if (dist2 > light[i].w) + dist2 /= light[i].w; + if (dist2 > 1.0) { continue; } @@ -55,30 +84,31 @@ void main() da = dot(norm, lv); float fa = light_col[i].a+1.0; - float dist_atten = clamp(1.0-(dist2-light[i].w*(1.0-fa))/(light[i].w*fa), 0.0, 1.0); + float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); dist_atten *= noise; float lit = da * dist_atten; vec3 col = light_col[i].rgb*lit*diff; + //vec3 col = vec3(dist2, light_col[i].a, lit); if (spec.a > 0.0) { - vec3 ref = reflect(normalize(pos), norm); - float sa = dot(ref,lv); - sa = max(sa, 0.0); - sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0); - sa *= noise; - col += da*sa*light_col[i].rgb*spec.rgb; + //vec3 ref = dot(pos+lv, norm); + + float sa = dot(normalize(lv+npos),norm); + + if (sa > 0.0) + { + sa = texture2D(lightFunc,vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0); + sa *= noise; + col += da*sa*light_col[i].rgb*spec.rgb; + } } out_col += col; } - //attenuate point light contribution by SSAO component - out_col *= texture2DRect(lightMap, frag.xy).g; - - if (dot(out_col, out_col) <= 0.0) { discard; diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl new file mode 100644 index 000000000..2e3e84dd1 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl @@ -0,0 +1,20 @@ +/** + * @file multiPointLightV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +varying vec4 vary_fragcoord; + +void main() +{ + //transform vertex + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = pos; + + gl_Position = pos; + gl_FrontColor = gl_Color; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl new file mode 100644 index 000000000..a9f03f761 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -0,0 +1,225 @@ +/** + * @file multiSpotLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +//class 1 -- no shadows + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform samplerCube environmentMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2D projectionMap; + +uniform mat4 proj_mat; //screen space to light space +uniform float proj_near; //near clip for projection +uniform vec3 proj_p; //plane projection is emitting from (in screen space) +uniform vec3 proj_n; +uniform float proj_focus; //distance from plane to begin blurring +uniform float proj_lod; //(number of mips in proj map) +uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambient_lod; +uniform float proj_ambiance; +uniform float near_clip; +uniform float far_clip; + +uniform vec3 proj_origin; //origin of projection to be used for angular attenuation +uniform float sun_wash; +uniform int proj_shadow_idx; +uniform float shadow_fade; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; + +vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) +{ + vec4 ret = texture2DLod(projectionMap, tc, lod); + + vec2 dist = tc-vec2(0.5); + + float det = max(1.0-lod/(proj_lod*0.5), 0.0); + + float d = dot(dist,dist); + + ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); + + return ret; +} + +vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod) +{ + vec4 ret = texture2DLod(projectionMap, tc, lod); + + vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); + + float det = min(lod/(proj_lod*0.5), 1.0); + + float d = min(dist.x, dist.y); + + float edge = 0.25*det; + + ret *= clamp(d/edge, 0.0, 1.0); + + return ret; +} + +vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod) +{ + vec4 ret = texture2DLod(projectionMap, tc, lod); + + vec2 dist = tc-vec2(0.5); + + float d = dot(dist,dist); + + ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0); + + return ret; +} + + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +void main() +{ + vec4 frag = vary_fragcoord; + frag.xyz /= frag.w; + frag.xyz = frag.xyz*0.5+0.5; + frag.xy *= screen_res; + + vec3 pos = getPosition(frag.xy).xyz; + vec3 lv = vary_light.xyz-pos.xyz; + float dist2 = dot(lv,lv); + dist2 /= vary_light.w; + if (dist2 > 1.0) + { + discard; + } + + vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; + + norm = normalize(norm); + float l_dist = -dot(lv, proj_n); + + vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); + if (proj_tc.z < 0.0) + { + discard; + } + + proj_tc.xyz /= proj_tc.w; + + float fa = gl_Color.a+1.0; + float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); + if (dist_atten <= 0.0) + { + discard; + } + + lv = proj_origin-pos.xyz; + lv = normalize(lv); + float da = dot(norm, lv); + + vec3 col = vec3(0,0,0); + + vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; + + float noise = texture2D(noiseMap, frag.xy/128.0).b; + if (proj_tc.z > 0.0 && + proj_tc.x < 1.0 && + proj_tc.y < 1.0 && + proj_tc.x > 0.0 && + proj_tc.y > 0.0) + { + float lit = 0.0; + float amb_da = proj_ambiance; + + if (da > 0.0) + { + float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); + float lod = diff * proj_lod; + + vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); + + vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; + + lit = da * dist_atten * noise; + + col = lcol*lit*diff_tex; + amb_da += (da*0.5)*proj_ambiance; + } + + //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); + vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); + + amb_da += (da*da*0.5+0.5)*proj_ambiance; + + amb_da *= dist_atten * noise; + + amb_da = min(amb_da, 1.0-lit); + + col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; + } + + + vec4 spec = texture2DRect(specularRect, frag.xy); + if (spec.a > 0.0) + { + vec3 ref = reflect(normalize(pos), norm); + + //project from point pos in direction ref to plane proj_p, proj_n + vec3 pdelta = proj_p-pos; + float ds = dot(ref, proj_n); + + if (ds < 0.0) + { + vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; + + vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); + + if (stc.z > 0.0) + { + stc.xy /= stc.w; + + float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); + + stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); + + if (stc.x < 1.0 && + stc.y < 1.0 && + stc.x > 0.0 && + stc.y > 0.0) + { + vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); + col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb; + } + } + } + } + + gl_FragColor.rgb = col; + gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index 68f376d69..22ed9dcd4 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -1,41 +1,64 @@ /** * @file pointLightF.glsl * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ */ + + #version 120 #extension GL_ARB_texture_rectangle : enable uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; -uniform sampler2DRect positionMap; uniform sampler2DRect normalMap; uniform samplerCube environmentMap; -uniform sampler2DRect lightMap; uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2DRect depthMap; uniform vec3 env_mat[3]; uniform float sun_wash; varying vec4 vary_light; -varying vec3 vary_fragcoord; +varying vec4 vary_fragcoord; uniform vec2 screen_res; +uniform mat4 inv_proj; +uniform vec4 viewport; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = (pos_screen.xy-viewport.xy)*2.0; + sc /= viewport.zw; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + void main() { - vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; - frag *= screen_res; - vec3 pos = texture2DRect(positionMap, frag).xyz; + vec4 frag = vary_fragcoord; + frag.xyz /= frag.w; + frag.xyz = frag.xyz*0.5+0.5; + frag.xy *= screen_res; + + vec3 pos = getPosition(frag.xy).xyz; vec3 lv = vary_light.xyz-pos; float dist2 = dot(lv,lv); - if (dist2 > vary_light.w) + dist2 /= vary_light.w; + if (dist2 > 1.0) { discard; } - vec3 norm = texture2DRect(normalMap, frag).xyz; + vec3 norm = texture2DRect(normalMap, frag.xy).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm float da = dot(norm, lv); if (da < 0.0) { @@ -46,35 +69,32 @@ void main() lv = normalize(lv); da = dot(norm, lv); - float noise = texture2D(noiseMap, frag/128.0).b; + float noise = texture2D(noiseMap, frag.xy/128.0).b; - vec3 col = texture2DRect(diffuseRect, frag).rgb; + vec3 col = texture2DRect(diffuseRect, frag.xy).rgb; float fa = gl_Color.a+1.0; - float dist_atten = clamp(1.0-(dist2-vary_light.w*(1.0-fa))/(vary_light.w*fa), 0.0, 1.0); + float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); float lit = da * dist_atten * noise; col = gl_Color.rgb*lit*col; - vec4 spec = texture2DRect(specularRect, frag); + vec4 spec = texture2DRect(specularRect, frag.xy); if (spec.a > 0.0) { - vec3 ref = reflect(normalize(pos), norm); - float sa = dot(ref,lv); - sa = max(sa, 0.0); - sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0); - sa *= noise; - col += da*sa*gl_Color.rgb*spec.rgb; + float sa = dot(normalize(lv-normalize(pos)),norm); + if (sa > 0.0) + { + sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0); + sa *= noise; + col += da*sa*gl_Color.rgb*spec.rgb; + } } - //attenuate point light contribution by SSAO component - col *= texture2DRect(lightMap, frag.xy).g; - if (dot(col, col) <= 0.0) { discard; } - gl_FragColor.rgb = col; gl_FragColor.a = 0.0; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl index a4edb8825..1a426dddf 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl @@ -5,8 +5,10 @@ * $License$ */ +#version 120 + varying vec4 vary_light; -varying vec3 vary_fragcoord; +varying vec4 vary_fragcoord; uniform vec2 screen_res; uniform float near_clip; @@ -14,10 +16,10 @@ uniform float near_clip; void main() { //transform vertex - gl_Position = ftransform(); + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); + vary_fragcoord = pos; vec4 tex = gl_MultiTexCoord0; tex.w = 1.0; diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl new file mode 100644 index 000000000..7e41b07f8 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl @@ -0,0 +1,59 @@ +/** + * @file postDeferredF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect localLightMap; +uniform sampler2DRect sunLightMap; +uniform sampler2DRect giLightMap; +uniform sampler2D luminanceMap; +uniform sampler2DRect lightMap; + +uniform vec3 lum_quad; +uniform float lum_lod; +uniform vec4 ambient; + +uniform vec3 gi_quad; + +uniform vec2 screen_res; +varying vec2 vary_fragcoord; + +void main() +{ + vec2 tc = vary_fragcoord.xy; + vec3 lum = texture2DLod(luminanceMap, tc/screen_res, lum_lod).rgb; + float luminance = lum.r; + luminance = luminance*lum_quad.y+lum_quad.z; + + vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); + + float ambocc = texture2DRect(lightMap, vary_fragcoord.xy).g; + + vec3 gi_col = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; + gi_col = gi_col*gi_col*gi_quad.x + gi_col*gi_quad.y+gi_quad.z*ambocc*ambient.rgb; + gi_col *= diff; + + vec4 sun_col = texture2DRect(sunLightMap, vary_fragcoord.xy); + + vec3 local_col = texture2DRect(localLightMap, vary_fragcoord.xy).rgb; + + + sun_col *= 1.0/min(luminance, 1.0); + gi_col *= 1.0/luminance; + + vec3 col = sun_col.rgb+gi_col+local_col; + + gl_FragColor.rgb = col.rgb; + col.rgb = max(col.rgb-vec3(1.0,1.0,1.0), vec3(0.0, 0.0, 0.0)); + + gl_FragColor.a = 0.0; // max(dot(col.rgb,col.rgb)*lum_quad.x, sun_col.a); + + //gl_FragColor.rgb = vec3(lum_lod); +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl new file mode 100644 index 000000000..ab48d08bb --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl @@ -0,0 +1,24 @@ +/** + * @file postDeferredF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2D bloomMap; + +uniform vec2 screen_res; +varying vec2 vary_fragcoord; + +void main() +{ + vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); + + vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res); + gl_FragColor = diff + bloom; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl new file mode 100644 index 000000000..12983baa9 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl @@ -0,0 +1,19 @@ +/** + * @file postDeferredV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl new file mode 100644 index 000000000..63b3c9f20 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl @@ -0,0 +1,82 @@ +/** + * @file postgiF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2DRect giLightMap; +uniform sampler2D noiseMap; + +uniform vec2 kern[32]; +uniform float dist_factor; +uniform float blur_size; +uniform vec2 delta; +uniform int kern_length; +uniform float kern_scale; +uniform vec3 blur_quad; + +varying vec2 vary_fragcoord; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +void main() +{ + vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + vec3 pos = getPosition(vary_fragcoord.xy).xyz; + + vec3 ccol = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; + vec2 dlt = kern_scale * delta/(1.0+norm.xy*norm.xy); + dlt /= max(-pos.z*dist_factor, 1.0); + float defined_weight = kern[0].x; + vec3 col = vec3(0.0); + + for (int i = 0; i < kern_length; i++) + { + vec2 tc = vary_fragcoord.xy + kern[i].y*dlt; + vec3 sampNorm = texture2DRect(normalMap, tc.xy).xyz; + sampNorm = vec3((sampNorm.xy-0.5)*2.0,sampNorm.z); // unpack norm + + float d = dot(norm.xyz, sampNorm); + + if (d > 0.8) + { + vec3 samppos = getPosition(tc.xy).xyz; + samppos -= pos; + if (dot(samppos,samppos) < -0.05*pos.z) + { + col += texture2DRect(giLightMap, tc).rgb*kern[i].x; + defined_weight += kern[i].x; + } + } + } + + col /= defined_weight; + + //col = ccol; + + col = col*col*blur_quad.x + col*blur_quad.y + blur_quad.z; + + gl_FragData[0].xyz = col; + + //gl_FragColor = ccol; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl new file mode 100644 index 000000000..ae57227fe --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl @@ -0,0 +1,19 @@ +/** + * @file postgiV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl index b3758c363..4d85bbf62 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl @@ -4,11 +4,16 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; +varying vec4 post_pos; void main() { gl_FragColor = vec4(1,1,1,texture2D(diffuseMap, gl_TexCoord[0].xy).a * gl_Color.a); + + gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl index aae1beeae..9baa39814 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl @@ -4,14 +4,20 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 + +varying vec4 post_pos; void main() { //transform vertex vec4 pos = gl_ModelViewProjectionMatrix*gl_Vertex; - //smash geometry against the near clip plane (great for ortho projections) - pos.z = max(pos.z, -1.0); - gl_Position = pos; + + post_pos = pos; + + gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; gl_FrontColor = gl_Color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index d5671a6ce..525df5822 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable @@ -11,10 +13,11 @@ uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; uniform sampler2DRect positionMap; uniform sampler2DRect normalMap; -uniform sampler2DRect depthMap; uniform sampler2DRect lightMap; +uniform sampler2DRect depthMap; uniform sampler2D noiseMap; uniform samplerCube environmentMap; +uniform sampler2D lightFunc; uniform float blur_size; uniform float blur_fidelity; @@ -38,8 +41,8 @@ uniform vec4 max_y; uniform vec4 glow; uniform float scene_light_strength; uniform vec3 env_mat[3]; -uniform mat4 shadow_matrix[3]; -uniform vec4 shadow_clip; +//uniform mat4 shadow_matrix[3]; +//uniform vec4 shadow_clip; uniform mat3 ssao_effect_mat; varying vec4 vary_light; @@ -52,6 +55,27 @@ vec3 vary_AmblitColor; vec3 vary_AdditiveColor; vec3 vary_AtmosAttenuation; +uniform mat4 inv_proj; +uniform vec2 screen_res; + +vec4 getPosition_d(vec2 pos_screen, float depth) +{ + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +vec4 getPosition(vec2 pos_screen) +{ //get position in screen space (world units) given window coordinate and depth map + float depth = texture2DRect(depthMap, pos_screen.xy).a; + return getPosition_d(pos_screen, depth); +} + vec3 getPositionEye() { return vary_PositionEye; @@ -235,45 +259,87 @@ vec3 scaleSoftClip(vec3 light) void main() { vec2 tc = vary_fragcoord.xy; - vec3 pos = texture2DRect(positionMap, tc).xyz; + float depth = texture2DRect(depthMap, tc.xy).a; + vec3 pos = getPosition_d(tc, depth).xyz; vec3 norm = texture2DRect(normalMap, tc).xyz; - vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + //vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz; float da = max(dot(norm.xyz, vary_light.xyz), 0.0); - vec4 diffuse = vec4(texture2DRect(diffuseRect, tc).rgb, 1.0); + vec4 diffuse = texture2DRect(diffuseRect, tc); vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; - float scol = scol_ambocc.r; + float scol = max(scol_ambocc.r, diffuse.a); float ambocc = scol_ambocc.g; calcAtmospherics(pos.xyz, ambocc); vec3 col = atmosAmbient(vec3(0)); - col += atmosAffectDirectionalLight(min(da, scol)); + col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a)); col *= diffuse.rgb; - if (spec.a > 0.2) + if (spec.a > 0.0) // specular reflection { - vec3 ref = reflect(pos.xyz, norm.xyz); - vec3 rc; - rc.x = dot(ref, env_mat[0]); - rc.y = dot(ref, env_mat[1]); - rc.z = dot(ref, env_mat[2]); - - vec3 refcol = textureCube(environmentMap, rc).rgb; - col.rgb += refcol * spec.rgb; + // the old infinite-sky shiny reflection + // + vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); + float sa = dot(refnormpersp, vary_light.xyz); + vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a; + + /* + // screen-space cheap fakey reflection map + // + vec3 refnorm = normalize(reflect(vec3(0,0,-1), norm.xyz)); + depth -= 0.5; // unbias depth + // first figure out where we'll make our 2D guess from + vec2 ref2d = (0.25 * screen_res.y) * (refnorm.xy) * abs(refnorm.z) / depth; + // Offset the guess source a little according to a trivial + // checkerboard dither function and spec.a. + // This is meant to be similar to sampling a blurred version + // of the diffuse map. LOD would be better in that regard. + // The goal of the blur is to soften reflections in surfaces + // with low shinyness, and also to disguise our lameness. + float checkerboard = floor(mod(tc.x+tc.y, 2.0)); // 0.0, 1.0 + float checkoffset = (3.0 + (7.0*(1.0-spec.a)))*(checkerboard-0.5); + ref2d += vec2(checkoffset, checkoffset); + ref2d += tc.xy; // use as offset from destination + // Get attributes from the 2D guess point. + // We average two samples of diffuse (not of anything else) per + // pixel to try to reduce aliasing some more. + vec3 refcol = 0.5 * (texture2DRect(diffuseRect, ref2d + vec2(0.0, -checkoffset)).rgb + + texture2DRect(diffuseRect, ref2d + vec2(-checkoffset, 0.0)).rgb); + float refdepth = texture2DRect(depthMap, ref2d).a; + vec3 refpos = getPosition_d(ref2d, refdepth).xyz; + vec3 refn = texture2DRect(normalMap, ref2d).rgb; + refn = normalize(vec3((refn.xy-0.5)*2.0,refn.z)); // unpack norm + // figure out how appropriate our guess actually was + float refapprop = max(0.0, dot(-refnorm, normalize(pos - refpos))); + // darken reflections from points which face away from the reflected ray - our guess was a back-face + //refapprop *= step(dot(refnorm, refn), 0.0); + refapprop = min(refapprop, max(0.0, -dot(refnorm, refn))); // more conservative variant + // get appropriate light strength for guess-point. + // reflect light direction to increase the illusion that + // these are reflections. + vec3 reflight = reflect(lightnorm.xyz, norm.xyz); + float reflit = max(dot(refn, reflight.xyz), 0.0); + // apply sun color to guess-point, dampen according to inappropriateness of guess + float refmod = min(refapprop, reflit); + vec3 refprod = vary_SunlitColor * refcol.rgb * refmod; + vec3 ssshiny = (refprod * spec.a); + ssshiny *= 0.3; // dampen it even more + */ + vec3 ssshiny = vec3(0,0,0); + + // add the two types of shiny together + col += (ssshiny + dumbshiny) * spec.rgb; } col = atmosLighting(col); col = scaleSoftClip(col); - + gl_FragColor.rgb = col; gl_FragColor.a = 0.0; - //gl_FragColor.rg = scol_ambocc.rg; - //gl_FragColor.rgb = norm.rgb*0.5+0.5; - //gl_FragColor.rgb = vec3(ambocc); - //gl_FragColor.rgb = vec3(scol); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl index ad8af4780..3bc94e70d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl new file mode 100644 index 000000000..29fac46bf --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -0,0 +1,167 @@ +/** + * @file spotLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform samplerCube environmentMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2D projectionMap; + +uniform mat4 proj_mat; //screen space to light space +uniform float proj_near; //near clip for projection +uniform vec3 proj_p; //plane projection is emitting from (in screen space) +uniform vec3 proj_n; +uniform float proj_focus; //distance from plane to begin blurring +uniform float proj_lod; //(number of mips in proj map) +uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambiance; +uniform float near_clip; +uniform float far_clip; + +uniform vec3 proj_origin; //origin of projection to be used for angular attenuation +uniform float sun_wash; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +void main() +{ + vec4 frag = vary_fragcoord; + frag.xyz /= frag.w; + frag.xyz = frag.xyz*0.5+0.5; + frag.xy *= screen_res; + + vec3 pos = getPosition(frag.xy).xyz; + vec3 lv = vary_light.xyz-pos.xyz; + float dist2 = dot(lv,lv); + dist2 /= vary_light.w; + if (dist2 > 1.0) + { + discard; + } + + vec3 norm = texture2DRect(normalMap, frag.xy).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + + norm = normalize(norm); + float l_dist = -dot(lv, proj_n); + + vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); + if (proj_tc.z < 0.0) + { + discard; + } + + proj_tc.xyz /= proj_tc.w; + + float fa = gl_Color.a+1.0; + float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + + lv = proj_origin-pos.xyz; + lv = normalize(lv); + float da = dot(norm, lv); + + vec3 col = vec3(0,0,0); + + vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; + + float noise = texture2D(noiseMap, frag.xy/128.0).b; + if (proj_tc.z > 0.0 && + proj_tc.x < 1.0 && + proj_tc.y < 1.0 && + proj_tc.x > 0.0 && + proj_tc.y > 0.0) + { + float lit = 0.0; + if (da > 0.0) + { + float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); + float lod = diff * proj_lod; + + vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod); + + vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; + + lit = da * dist_atten * noise; + + col = lcol*lit*diff_tex; + } + + float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); + float lod = diff * proj_lod; + vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod); + //float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0)); + float amb_da = proj_ambiance; + + amb_da += (da*da*0.5+0.5)*proj_ambiance; + + amb_da *= dist_atten * noise; + + amb_da = min(amb_da, 1.0-lit); + + col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; + } + + + vec4 spec = texture2DRect(specularRect, frag.xy); + if (spec.a > 0.0) + { + vec3 ref = reflect(normalize(pos), norm); + + //project from point pos in direction ref to plane proj_p, proj_n + vec3 pdelta = proj_p-pos; + float ds = dot(ref, proj_n); + + if (ds < 0.0) + { + vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; + + vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz; + + if (stc.z > 0.0) + { + stc.xy /= stc.z+proj_near; + + if (stc.x < 1.0 && + stc.y < 1.0 && + stc.x > 0.0 && + stc.y > 0.0) + { + vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); + col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb; + } + } + } + } + + gl_FragColor.rgb = col; + gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl index d43fe6ca9..5db627ab1 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl @@ -4,136 +4,14 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 + +//class 1, no shadow, no SSAO, should never be called #extension GL_ARB_texture_rectangle : enable -uniform sampler2DRect positionMap; -uniform sampler2DRect normalMap; -uniform sampler2DRect depthMap; -uniform sampler2DShadow shadowMap0; -uniform sampler2DShadow shadowMap1; -uniform sampler2DShadow shadowMap2; -uniform sampler2DShadow shadowMap3; -uniform sampler2D noiseMap; - -// Inputs -uniform mat4 shadow_matrix[4]; -uniform vec4 shadow_clip; -uniform float ssao_radius; -uniform float ssao_max_radius; -uniform float ssao_factor; -uniform float ssao_factor_inv; - -varying vec2 vary_fragcoord; -varying vec4 vary_light; - -//calculate decreases in ambient lighting when crowded out (SSAO) -float calcAmbientOcclusion(vec4 pos, vec3 norm) -{ - vec2 kern[8]; - // exponentially (^2) distant occlusion samples spread around origin - kern[0] = vec2(-1.0, 0.0) * 0.125*0.125; - kern[1] = vec2(1.0, 0.0) * 0.250*0.250; - kern[2] = vec2(0.0, 1.0) * 0.375*0.375; - kern[3] = vec2(0.0, -1.0) * 0.500*0.500; - kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625; - kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750; - kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875; - kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000; - - vec2 pos_screen = vary_fragcoord.xy; - vec3 pos_world = pos.xyz; - vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; - - float angle_hidden = 0.0; - int points = 0; - - float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); - - // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?) - for (int i = 0; i < 8; i++) - { - vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect); - vec3 samppos_world = texture2DRect(positionMap, samppos_screen).xyz; - - vec3 diff = pos_world - samppos_world; - float dist2 = dot(diff, diff); - - // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area - // --> solid angle shrinking by the square of distance - //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2 - //(k should vary inversely with # of samples, but this is taken care of later) - - //if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) // -0.05*norm to shift sample point back slightly for flat surfaces - // angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional. max of 1.0 (= ssao_factor_inv * ssao_factor) - angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); - - // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion" - points = points + int(diff.z > -1.0); - } - - angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); - - return 1.0 - (float(points != 0) * angle_hidden); -} - void main() { - vec2 pos_screen = vary_fragcoord.xy; - vec4 pos = vec4(texture2DRect(positionMap, pos_screen).xyz, 1.0); - vec3 norm = texture2DRect(normalMap, pos_screen).xyz; - - /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL - { - gl_FragColor = vec4(0.0); // doesn't matter - return; - }*/ - - float shadow = 1.0; - float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); - - if (dp_directional_light == 0.0) - { - // if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup - shadow = 0.0; - } - else if (pos.z > -shadow_clip.w) - { - if (pos.z < -shadow_clip.z) - { - vec4 lpos = shadow_matrix[3]*pos; - shadow = shadow2DProj(shadowMap3, lpos).x; - shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); - } - else if (pos.z < -shadow_clip.y) - { - vec4 lpos = shadow_matrix[2]*pos; - shadow = shadow2DProj(shadowMap2, lpos).x; - } - else if (pos.z < -shadow_clip.x) - { - vec4 lpos = shadow_matrix[1]*pos; - shadow = shadow2DProj(shadowMap1, lpos).x; - } - else - { - vec4 lpos = shadow_matrix[0]*pos; - shadow = shadow2DProj(shadowMap0, lpos).x; - } - - // take the most-shadowed value out of these two: - // * the blurred sun shadow in the light (shadow) map - // * an unblurred dot product between the sun and this norm - // the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting - shadow = min(shadow, dp_directional_light); - } - else - { - // more distant than the shadow map covers - just use directional shading as shadow - shadow = dp_directional_light; - } - - gl_FragColor[0] = shadow; - gl_FragColor[1] = calcAmbientOcclusion(pos, norm); - //gl_FragColor[2] is unused as of August 2008, may be used for debugging + gl_FragColor = vec4(0,0,0,0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl new file mode 100644 index 000000000..3c936251f --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -0,0 +1,124 @@ +/** + * @file sunLightSSAOF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +//class 1 -- no shadow, SSAO only + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2D noiseMap; + + +// Inputs +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform float ssao_radius; +uniform float ssao_max_radius; +uniform float ssao_factor; +uniform float ssao_factor_inv; + +varying vec2 vary_fragcoord; +varying vec4 vary_light; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +uniform float shadow_bias; +uniform float shadow_offset; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +//calculate decreases in ambient lighting when crowded out (SSAO) +float calcAmbientOcclusion(vec4 pos, vec3 norm) +{ + float ret = 1.0; + + float dist = dot(pos.xyz,pos.xyz); + + if (dist < 64.0*64.0) + { + vec2 kern[8]; + // exponentially (^2) distant occlusion samples spread around origin + kern[0] = vec2(-1.0, 0.0) * 0.125*0.125; + kern[1] = vec2(1.0, 0.0) * 0.250*0.250; + kern[2] = vec2(0.0, 1.0) * 0.375*0.375; + kern[3] = vec2(0.0, -1.0) * 0.500*0.500; + kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625; + kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750; + kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875; + kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000; + + vec2 pos_screen = vary_fragcoord.xy; + vec3 pos_world = pos.xyz; + vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; + + float angle_hidden = 0.0; + int points = 0; + + float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); + + // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?) + for (int i = 0; i < 8; i++) + { + vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect); + vec3 samppos_world = getPosition(samppos_screen).xyz; + + vec3 diff = pos_world - samppos_world; + float dist2 = dot(diff, diff); + + // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area + // --> solid angle shrinking by the square of distance + //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2 + //(k should vary inversely with # of samples, but this is taken care of later) + + //if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) // -0.05*norm to shift sample point back slightly for flat surfaces + // angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional. max of 1.0 (= ssao_factor_inv * ssao_factor) + angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); + + // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion" + points = points + int(diff.z > -1.0); + } + + angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); + + ret = (1.0 - (float(points != 0) * angle_hidden)); + ret += max((dist-32.0*32.0)/(32.0*32.0), 0.0); + } + + return min(ret, 1.0); +} + +void main() +{ + vec2 pos_screen = vary_fragcoord.xy; + + //try doing an unproject here + + vec4 pos = getPosition(pos_screen); + + vec3 norm = texture2DRect(normalMap, pos_screen).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + + gl_FragColor[0] = 1.0; + gl_FragColor[1] = calcAmbientOcclusion(pos, norm); + gl_FragColor[2] = 1.0; + gl_FragColor[3] = 1.0; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl index 5081485c4..9aef0a6bb 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 varying vec4 vary_light; varying vec2 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl index 211b2e039..0a3fae592 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D detail_0; uniform sampler2D detail_1; @@ -12,7 +14,6 @@ uniform sampler2D detail_3; uniform sampler2D alpha_ramp; varying vec3 vary_normal; -varying vec4 vary_position; void main() { @@ -28,9 +29,9 @@ void main() float alphaFinal = texture2D(alpha_ramp, gl_TexCoord[1].zw).a; vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal ); - gl_FragData[0] = vec4(outColor.rgb, 1.0); + gl_FragData[0] = vec4(outColor.rgb, 0.0); gl_FragData[1] = vec4(outColor.rgb*0.2, 0.2); - gl_FragData[2] = vec4(normalize(vary_normal), 0.0); - gl_FragData[3] = vary_position; + vec3 nvn = normalize(vary_normal); + gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl index e9d6dcabf..06507f456 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl @@ -4,9 +4,10 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 varying vec3 vary_normal; -varying vec4 vary_position; vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) { @@ -27,7 +28,6 @@ void main() //transform vertex gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_position = gl_ModelViewMatrix * gl_Vertex; vary_normal = normalize(gl_NormalMatrix * gl_Normal); // Transform and pass tex coords diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index ea70eabf5..123520190 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -4,17 +4,18 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; varying vec3 vary_normal; -varying vec4 vary_position; void main() { vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy); gl_FragData[0] = vec4(gl_Color.rgb*col.rgb, col.a <= 0.5 ? 0.0 : 0.005); gl_FragData[1] = vec4(0,0,0,0); - gl_FragData[2] = vec4(normalize(vary_normal), 0.0); - gl_FragData[3] = vary_position; + vec3 nvn = normalize(vary_normal); + gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl index 9131d7c2b..d1500393b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl @@ -4,9 +4,10 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 varying vec3 vary_normal; -varying vec4 vary_position; void main() { @@ -14,8 +15,6 @@ void main() gl_Position = ftransform(); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - vary_position = gl_ModelViewMatrix * gl_Vertex; - vary_normal = normalize(gl_NormalMatrix * gl_Normal); gl_FrontColor = gl_Color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 83959101e..606e44eae 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -4,21 +4,24 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable + vec3 scaleSoftClip(vec3 inColor); vec3 atmosTransport(vec3 inColor); uniform sampler2D bumpMap; uniform sampler2D screenTex; uniform sampler2D refTex; -uniform sampler2DShadow shadowMap0; -uniform sampler2DShadow shadowMap1; -uniform sampler2DShadow shadowMap2; -uniform sampler2DShadow shadowMap3; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; uniform sampler2D noiseMap; -uniform mat4 shadow_matrix[4]; +uniform mat4 shadow_matrix[6]; uniform vec4 shadow_clip; uniform float sunAngle; @@ -33,9 +36,9 @@ uniform vec3 normScale; uniform float fresnelScale; uniform float fresnelOffset; uniform float blurMultiplier; +uniform vec2 screen_res; uniform mat4 norm_mat; //region space to screen space - //bigWave is (refCoord.w, view.w); varying vec4 refCoord; varying vec4 littleWave; @@ -114,51 +117,27 @@ void main() vec4 fb = texture2D(screenTex, distort2); //mix with reflection - // Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug + // Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999); float shadow = 1.0; vec4 pos = vary_position; //vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; - -// if (pos.z > -shadow_clip.w) -// { - vec4 spos = pos; - -/* if (pos.z < -shadow_clip.z) - { - vec4 lpos = (shadow_matrix[3]*spos); - shadow = shadow2DProj(shadowMap3, lpos).x; - } - else if (pos.z < -shadow_clip.y) - { - vec4 lpos = (shadow_matrix[2]*spos); - shadow = shadow2DProj(shadowMap2, lpos).x; - } - else if (pos.z < -shadow_clip.x) - { - vec4 lpos = (shadow_matrix[1]*spos); - shadow = shadow2DProj(shadowMap1, lpos).x; - } - else - { - vec4 lpos = (shadow_matrix[0]*spos); - shadow = shadow2DProj(shadowMap0, lpos).x; - } - }*/ + vec4 spos = pos; + + //spec *= shadow; + //color.rgb += spec * specular; -// spec *= shadow; -// color.rgb += spec * specular; - -// color.rgb = atmosTransport(color.rgb); -// color.rgb = scaleSoftClip(color.rgb); -// color.a = spec * sunAngle2; + //color.rgb = atmosTransport(color.rgb); + //color.rgb = scaleSoftClip(color.rgb); + //color.a = spec * sunAngle2; -// gl_FragColor = color; + //wavef.z *= 0.1f; + //wavef = normalize(wavef); vec3 screenspacewavef = (norm_mat*vec4(wavef, 1.0)).xyz; gl_FragData[0] = vec4(color.rgb, 0.5); // diffuse gl_FragData[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec - gl_FragData[2] = vec4(screenspacewavef, 0.0); // normalxyz, displace + gl_FragData[2] = vec4(screenspacewavef.xy*0.5+0.5, screenspacewavef.z, screenspacewavef.z*0.5); // normalxyz, displace } diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl index b45e5c530..2be8d4286 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl index 5d7af2c13..61e5ba0d9 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl index 61dfd2f12..fd5300a1f 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl @@ -5,6 +5,7 @@ * $License$ */ +#version 120 void main() { diff --git a/indra/newview/app_settings/shaders/class1/effects/glowV.glsl b/indra/newview/app_settings/shaders/class1/effects/glowV.glsl index 13ce7c785..744eff196 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowV.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform vec2 glowDelta; diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl index 2278c6916..51b3cdd99 100644 --- a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D detail0; uniform sampler2D detail1; diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl index 112d66981..fc4cb14c4 100644 --- a/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl index e2f68e882..7db3133f6 100644 --- a/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 // this class1 shader is just a copy of terrainF diff --git a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl index f1740a4dc..6f65b0179 100644 --- a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; uniform sampler2D bumpMap; diff --git a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl index 7e1788678..89217484f 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 vec3 scaleSoftClip(vec3 inColor); vec3 atmosTransport(vec3 inColor); diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl index 7ee41998e..94296e0ba 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 vec4 applyWaterFog(vec4 color) { diff --git a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl index 48ac87ef0..4dae985a7 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl index 328c41652..5e4c123a8 100644 --- a/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl index a9ea6e856..4c052a35a 100644 --- a/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 void main() { diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl index 071489bca..65a87b5f6 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl index b12cca912..7bfea160e 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl index bc795a751..32f52fbe8 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl new file mode 100644 index 000000000..1bdaccf9b --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl @@ -0,0 +1,17 @@ +/** + * @file lightFullbrightShinyWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + + +#version 120 + +uniform sampler2D diffuseMap; +uniform samplerCube environmentMap; + +void fullbright_shiny_lighting_water() +{ + gl_FragColor = texture2D(diffuseMap, gl_TexCoord[0].xy); +} diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl index b13088fb1..89afa0ab2 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl @@ -5,6 +5,8 @@ * $License$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl index bbbd9f3df..4ce4bc0cb 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 float calcDirectionalLight(vec3 n, vec3 l) { diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl index 3e8fdfb3e..a437d075a 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 float calcDirectionalLight(vec3 n, vec3 l) @@ -12,7 +14,8 @@ float calcDirectionalLight(vec3 n, vec3 l) return a; } -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la) + +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight) { //get light vector vec3 lv = lp.xyz-v; @@ -26,6 +29,10 @@ float calcPointLight(vec3 v, vec3 n, vec4 lp, float la) //distance attenuation float da = clamp(1.0/(la * d), 0.0, 1.0); + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 + //angular attenuation da *= calcDirectionalLight(n, lv); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl index 89785c45c..28dabb494 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl index 7ac3c359b..7985c17e0 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl index 853212923..fddba5cff 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 float calcDirectionalLight(vec3 n, vec3 l); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl index 8c2813a85..8c01f3dd5 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 float calcDirectionalLight(vec3 n, vec3 l); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl index 81dff1ef3..97506312a 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl index 218585fb8..4146b8121 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl @@ -4,6 +4,9 @@ * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 + float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da); vec3 atmosAmbient(vec3 light); vec3 atmosAffectDirectionalLight(float lightIntensity); diff --git a/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl index e5361033e..df198eafc 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 float calcDirectionalLight(vec3 n, vec3 l); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl index 1b0ffb911..028b51cbb 100755 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 void fullbright_lighting(); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl index 936c228b4..b474ac55d 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 void fullbright_shiny_lighting(); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl index ba2aa024d..75b841a5f 100755 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl new file mode 100644 index 000000000..5daf66fb3 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl @@ -0,0 +1,15 @@ +/** + * @file fullbrightShinyWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +void fullbright_shiny_lighting_water(); + +void main() +{ + fullbright_shiny_lighting_water(); +} diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl index e64ccb844..690a5d996 100755 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl index fd855aa91..8645dc3a8 100755 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 void fullbright_lighting_water(); diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl index bdb0b05f9..1d83116b1 100644 --- a/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 void shiny_lighting(); diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl index c2e1ddf73..3fb9a298c 100644 --- a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl index 0a2a5f624..1fc497e49 100755 --- a/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 void shiny_lighting_water(); diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl index 7dacca4fe..97f5741b3 100644 --- a/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 void default_lighting(); diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl index 78b96b302..03167cfc6 100644 --- a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl index e066b3d02..e133dcf41 100755 --- a/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 void default_lighting_water(); diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl index 248c32201..4c20ad758 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 vec3 atmosLighting(vec3 light) { diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl index c2c39e2e1..e83180714 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 vec3 atmosAmbient(vec3 light) { diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl index 551b64340..c5adb50e4 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 void setPositionEye(vec3 v); diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl index c001a4070..f8405b4d5 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 varying vec3 vary_PositionEye; diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl index 1b263b085..658767427 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 varying vec3 vary_PositionEye; diff --git a/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl index c1ffda159..76a072000 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform vec4 gamma; diff --git a/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl index 7097906fd..77ed3ea2b 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 vec3 atmosTransport(vec3 light) { diff --git a/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl b/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl index 3dd62d2d1..4af024f17 100644 --- a/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl +++ b/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol); void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl new file mode 100644 index 000000000..f234f57d4 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -0,0 +1,125 @@ +/** + * @file alphaF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2D diffuseMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2DRect depthMap; + +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform vec2 screen_res; +uniform vec2 shadow_res; + +vec3 atmosLighting(vec3 light); +vec3 scaleSoftClip(vec3 light); + +varying vec3 vary_ambient; +varying vec3 vary_directional; +varying vec3 vary_fragcoord; +varying vec3 vary_position; +varying vec3 vary_pointlight_col; + +uniform float shadow_bias; + +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos.xyz /= pos.w; + pos.w = 1.0; + return pos; +} + +float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +{ + stc.xyz /= stc.w; + stc.z += shadow_bias; + + float cs = shadow2DRect(shadowMap, stc.xyz).x; + float shadow = cs; + + shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, scl, 0.0)).x, cs); + shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, -scl, 0.0)).x, cs); + shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, scl, 0.0)).x, cs); + shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, -scl, 0.0)).x, cs); + + return shadow/5.0; +} + + +void main() +{ + vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; + frag *= screen_res; + + float shadow = 1.0; + vec4 pos = vec4(vary_position, 1.0); + + vec4 spos = pos; + + if (spos.z > -shadow_clip.w) + { + vec4 lpos; + + if (spos.z < -shadow_clip.z) + { + lpos = shadow_matrix[3]*spos; + lpos.xy *= shadow_res; + shadow = pcfShadow(shadowMap3, lpos, 1.5); + shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); + } + else if (spos.z < -shadow_clip.y) + { + lpos = shadow_matrix[2]*spos; + lpos.xy *= shadow_res; + shadow = pcfShadow(shadowMap2, lpos, 1.5); + } + else if (spos.z < -shadow_clip.x) + { + lpos = shadow_matrix[1]*spos; + lpos.xy *= shadow_res; + shadow = pcfShadow(shadowMap1, lpos, 1.5); + } + else + { + lpos = shadow_matrix[0]*spos; + lpos.xy *= shadow_res; + shadow = pcfShadow(shadowMap0, lpos, 1.5); + } + } + + vec4 diff= texture2D(diffuseMap, gl_TexCoord[0].xy); + + vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, gl_Color.a); + vec4 color = diff * col; + + color.rgb = atmosLighting(color.rgb); + + color.rgb = scaleSoftClip(color.rgb); + + color.rgb += diff.rgb * vary_pointlight_col.rgb; + + //gl_FragColor = gl_Color; + gl_FragColor = color; + //gl_FragColor.r = 0.0; + //gl_FragColor = vec4(1,0,1,1)*shadow; + +} + diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl new file mode 100644 index 000000000..7024025f7 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl @@ -0,0 +1,100 @@ +/** + * @file alphaV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); +void calcAtmospherics(vec3 inPositionEye); + +float calcDirectionalLight(vec3 n, vec3 l); + +vec3 atmosAmbient(vec3 light); +vec3 atmosAffectDirectionalLight(float lightIntensity); +vec3 scaleDownLight(vec3 light); +vec3 scaleUpLight(vec3 light); + +varying vec3 vary_ambient; +varying vec3 vary_directional; +varying vec3 vary_fragcoord; +varying vec3 vary_position; +varying vec3 vary_pointlight_col; + +uniform float near_clip; +uniform float shadow_offset; +uniform float shadow_bias; + +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +{ + //get light vector + vec3 lv = lp.xyz-v; + + //get distance + float d = length(lv); + + //normalize light vector + lv *= 1.0/d; + + //distance attenuation + float dist2 = d*d/(la*la); + float da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 + + //angular attenuation + da *= calcDirectionalLight(n, lv); + + return da; +} + +void main() +{ + //transform vertex + gl_Position = ftransform(); + + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + + vec4 pos = (gl_ModelViewMatrix * gl_Vertex); + vec3 norm = normalize(gl_NormalMatrix * gl_Normal); + + float dp_directional_light = max(0.0, dot(norm, gl_LightSource[0].position.xyz)); + vary_position = pos.xyz + gl_LightSource[0].position.xyz * (1.0-dp_directional_light)*shadow_offset; + + calcAtmospherics(pos.xyz); + + //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); + vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a); + + // Collect normal lights + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation, gl_LightSource[2].specular.a); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation ,gl_LightSource[3].specular.a); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation, gl_LightSource[4].specular.a); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].quadraticAttenuation, gl_LightSource[5].specular.a); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].quadraticAttenuation, gl_LightSource[6].specular.a); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].quadraticAttenuation, gl_LightSource[7].specular.a); + + vary_pointlight_col = col.rgb*gl_Color.rgb; + + col.rgb = vec3(0,0,0); + + // Add windlight lights + col.rgb = atmosAmbient(vec3(0.)); + + vary_ambient = col.rgb*gl_Color.rgb; + vary_directional.rgb = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); + + col.rgb = col.rgb*gl_Color.rgb; + + gl_FrontColor = col; + + gl_FogFragCoord = pos.z; + + pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); + +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl new file mode 100644 index 000000000..5ecbbd2c4 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl @@ -0,0 +1,98 @@ +/** + * @file avatarAlphaF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2D diffuseMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2D noiseMap; + +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform vec2 screen_res; +uniform vec2 shadow_res; + +vec3 atmosLighting(vec3 light); +vec3 scaleSoftClip(vec3 light); + +varying vec3 vary_ambient; +varying vec3 vary_directional; +varying vec3 vary_position; +varying vec3 vary_normal; + +uniform float shadow_bias; + +float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +{ + stc.xyz /= stc.w; + stc.z += shadow_bias; + + float cs = shadow2DRect(shadowMap, stc.xyz).x; + float shadow = cs; + + shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, scl, 0.0)).x, cs); + shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, -scl, 0.0)).x, cs); + shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, scl, 0.0)).x, cs); + shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, -scl, 0.0)).x, cs); + + return shadow/5.0; +} + +void main() +{ + float shadow = 1.0; + vec4 pos = vec4(vary_position, 1.0); + vec3 norm = normalize(vary_normal); + + //vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; + + vec4 spos = pos; + + if (spos.z > -shadow_clip.w) + { + vec4 lpos; + + if (spos.z < -shadow_clip.z) + { + lpos = shadow_matrix[3]*spos; + lpos.xy *= shadow_res; + shadow = pcfShadow(shadowMap3, lpos, 1.5); + shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); + } + else if (spos.z < -shadow_clip.y) + { + lpos = shadow_matrix[2]*spos; + lpos.xy *= shadow_res; + shadow = pcfShadow(shadowMap2, lpos, 1.5); + } + else if (spos.z < -shadow_clip.x) + { + lpos = shadow_matrix[1]*spos; + lpos.xy *= shadow_res; + shadow = pcfShadow(shadowMap1, lpos, 1.5); + } + else + { + lpos = shadow_matrix[0]*spos; + lpos.xy *= shadow_res; + shadow = pcfShadow(shadowMap0, lpos, 1.5); + } + } + + + vec4 col = vec4(vary_ambient + vary_directional*shadow, gl_Color.a); + vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * col; + + color.rgb = atmosLighting(color.rgb); + + color.rgb = scaleSoftClip(color.rgb); + + gl_FragColor = color; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl new file mode 100644 index 000000000..43a554b47 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl @@ -0,0 +1,85 @@ +/** + * @file avatarAlphaV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); +mat4 getSkinnedTransform(); +void calcAtmospherics(vec3 inPositionEye); + +float calcDirectionalLight(vec3 n, vec3 l); +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight); + +vec3 atmosAmbient(vec3 light); +vec3 atmosAffectDirectionalLight(float lightIntensity); +vec3 scaleDownLight(vec3 light); +vec3 scaleUpLight(vec3 light); + +varying vec3 vary_position; +varying vec3 vary_ambient; +varying vec3 vary_directional; +varying vec3 vary_normal; + +uniform float near_clip; +uniform float shadow_offset; +uniform float shadow_bias; + +void main() +{ + gl_TexCoord[0] = gl_MultiTexCoord0; + + vec4 pos; + vec3 norm; + + mat4 trans = getSkinnedTransform(); + pos.x = dot(trans[0], gl_Vertex); + pos.y = dot(trans[1], gl_Vertex); + pos.z = dot(trans[2], gl_Vertex); + pos.w = 1.0; + + norm.x = dot(trans[0].xyz, gl_Normal); + norm.y = dot(trans[1].xyz, gl_Normal); + norm.z = dot(trans[2].xyz, gl_Normal); + norm = normalize(norm); + + gl_Position = gl_ProjectionMatrix * pos; + + float dp_directional_light = max(0.0, dot(norm, gl_LightSource[0].position.xyz)); + vary_position = pos.xyz + gl_LightSource[0].position.xyz * (1.0-dp_directional_light)*shadow_offset; + vary_normal = norm; + + calcAtmospherics(pos.xyz); + + //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); + + vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a); + + // Collect normal lights (need to be divided by two, as we later multiply by 2) + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a); + col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); + col.rgb = scaleDownLight(col.rgb); + + // Add windlight lights + col.rgb += atmosAmbient(vec3(0.)); + + vary_ambient = col.rgb*gl_Color.rgb; + vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); + + col.rgb = min(col.rgb*gl_Color.rgb, 1.0); + + gl_FrontColor = col; + + gl_FogFragCoord = pos.z; + +} + + diff --git a/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl new file mode 100644 index 000000000..258a9b7c4 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl @@ -0,0 +1,81 @@ +/** + * @file blurLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2DRect lightMap; + +uniform float dist_factor; +uniform float blur_size; +uniform vec2 delta; +uniform vec3 kern[4]; +uniform float kern_scale; + +varying vec2 vary_fragcoord; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +void main() +{ + vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + vec3 pos = getPosition(vary_fragcoord.xy).xyz; + vec4 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rgba; + + vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy); + + dlt /= max(-pos.z*dist_factor, 1.0); + + vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free' + vec4 col = defined_weight.xyxx * ccol; + + for (int i = 1; i < 4; i++) + { + vec2 tc = vary_fragcoord.xy + kern[i].z*dlt; + vec3 samppos = getPosition(tc).xyz; + float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane + if (d*d <= 0.003) + { + col += texture2DRect(lightMap, tc)*kern[i].xyxx; + defined_weight += kern[i].xy; + } + } + for (int i = 1; i < 4; i++) + { + vec2 tc = vary_fragcoord.xy - kern[i].z*dlt; + vec3 samppos = getPosition(tc).xyz; + float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane + if (d*d <= 0.003) + { + col += texture2DRect(lightMap, tc)*kern[i].xyxx; + defined_weight += kern[i].xy; + } + } + + + + col /= defined_weight.xyxx; + + gl_FragColor = col; +} + diff --git a/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl b/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl new file mode 100644 index 000000000..b1b3f55f0 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl @@ -0,0 +1,17 @@ +/** + * @file blurLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl b/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl new file mode 100644 index 000000000..3155f3f92 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl @@ -0,0 +1,63 @@ +/** + * @file edgeF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; + +varying vec2 vary_fragcoord; + +uniform float depth_cutoff; +uniform float norm_cutoff; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +float getDepth(vec2 pos_screen) +{ + float z = texture2DRect(depthMap, pos_screen.xy).a; + z = z*2.0-1.0; + vec4 ndc = vec4(0.0, 0.0, z, 1.0); + vec4 p = inv_proj*ndc; + return p.z/p.w; +} + +void main() +{ + vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + float depth = getDepth(vary_fragcoord.xy); + + vec2 tc = vary_fragcoord.xy; + + float sc = 0.75; + + vec2 de; + de.x = (depth-getDepth(tc+vec2(sc, sc))) + (depth-getDepth(tc+vec2(-sc, -sc))); + de.y = (depth-getDepth(tc+vec2(-sc, sc))) + (depth-getDepth(tc+vec2(sc, -sc))); + de /= depth; + de *= de; + de = step(depth_cutoff, de); + + vec2 ne; + vec3 nexnorm = texture2DRect(normalMap, tc+vec2(-sc,-sc)).rgb; + nexnorm = vec3((nexnorm.xy-0.5)*2.0,nexnorm.z); // unpack norm + ne.x = dot(nexnorm, norm); + vec3 neynorm = texture2DRect(normalMap, tc+vec2(sc,sc)).rgb; + neynorm = vec3((neynorm.xy-0.5)*2.0,neynorm.z); // unpack norm + ne.y = dot(neynorm, norm); + + ne = 1.0-ne; + + ne = step(norm_cutoff, ne); + + gl_FragColor.a = dot(de,de)+dot(ne,ne); + //gl_FragColor.a = dot(de,de); +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/edgeV.glsl b/indra/newview/app_settings/shaders/class2/deferred/edgeV.glsl new file mode 100644 index 000000000..b3413c301 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/edgeV.glsl @@ -0,0 +1,19 @@ +/** + * @file edgeV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl new file mode 100644 index 000000000..d6cd984eb --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -0,0 +1,236 @@ +/** + * @file multiSpotLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform samplerCube environmentMap; +uniform sampler2DRect lightMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2D projectionMap; + +uniform mat4 proj_mat; //screen space to light space +uniform float proj_near; //near clip for projection +uniform vec3 proj_p; //plane projection is emitting from (in screen space) +uniform vec3 proj_n; +uniform float proj_focus; //distance from plane to begin blurring +uniform float proj_lod; //(number of mips in proj map) +uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambient_lod; +uniform float proj_ambiance; +uniform float near_clip; +uniform float far_clip; + +uniform vec3 proj_origin; //origin of projection to be used for angular attenuation +uniform float sun_wash; +uniform int proj_shadow_idx; +uniform float shadow_fade; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; + +vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) +{ + vec4 ret = texture2DLod(projectionMap, tc, lod); + + vec2 dist = tc-vec2(0.5); + + float det = max(1.0-lod/(proj_lod*0.5), 0.0); + + float d = dot(dist,dist); + + ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); + + return ret; +} + +vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod) +{ + vec4 ret = texture2DLod(projectionMap, tc, lod); + + vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); + + float det = min(lod/(proj_lod*0.5), 1.0); + + float d = min(dist.x, dist.y); + + float edge = 0.25*det; + + ret *= clamp(d/edge, 0.0, 1.0); + + return ret; +} + +vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod) +{ + vec4 ret = texture2DLod(projectionMap, tc, lod); + + vec2 dist = tc-vec2(0.5); + + float d = dot(dist,dist); + + ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0); + + return ret; +} + + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +void main() +{ + vec4 frag = vary_fragcoord; + frag.xyz /= frag.w; + frag.xyz = frag.xyz*0.5+0.5; + frag.xy *= screen_res; + + vec3 pos = getPosition(frag.xy).xyz; + vec3 lv = vary_light.xyz-pos.xyz; + float dist2 = dot(lv,lv); + dist2 /= vary_light.w; + if (dist2 > 1.0) + { + discard; + } + + float shadow = 1.0; + + if (proj_shadow_idx >= 0) + { + vec4 shd = texture2DRect(lightMap, frag.xy); + float sh[2]; + sh[0] = shd.b; + sh[1] = shd.a; + shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); + } + + vec3 norm = texture2DRect(normalMap, frag.xy).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + + norm = normalize(norm); + float l_dist = -dot(lv, proj_n); + + vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); + if (proj_tc.z < 0.0) + { + discard; + } + + proj_tc.xyz /= proj_tc.w; + + float fa = gl_Color.a+1.0; + float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); + if (dist_atten <= 0.0) + { + discard; + } + + lv = proj_origin-pos.xyz; + lv = normalize(lv); + float da = dot(norm, lv); + + vec3 col = vec3(0,0,0); + + vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; + + float noise = texture2D(noiseMap, frag.xy/128.0).b; + if (proj_tc.z > 0.0 && + proj_tc.x < 1.0 && + proj_tc.y < 1.0 && + proj_tc.x > 0.0 && + proj_tc.y > 0.0) + { + float lit = 0.0; + float amb_da = proj_ambiance; + + if (da > 0.0) + { + float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); + float lod = diff * proj_lod; + + vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod); + + vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; + + lit = da * dist_atten * noise; + + col = lcol*lit*diff_tex*shadow; + amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; + } + + //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); + vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod); + + amb_da += (da*da*0.5+0.5)*proj_ambiance; + + amb_da *= dist_atten * noise; + + amb_da = min(amb_da, 1.0-lit); + + col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; + } + + + vec4 spec = texture2DRect(specularRect, frag.xy); + if (spec.a > 0.0) + { + vec3 ref = reflect(normalize(pos), norm); + + //project from point pos in direction ref to plane proj_p, proj_n + vec3 pdelta = proj_p-pos; + float ds = dot(ref, proj_n); + + if (ds < 0.0) + { + vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; + + vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); + + if (stc.z > 0.0) + { + stc.xy /= stc.w; + + float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); + + stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); + + if (stc.x < 1.0 && + stc.y < 1.0 && + stc.x > 0.0 && + stc.y > 0.0) + { + vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); + col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow; + } + } + } + } + + gl_FragColor.rgb = col; + gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl new file mode 100644 index 000000000..757e3e7aa --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl @@ -0,0 +1,59 @@ +/** + * @file postDeferredF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect localLightMap; +uniform sampler2DRect sunLightMap; +uniform sampler2DRect giLightMap; +uniform sampler2D luminanceMap; +uniform sampler2DRect lightMap; + +uniform vec3 gi_lum_quad; +uniform vec3 sun_lum_quad; +uniform vec3 lum_quad; +uniform float lum_lod; +uniform vec4 ambient; + +uniform vec3 gi_quad; + +uniform vec2 screen_res; +varying vec2 vary_fragcoord; + +void main() +{ + vec2 tc = vary_fragcoord.xy; + vec3 lcol = texture2DLod(luminanceMap, tc/screen_res, lum_lod).rgb; + + float lum = sqrt(lcol.r)*lum_quad.x+lcol.r*lcol.r*lum_quad.y+lcol.r*lum_quad.z; + + vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); + + float ambocc = texture2DRect(lightMap, vary_fragcoord.xy).g; + + vec3 gi_col = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; + gi_col = gi_col*gi_col*gi_quad.x + gi_col*gi_quad.y+gi_quad.z*ambocc*ambient.rgb; + gi_col *= diff; + + vec4 sun_col = texture2DRect(sunLightMap, vary_fragcoord.xy); + + vec3 local_col = texture2DRect(localLightMap, vary_fragcoord.xy).rgb; + + + float sun_lum = 1.0-lum; + sun_lum = sun_lum*sun_lum*sun_lum_quad.x + sun_lum*sun_lum_quad.y+sun_lum_quad.z; + + float gi_lum = lum; + gi_lum = gi_lum*gi_lum*gi_lum_quad.x+gi_lum*gi_lum_quad.y+gi_lum_quad.z; + gi_col *= 1.0/gi_lum; + + vec3 col = sun_col.rgb*(1.0+max(sun_lum,0.0))+gi_col+local_col; + + gl_FragColor.rgb = col.rgb; + gl_FragColor.a = max(sun_lum*min(sun_col.r+sun_col.g+sun_col.b, 1.0), sun_col.a); + + //gl_FragColor.rgb = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl b/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl new file mode 100644 index 000000000..0ec81dcb0 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl @@ -0,0 +1,17 @@ +/** + * @file postDeferredV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl new file mode 100644 index 000000000..0160e8427 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -0,0 +1,346 @@ +/** + * @file softenLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect normalMap; +uniform sampler2DRect lightMap; +uniform sampler2DRect depthMap; +uniform sampler2D noiseMap; +uniform samplerCube environmentMap; +uniform sampler2D lightFunc; +uniform vec3 gi_quad; + +uniform float blur_size; +uniform float blur_fidelity; + +// Inputs +uniform vec4 morphFactor; +uniform vec3 camPosLocal; +//uniform vec4 camPosWorld; +uniform vec4 gamma; +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +uniform vec4 blue_density; +uniform vec4 haze_horizon; +uniform vec4 haze_density; +uniform vec4 cloud_shadow; +uniform vec4 density_multiplier; +uniform vec4 distance_multiplier; +uniform vec4 max_y; +uniform vec4 glow; +uniform float scene_light_strength; +uniform vec3 env_mat[3]; +uniform vec4 shadow_clip; +uniform mat3 ssao_effect_mat; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +varying vec4 vary_light; +varying vec2 vary_fragcoord; + +vec3 vary_PositionEye; + +vec3 vary_SunlitColor; +vec3 vary_AmblitColor; +vec3 vary_AdditiveColor; +vec3 vary_AtmosAttenuation; + +vec4 getPosition_d(vec2 pos_screen, float depth) +{ + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +vec4 getPosition(vec2 pos_screen) +{ //get position in screen space (world units) given window coordinate and depth map + float depth = texture2DRect(depthMap, pos_screen.xy).a; + return getPosition_d(pos_screen, depth); +} + +vec3 getPositionEye() +{ + return vary_PositionEye; +} +vec3 getSunlitColor() +{ + return vary_SunlitColor; +} +vec3 getAmblitColor() +{ + return vary_AmblitColor; +} +vec3 getAdditiveColor() +{ + return vary_AdditiveColor; +} +vec3 getAtmosAttenuation() +{ + return vary_AtmosAttenuation; +} + + +void setPositionEye(vec3 v) +{ + vary_PositionEye = v; +} + +void setSunlitColor(vec3 v) +{ + vary_SunlitColor = v; +} + +void setAmblitColor(vec3 v) +{ + vary_AmblitColor = v; +} + +void setAdditiveColor(vec3 v) +{ + vary_AdditiveColor = v; +} + +void setAtmosAttenuation(vec3 v) +{ + vary_AtmosAttenuation = v; +} + +void calcAtmospherics(vec3 inPositionEye, float ambFactor) { + + vec3 P = inPositionEye; + setPositionEye(P); + + //(TERRAIN) limit altitude + if (P.y > max_y.x) P *= (max_y.x / P.y); + if (P.y < -max_y.x) P *= (-max_y.x / P.y); + + vec3 tmpLightnorm = lightnorm.xyz; + + vec3 Pn = normalize(P); + float Plen = length(P); + + vec4 temp1 = vec4(0); + vec3 temp2 = vec3(0); + vec4 blue_weight; + vec4 haze_weight; + vec4 sunlight = sunlight_color; + vec4 light_atten; + + //sunlight attenuation effect (hue and brightness) due to atmosphere + //this is used later for sunlight modulation at various altitudes + light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x); + //I had thought blue_density and haze_density should have equal weighting, + //but attenuation due to haze_density tends to seem too strong + + temp1 = blue_density + vec4(haze_density.r); + blue_weight = blue_density / temp1; + haze_weight = vec4(haze_density.r) / temp1; + + //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) + temp2.y = max(0.0, tmpLightnorm.y); + temp2.y = 1. / temp2.y; + sunlight *= exp( - light_atten * temp2.y); + + // main atmospheric scattering line integral + temp2.z = Plen * density_multiplier.x; + + // Transparency (-> temp1) + // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati + // compiler gets confused. + temp1 = exp(-temp1 * temp2.z * distance_multiplier.x); + + //final atmosphere attenuation factor + setAtmosAttenuation(temp1.rgb); + + //compute haze glow + //(can use temp2.x as temp because we haven't used it yet) + temp2.x = dot(Pn, tmpLightnorm.xyz); + temp2.x = 1. - temp2.x; + //temp2.x is 0 at the sun and increases away from sun + temp2.x = max(temp2.x, .03); //was glow.y + //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) + temp2.x *= glow.x; + //higher glow.x gives dimmer glow (because next step is 1 / "angle") + temp2.x = pow(temp2.x, glow.z); + //glow.z should be negative, so we're doing a sort of (1 / "angle") function + + //add "minimum anti-solar illumination" + temp2.x += .25; + + //increase ambient when there are more clouds + vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5; + + /* decrease value and saturation (that in HSV, not HSL) for occluded areas + * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html + * // The following line of code performs the equivalent of: + * float ambAlpha = tmpAmbient.a; + * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis + * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); + * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); + */ + tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); + + //haze color + setAdditiveColor( + vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient) + + (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x + + tmpAmbient))); + + //brightness of surface both sunlight and ambient + setSunlitColor(vec3(sunlight * .5)); + setAmblitColor(vec3(tmpAmbient * .25)); + setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); +} + +vec3 atmosLighting(vec3 light) +{ + light *= getAtmosAttenuation().r; + light += getAdditiveColor(); + return (2.0 * light); +} + +vec3 atmosTransport(vec3 light) { + light *= getAtmosAttenuation().r; + light += getAdditiveColor() * 2.0; + return light; +} +vec3 atmosGetDiffuseSunlightColor() +{ + return getSunlitColor(); +} + +vec3 scaleDownLight(vec3 light) +{ + return (light / scene_light_strength ); +} + +vec3 scaleUpLight(vec3 light) +{ + return (light * scene_light_strength); +} + +vec3 atmosAmbient(vec3 light) +{ + return getAmblitColor() + light / 2.0; +} + +vec3 atmosAffectDirectionalLight(float lightIntensity) +{ + return getSunlitColor() * lightIntensity; +} + +vec3 scaleSoftClip(vec3 light) +{ + //soft clip effect: + light = 1. - clamp(light, vec3(0.), vec3(1.)); + light = 1. - pow(light, gamma.xxx); + + return light; +} + +void main() +{ + vec2 tc = vary_fragcoord.xy; + float depth = texture2DRect(depthMap, tc.xy).a; + vec3 pos = getPosition_d(tc, depth).xyz; + vec3 norm = texture2DRect(normalMap, tc).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + //vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz; + + float da = max(dot(norm.xyz, vary_light.xyz), 0.0); + + vec4 diffuse = texture2DRect(diffuseRect, tc); + vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); + + vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; + float scol = max(scol_ambocc.r, diffuse.a); + float ambocc = scol_ambocc.g; + + calcAtmospherics(pos.xyz, ambocc); + + vec3 col = atmosAmbient(vec3(0)); + col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a)); + + col *= diffuse.rgb; + + if (spec.a > 0.0) // specular reflection + { + // the old infinite-sky shiny reflection + // + vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); + float sa = dot(refnormpersp, vary_light.xyz); + vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a; + + /* + // screen-space cheap fakey reflection map + // + vec3 refnorm = normalize(reflect(vec3(0,0,-1), norm.xyz)); + depth -= 0.5; // unbias depth + // first figure out where we'll make our 2D guess from + vec2 ref2d = (0.25 * screen_res.y) * (refnorm.xy) * abs(refnorm.z) / depth; + // Offset the guess source a little according to a trivial + // checkerboard dither function and spec.a. + // This is meant to be similar to sampling a blurred version + // of the diffuse map. LOD would be better in that regard. + // The goal of the blur is to soften reflections in surfaces + // with low shinyness, and also to disguise our lameness. + float checkerboard = floor(mod(tc.x+tc.y, 2.0)); // 0.0, 1.0 + float checkoffset = (3.0 + (7.0*(1.0-spec.a)))*(checkerboard-0.5); + ref2d += vec2(checkoffset, checkoffset); + ref2d += tc.xy; // use as offset from destination + // Get attributes from the 2D guess point. + // We average two samples of diffuse (not of anything else) per + // pixel to try to reduce aliasing some more. + vec3 refcol = 0.5 * (texture2DRect(diffuseRect, ref2d + vec2(0.0, -checkoffset)).rgb + + texture2DRect(diffuseRect, ref2d + vec2(-checkoffset, 0.0)).rgb); + float refdepth = texture2DRect(depthMap, ref2d).a; + vec3 refpos = getPosition_d(ref2d, refdepth).xyz; + float refshad = texture2DRect(lightMap, ref2d).r; + vec3 refn = texture2DRect(normalMap, ref2d).rgb; + refn = vec3((refn.xy-0.5)*2.0,refn.z); // unpack norm + refn = normalize(refn); + // figure out how appropriate our guess actually was + float refapprop = max(0.0, dot(-refnorm, normalize(pos - refpos))); + // darken reflections from points which face away from the reflected ray - our guess was a back-face + //refapprop *= step(dot(refnorm, refn), 0.0); + refapprop = min(refapprop, max(0.0, -dot(refnorm, refn))); // more conservative variant + // get appropriate light strength for guess-point + // reflect light direction to increase the illusion that + // these are reflections. + vec3 reflight = reflect(lightnorm.xyz, norm.xyz); + float reflit = min(max(dot(refn, reflight.xyz), 0.0), refshad); + // apply sun color to guess-point, dampen according to inappropriateness of guess + float refmod = min(refapprop, reflit); + vec3 refprod = vary_SunlitColor * refcol.rgb * refmod; + vec3 ssshiny = (refprod * spec.a); + ssshiny *= 0.3; // dampen it even more + */ + vec3 ssshiny = vec3(0,0,0); + + // add the two types of shiny together + col += (ssshiny + dumbshiny) * spec.rgb; + } + + col = atmosLighting(col); + col = scaleSoftClip(col); + + gl_FragColor.rgb = col; + gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl new file mode 100644 index 000000000..8f0bcca76 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl @@ -0,0 +1,26 @@ +/** + * @file softenLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +uniform vec2 screen_res; + +varying vec4 vary_light; +varying vec2 vary_fragcoord; +void main() +{ + //transform vertex + gl_Position = ftransform(); + + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; + + vec4 tex = gl_MultiTexCoord0; + tex.w = 1.0; + + vary_light = gl_MultiTexCoord0; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl new file mode 100644 index 000000000..d0e242c2d --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -0,0 +1,185 @@ +/** + * @file spotLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform samplerCube environmentMap; +uniform sampler2DRect lightMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2D projectionMap; + +uniform mat4 proj_mat; //screen space to light space +uniform float proj_near; //near clip for projection +uniform vec3 proj_p; //plane projection is emitting from (in screen space) +uniform vec3 proj_n; +uniform float proj_focus; //distance from plane to begin blurring +uniform float proj_lod; //(number of mips in proj map) +uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambiance; +uniform float near_clip; +uniform float far_clip; + +uniform vec3 proj_origin; //origin of projection to be used for angular attenuation +uniform float sun_wash; +uniform int proj_shadow_idx; +uniform float shadow_fade; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +void main() +{ + vec4 frag = vary_fragcoord; + frag.xyz /= frag.w; + frag.xyz = frag.xyz*0.5+0.5; + frag.xy *= screen_res; + + float shadow = 1.0; + + if (proj_shadow_idx >= 0) + { + vec4 shd = texture2DRect(lightMap, frag.xy); + float sh[2]; + sh[0] = shd.b; + sh[1] = shd.a; + shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); + } + + vec3 pos = getPosition(frag.xy).xyz; + vec3 lv = vary_light.xyz-pos.xyz; + float dist2 = dot(lv,lv); + dist2 /= vary_light.w; + if (dist2 > 1.0) + { + discard; + } + + vec3 norm = texture2DRect(normalMap, frag.xy).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + + norm = normalize(norm); + float l_dist = -dot(lv, proj_n); + + vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); + if (proj_tc.z < 0.0) + { + discard; + } + + proj_tc.xyz /= proj_tc.w; + + float fa = gl_Color.a+1.0; + float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + + lv = proj_origin-pos.xyz; + lv = normalize(lv); + float da = dot(norm, lv); + + vec3 col = vec3(0,0,0); + + vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; + + float noise = texture2D(noiseMap, frag.xy/128.0).b; + if (proj_tc.z > 0.0 && + proj_tc.x < 1.0 && + proj_tc.y < 1.0 && + proj_tc.x > 0.0 && + proj_tc.y > 0.0) + { + float lit = 0.0; + if (da > 0.0) + { + float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); + float lod = diff * proj_lod; + + vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod); + + vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; + + lit = da * dist_atten * noise; + + col = lcol*lit*diff_tex*shadow; + } + + float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); + float lod = diff * proj_lod; + vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod); + //float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0)); + float amb_da = proj_ambiance; + if (da > 0.0) + { + amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; + } + + amb_da += (da*da*0.5+0.5)*proj_ambiance; + + amb_da *= dist_atten * noise; + + amb_da = min(amb_da, 1.0-lit); + + col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; + } + + + vec4 spec = texture2DRect(specularRect, frag.xy); + if (spec.a > 0.0) + { + vec3 ref = reflect(normalize(pos), norm); + + //project from point pos in direction ref to plane proj_p, proj_n + vec3 pdelta = proj_p-pos; + float ds = dot(ref, proj_n); + + if (ds < 0.0) + { + vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; + + vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz; + + if (stc.z > 0.0) + { + stc.xy /= stc.z+proj_near; + + if (stc.x < 1.0 && + stc.y < 1.0 && + stc.x > 0.0 && + stc.y > 0.0) + { + vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); + col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow; + } + } + } + } + + gl_FragColor.rgb = col; + gl_FragColor.a = 0.0; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl new file mode 100644 index 000000000..4369b3b34 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -0,0 +1,196 @@ +/** + * @file sunLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +//class 2, shadows, no SSAO + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2DShadow shadowMap4; +uniform sampler2DShadow shadowMap5; + + +// Inputs +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform float ssao_radius; +uniform float ssao_max_radius; +uniform float ssao_factor; +uniform float ssao_factor_inv; + +varying vec2 vary_fragcoord; +varying vec4 vary_light; + +uniform mat4 inv_proj; +uniform vec2 screen_res; +uniform vec2 shadow_res; +uniform vec2 proj_shadow_res; + +uniform float shadow_bias; +uniform float shadow_offset; + +uniform float spot_shadow_bias; +uniform float spot_shadow_offset; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +{ + stc.xyz /= stc.w; + stc.z += shadow_bias*scl; + + float cs = shadow2DRect(shadowMap, stc.xyz).x; + float shadow = cs; + + shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, 1.5, 0.0)).x, cs); + shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, -1.5, 0.0)).x, cs); + shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, 1.5, 0.0)).x, cs); + shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, -1.5, 0.0)).x, cs); + + return shadow/5.0; + + //return shadow; +} + +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl) +{ + stc.xyz /= stc.w; + stc.z += spot_shadow_bias*scl; + + float cs = shadow2D(shadowMap, stc.xyz).x; + float shadow = cs; + + vec2 off = 1.5/proj_shadow_res; + + shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs); + shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs); + shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs); + shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs); + + return shadow/5.0; + + //return shadow; +} + +void main() +{ + vec2 pos_screen = vary_fragcoord.xy; + + //try doing an unproject here + + vec4 pos = getPosition(pos_screen); + + vec4 nmap4 = texture2DRect(normalMap, pos_screen); + nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm + float displace = nmap4.w; + vec3 norm = nmap4.xyz; + + /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL + { + gl_FragColor = vec4(0.0); // doesn't matter + return; + }*/ + + float shadow = 1.0; + float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); + + vec3 shadow_pos = pos.xyz + displace*norm; + vec3 offset = vary_light.xyz * (1.0-dp_directional_light); + + vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0); + + if (spos.z > -shadow_clip.w) + { + if (dp_directional_light == 0.0) + { + // if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup + shadow = 0.0; + } + else + { + vec4 lpos; + + if (spos.z < -shadow_clip.z) + { + lpos = shadow_matrix[3]*spos; + lpos.xy *= shadow_res; + shadow = pcfShadow(shadowMap3, lpos, 0.25); + shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); + } + else if (spos.z < -shadow_clip.y) + { + lpos = shadow_matrix[2]*spos; + lpos.xy *= shadow_res; + shadow = pcfShadow(shadowMap2, lpos, 0.5); + } + else if (spos.z < -shadow_clip.x) + { + lpos = shadow_matrix[1]*spos; + lpos.xy *= shadow_res; + shadow = pcfShadow(shadowMap1, lpos, 0.75); + } + else + { + lpos = shadow_matrix[0]*spos; + lpos.xy *= shadow_res; + shadow = pcfShadow(shadowMap0, lpos, 1.0); + } + + // take the most-shadowed value out of these two: + // * the blurred sun shadow in the light (shadow) map + // * an unblurred dot product between the sun and this norm + // the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting + shadow = min(shadow, dp_directional_light); + + //lpos.xy /= lpos.w*32.0; + //if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1) + //{ + // shadow = 0.0; + //} + + } + } + else + { + // more distant than the shadow map covers + shadow = 1.0; + } + + gl_FragColor[0] = shadow; + gl_FragColor[1] = 1.0; + + spos = vec4(shadow_pos+norm*spot_shadow_offset, 1.0); + + //spotlight shadow 1 + vec4 lpos = shadow_matrix[4]*spos; + gl_FragColor[2] = pcfShadow(shadowMap4, lpos, 0.8); + + //spotlight shadow 2 + lpos = shadow_matrix[5]*spos; + gl_FragColor[3] = pcfShadow(shadowMap5, lpos, 0.8); + + //gl_FragColor.rgb = pos.xyz; + //gl_FragColor.b = shadow; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl new file mode 100644 index 000000000..c457d0a3e --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -0,0 +1,257 @@ +/** + * @file sunLightSSAOF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +//class 2 -- shadows and SSAO + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2DShadow shadowMap4; +uniform sampler2DShadow shadowMap5; +uniform sampler2D noiseMap; + +// Inputs +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform float ssao_radius; +uniform float ssao_max_radius; +uniform float ssao_factor; +uniform float ssao_factor_inv; + +varying vec2 vary_fragcoord; +varying vec4 vary_light; + +uniform mat4 inv_proj; +uniform vec2 screen_res; +uniform vec2 shadow_res; +uniform vec2 proj_shadow_res; + +uniform float shadow_bias; +uniform float shadow_offset; + +uniform float spot_shadow_bias; +uniform float spot_shadow_offset; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +//calculate decreases in ambient lighting when crowded out (SSAO) +float calcAmbientOcclusion(vec4 pos, vec3 norm) +{ + float ret = 1.0; + + float dist = dot(pos.xyz,pos.xyz); + + if (dist < 64.0*64.0) + { + vec2 kern[8]; + // exponentially (^2) distant occlusion samples spread around origin + kern[0] = vec2(-1.0, 0.0) * 0.125*0.125; + kern[1] = vec2(1.0, 0.0) * 0.250*0.250; + kern[2] = vec2(0.0, 1.0) * 0.375*0.375; + kern[3] = vec2(0.0, -1.0) * 0.500*0.500; + kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625; + kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750; + kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875; + kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000; + + vec2 pos_screen = vary_fragcoord.xy; + vec3 pos_world = pos.xyz; + vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; + + float angle_hidden = 0.0; + int points = 0; + + float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); + + // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?) + for (int i = 0; i < 8; i++) + { + vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect); + vec3 samppos_world = getPosition(samppos_screen).xyz; + + vec3 diff = pos_world - samppos_world; + float dist2 = dot(diff, diff); + + // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area + // --> solid angle shrinking by the square of distance + //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2 + //(k should vary inversely with # of samples, but this is taken care of later) + + //if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) // -0.05*norm to shift sample point back slightly for flat surfaces + // angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional. max of 1.0 (= ssao_factor_inv * ssao_factor) + angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); + + // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion" + points = points + int(diff.z > -1.0); + } + + angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); + + ret = (1.0 - (float(points != 0) * angle_hidden)); + ret += max((dist-32.0*32.0)/(32.0*32.0), 0.0); + } + + return min(ret, 1.0); +} + +float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +{ + stc.xyz /= stc.w; + stc.z += shadow_bias*scl; + + float cs = shadow2DRect(shadowMap, stc.xyz).x; + float shadow = cs; + + shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, 1.5, 0.0)).x, cs); + shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, -1.5, 0.0)).x, cs); + shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, 1.5, 0.0)).x, cs); + shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, -1.5, 0.0)).x, cs); + + return shadow/5.0; + + //return shadow; +} + +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl) +{ + stc.xyz /= stc.w; + stc.z += spot_shadow_bias*scl; + + float cs = shadow2D(shadowMap, stc.xyz).x; + float shadow = cs; + + vec2 off = 1.5/proj_shadow_res; + + shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs); + shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs); + shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs); + shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs); + + + return shadow/5.0; + + //return shadow; +} + +void main() +{ + vec2 pos_screen = vary_fragcoord.xy; + + //try doing an unproject here + + vec4 pos = getPosition(pos_screen); + + vec4 nmap4 = texture2DRect(normalMap, pos_screen); + nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm + float displace = nmap4.w; + vec3 norm = nmap4.xyz; + + /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL + { + gl_FragColor = vec4(0.0); // doesn't matter + return; + }*/ + + float shadow = 1.0; + float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); + + vec3 shadow_pos = pos.xyz + displace*norm; + vec3 offset = vary_light.xyz * (1.0-dp_directional_light); + + vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0); + + if (spos.z > -shadow_clip.w) + { + if (dp_directional_light == 0.0) + { + // if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup + shadow = 0.0; + } + else + { + vec4 lpos; + + if (spos.z < -shadow_clip.z) + { + lpos = shadow_matrix[3]*spos; + lpos.xy *= shadow_res; + shadow = pcfShadow(shadowMap3, lpos, 0.25); + shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); + } + else if (spos.z < -shadow_clip.y) + { + lpos = shadow_matrix[2]*spos; + lpos.xy *= shadow_res; + shadow = pcfShadow(shadowMap2, lpos, 0.5); + } + else if (spos.z < -shadow_clip.x) + { + lpos = shadow_matrix[1]*spos; + lpos.xy *= shadow_res; + shadow = pcfShadow(shadowMap1, lpos, 0.75); + } + else + { + lpos = shadow_matrix[0]*spos; + lpos.xy *= shadow_res; + shadow = pcfShadow(shadowMap0, lpos, 1.0); + } + + // take the most-shadowed value out of these two: + // * the blurred sun shadow in the light (shadow) map + // * an unblurred dot product between the sun and this norm + // the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting + shadow = min(shadow, dp_directional_light); + + //lpos.xy /= lpos.w*32.0; + //if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1) + //{ + // shadow = 0.0; + //} + + } + } + else + { + // more distant than the shadow map covers + shadow = 1.0; + } + + gl_FragColor[0] = shadow; + gl_FragColor[1] = calcAmbientOcclusion(pos, norm); + + spos.xyz = shadow_pos+offset*spot_shadow_offset; + + //spotlight shadow 1 + vec4 lpos = shadow_matrix[4]*spos; + gl_FragColor[2] = pcfShadow(shadowMap4, lpos, 0.8); + + //spotlight shadow 2 + lpos = shadow_matrix[5]*spos; + gl_FragColor[3] = pcfShadow(shadowMap5, lpos, 0.8); + + //gl_FragColor.rgb = pos.xyz; + //gl_FragColor.b = shadow; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl new file mode 100644 index 000000000..9beb513ad --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl @@ -0,0 +1,27 @@ +/** + * @file sunLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +varying vec4 vary_light; +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; + vec4 tex = gl_MultiTexCoord0; + tex.w = 1.0; + + vary_light = gl_MultiTexCoord0; + + gl_FrontColor = gl_Color; +} diff --git a/indra/newview/app_settings/shaders/class2/effects/blurF.glsl b/indra/newview/app_settings/shaders/class2/effects/blurF.glsl index 7edfebab2..43f37a80a 100644 --- a/indra/newview/app_settings/shaders/class2/effects/blurF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/blurF.glsl @@ -5,6 +5,7 @@ * $License$ */ +#version 120 #extension GL_ARB_texture_rectangle : enable uniform sampler2DRect RenderTexture; diff --git a/indra/newview/app_settings/shaders/class2/effects/blurV.glsl b/indra/newview/app_settings/shaders/class2/effects/blurV.glsl index ba65b16cc..cf4218bf7 100644 --- a/indra/newview/app_settings/shaders/class2/effects/blurV.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/blurV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform vec2 texelSize; uniform vec2 blurDirection; diff --git a/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl b/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl index 729949a17..f57633950 100644 --- a/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl @@ -5,6 +5,7 @@ * $License$ */ +#version 120 #extension GL_ARB_texture_rectangle : enable uniform sampler2DRect RenderTexture; diff --git a/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl b/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl index 29c2a0948..229ede470 100644 --- a/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 void main(void) { diff --git a/indra/newview/app_settings/shaders/class2/effects/extractF.glsl b/indra/newview/app_settings/shaders/class2/effects/extractF.glsl index f9eee5b89..fdf547264 100644 --- a/indra/newview/app_settings/shaders/class2/effects/extractF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/extractF.glsl @@ -5,6 +5,7 @@ * $License$ */ +#version 120 #extension GL_ARB_texture_rectangle : enable uniform sampler2DRect RenderTexture; diff --git a/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl b/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl index 833ef7d30..f6dfa52a9 100644 --- a/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl @@ -5,6 +5,7 @@ * $License$ */ +#version 120 #extension GL_ARB_texture_rectangle : enable uniform sampler2DRect RenderTexture; diff --git a/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl b/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl index 3a236846c..3dbed8e01 100644 --- a/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl @@ -5,6 +5,7 @@ * $License$ */ +#version 120 #extension GL_ARB_texture_rectangle : enable uniform sampler2DRect RenderTexture; diff --git a/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl b/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl index 4253bc21c..9ccc776ad 100644 --- a/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D detail_0; uniform sampler2D detail_1; diff --git a/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl b/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl index 119d55a2c..19211b8e6 100644 --- a/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl b/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl index 3a98970f8..6f2f560a9 100755 --- a/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D detail_0; uniform sampler2D detail_1; diff --git a/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl index 1998fea22..246b55440 100644 --- a/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; uniform sampler2D bumpMap; diff --git a/indra/newview/app_settings/shaders/class2/environment/waterF.glsl b/indra/newview/app_settings/shaders/class2/environment/waterF.glsl index 6ec3dc478..246377382 100644 --- a/indra/newview/app_settings/shaders/class2/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/waterF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 vec3 scaleSoftClip(vec3 inColor); vec3 atmosTransport(vec3 inColor); diff --git a/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl index 522c990cf..25d65b571 100644 --- a/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform vec4 lightnorm; uniform vec4 waterPlane; diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl index b372d6629..e7779d357 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl index e6b6d8580..509ac80b2 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl index 8f408c043..17a4cb03f 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; uniform samplerCube environmentMap; diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl new file mode 100644 index 000000000..9b4b58436 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl @@ -0,0 +1,31 @@ +/** + * @file lightFullbrightShinyWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +uniform sampler2D diffuseMap; +uniform samplerCube environmentMap; + +vec3 fullbrightShinyAtmosTransport(vec3 light); +vec3 fullbrightScaleSoftClip(vec3 light); +vec4 applyWaterFog(vec4 color); + +void fullbright_shiny_lighting_water() +{ + vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy); + color.rgb *= gl_Color.rgb; + + vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb; + color.rgb = mix(color.rgb, envColor.rgb, gl_Color.a); + + color.rgb = fullbrightShinyAtmosTransport(color.rgb); + color.rgb = fullbrightScaleSoftClip(color.rgb); + color.a = max(color.a, gl_Color.a); + + gl_FragColor = applyWaterFog(color); +} + diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl index 060ad9cb6..548d1c9ee 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl index b3927c77a..675fd4adf 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; uniform samplerCube environmentMap; diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl index f090306be..4e8a0d189 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl index c3384ffc5..4e9fa16a1 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 // All lights, no specular highlights diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl index ff3bcb5cd..75c0d7414 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 // All lights, no specular highlights diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl index 086954cd4..64df7f0f9 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl index edd1a8a94..2408e11d9 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da); vec3 calcPointLightSpecular(inout vec4 specular, vec3 view, vec3 v, vec3 n, vec3 l, float r, float pw, vec3 lightCol); diff --git a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl index f4c59734a..5f5b426da 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl @@ -4,9 +4,11 @@ * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 float calcDirectionalLight(vec3 n, vec3 l); -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight); vec3 atmosAmbient(vec3 light); vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -18,9 +20,10 @@ vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight) // Collect normal lights (need to be divided by two, as we later multiply by 2) col.rgb += gl_LightSource[1].diffuse.rgb * calcDirectionalLight(norm, gl_LightSource[1].position.xyz); - col.rgb += gl_LightSource[2].diffuse.rgb * calcPointLight(pos, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); - col.rgb += gl_LightSource[3].diffuse.rgb * calcPointLight(pos, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); - //col.rgb += gl_LightSource[4].diffuse.rgb * calcPointLight(pos, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); + + col.rgb += gl_LightSource[2].diffuse.rgb * calcPointLightOrSpotLight(pos, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); + col.rgb += gl_LightSource[3].diffuse.rgb * calcPointLightOrSpotLight(pos, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); + //col.rgb += gl_LightSource[4].diffuse.rgb * calcPointLightOrSpotLight(pos, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); col.rgb = scaleDownLight(col.rgb); // Add windlight lights diff --git a/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl b/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl index 0d52f32a2..76e96cb27 100755 --- a/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl +++ b/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl index 92c0664a5..80da3ee23 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 ////////////////////////////////////////////////////////// // The fragment shader for the terrain atmospherics diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl index 32d5ed5db..c806655dc 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 // Output variables vec3 getSunlitColor(); diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl index e40372e81..8b73c07ac 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 // varying param funcs void setSunlitColor(vec3 v); diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl index 0dbf2d35e..3a5eeb853 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 varying vec3 vary_PositionEye; diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl index b528837a5..aef449775 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 varying vec3 vary_PositionEye; diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl index b7d7e5a2c..69262ec7d 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 ///////////////////////////////////////////////////////////////////////// // The fragment shader for the sky diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl index e149d5861..881bb90b8 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 ////////////////////////////////////////////////////////////////////////// // The vertex shader for creating the atmospheric sky diff --git a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl index 5410889ed..3ca7a962d 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 uniform vec4 gamma; diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl index bc6d6d33f..6737d2617 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 ///////////////////////////////////////////////////////////////////////// // The fragment shader for the sky diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl index e396aea6c..e1a6844d2 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 // SKY //////////////////////////////////////////////////////////////////////// // The vertex shader for creating the atmospheric sky diff --git a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl index b7678cac6..e1e385496 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 ////////////////////////////////////////////////////////// // The fragment shader for the terrain atmospherics diff --git a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl b/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl index 04c10536e..1b6e843c0 100644 --- a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl +++ b/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); mat4 getSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl new file mode 100644 index 000000000..fc370ef36 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl @@ -0,0 +1,88 @@ +/** + * @file giDownsampleF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +uniform sampler2DRect giLightMap; + +uniform vec2 kern[32]; +uniform float dist_factor; +uniform float blur_size; +uniform vec2 delta; +uniform int kern_length; +uniform float kern_scale; +uniform vec3 blur_quad; + +varying vec2 vary_fragcoord; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +float getDepth(vec2 pos_screen) +{ + float z = texture2DRect(depthMap, pos_screen.xy).a; + z = z*2.0-1.0; + vec4 ndc = vec4(0.0, 0.0, z, 1.0); + vec4 p = inv_proj*ndc; + return p.z/p.w; +} + +void main() +{ + vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + float depth = getDepth(vary_fragcoord.xy); + + vec3 ccol = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; + vec2 dlt = kern_scale * delta/(vec2(1.0,1.0)+norm.xy*norm.xy); + dlt /= clamp(-depth*blur_quad.x, 1.0, 3.0); + float defined_weight = kern[0].x; + vec3 col = ccol*kern[0].x; + + for (int i = 0; i < kern_length; i++) + { + vec2 tc = vary_fragcoord.xy + kern[i].y*dlt; + vec3 sampNorm = texture2DRect(normalMap, tc.xy).xyz; + sampNorm = vec3((sampNorm.xy-0.5)*2.0,sampNorm.z); // unpack norm + + float d = dot(norm.xyz, sampNorm); + + if (d > 0.5) + { + float sampdepth = getDepth(tc.xy); + sampdepth -= depth; + if (sampdepth*sampdepth < blur_quad.z) + { + col += texture2DRect(giLightMap, tc).rgb*kern[i].x; + defined_weight += kern[i].x; + } + } + } + + col /= defined_weight; + + //col = ccol; + + col = col*blur_quad.y; + + gl_FragData[0].xyz = col; + + //gl_FragColor = ccol; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl new file mode 100644 index 000000000..ae57227fe --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl @@ -0,0 +1,19 @@ +/** + * @file postgiV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/giF.glsl b/indra/newview/app_settings/shaders/class3/deferred/giF.glsl new file mode 100644 index 000000000..951e3e97a --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/giF.glsl @@ -0,0 +1,193 @@ +/** + * @file giF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2DRect lightMap; +uniform sampler2DRect specularRect; + +uniform sampler2D noiseMap; + +uniform sampler2D diffuseGIMap; +uniform sampler2D specularGIMap; +uniform sampler2D normalGIMap; +uniform sampler2D depthGIMap; + +uniform sampler2D lightFunc; + +// Inputs +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +uniform vec4 sunlight_color; + +uniform mat4 inv_proj; +uniform mat4 gi_mat; //gPipeline.mGIMatrix - eye space to sun space +uniform mat4 gi_mat_proj; //gPipeline.mGIMatrixProj - eye space to projected sun space +uniform mat4 gi_norm_mat; //gPipeline.mGINormalMatrix - eye space normal to sun space normal matrix +uniform mat4 gi_inv_proj; //gPipeline.mGIInvProj - projected sun space to sun space +uniform float gi_sample_width; +uniform float gi_noise; +uniform float gi_attenuation; +uniform float gi_range; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +vec4 getGIPosition(vec2 gi_tc) +{ + float depth = texture2D(depthGIMap, gi_tc).a; + vec2 sc = gi_tc*2.0; + sc -= vec2(1.0, 1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = gi_inv_proj*ndc; + pos.xyz /= pos.w; + pos.w = 1.0; + return pos; +} + +vec3 giAmbient(vec3 pos, vec3 norm) +{ + vec4 gi_c = gi_mat_proj * vec4(pos, 1.0); + gi_c.xyz /= gi_c.w; + + vec4 gi_pos = gi_mat*vec4(pos,1.0); + vec3 gi_norm = (gi_norm_mat*vec4(norm,1.0)).xyz; + gi_norm = normalize(gi_norm); + + vec4 c_spec = texture2DRect(specularRect, vary_fragcoord.xy); + vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).rgb; + gi_pos.xyz += nz.x*gi_noise*gi_norm.xyz; + vec2 tcx = gi_norm.xy; + vec2 tcy = gi_norm.yx; + + vec4 eye_pos = gi_mat*vec4(0,0,0,1.0); + + vec3 eye_dir = normalize(gi_pos.xyz-eye_pos.xyz); + vec3 eye_ref = reflect(eye_dir, gi_norm); + + float da = 0.0; //texture2DRect(lightMap, vary_fragcoord.xy).r*0.5; + vec3 fdiff = vec3(da); + float fda = da; + + vec3 rcol = vec3(0,0,0); + + float fsa = 0.0; + + + for (int i = -1; i <= 1; i += 2 ) + { + for (int j = -1; j <= 1; j+= 2) + { + vec2 tc = vec2(i, j)*0.75+gi_norm.xy*nz.z; + tc += nz.xy*2.0; + tc *= gi_sample_width*0.25; + tc += gi_c.xy; + + vec3 lnorm = -(texture2D(normalGIMap, tc.xy).xyz*2.0-1.0); + vec3 lpos = getGIPosition(tc.xy).xyz; + + vec3 at = lpos-gi_pos.xyz; + float dist = length(at); + float dist_atten = clamp(1.0/(gi_attenuation*dist), 0.0, 1.0); + + + if (dist_atten > 0.01) + { //possible contribution of indirect light to this surface + vec3 ldir = at; + + float ld = -dot(ldir, lnorm); + + if (ld < 0.0) + { + float ang_atten = dot(ldir, gi_norm); + + if (ang_atten > 0.0) + { + vec4 spec = texture2D(specularGIMap, tc.xy); + at = normalize(at); + vec3 diff; + + float da = 0.0; + + //contribution from indirect source to visible pixel + vec3 ha = at; + ha.z -= 1.0; + ha = normalize(ha); + if (spec.a > 0.0) + { + float sa = dot(ha,lnorm); + da = texture2D(lightFunc, vec2(sa, spec.a)).a; + } + else + { + da = -lnorm.z; + } + + diff = texture2D(diffuseGIMap, tc.xy).rgb+spec.rgb*spec.a*2.0; + + if (da > 0.0) + { //contribution from visible pixel to eye + vec3 ha = normalize(at-eye_dir); + if (c_spec.a > 0.0) + { + float sa = dot(ha, gi_norm); + da = dist_atten*texture2D(lightFunc, vec2(sa, c_spec.a)).a; + } + else + { + da = dist_atten*dot(gi_norm, normalize(ldir)); + } + fda += da; + fdiff += da*(c_spec.rgb*c_spec.a*2.0+vec3(1,1,1))*diff.rgb; + } + } + } + } + } + } + + fdiff *= sunlight_color.rgb; + + vec3 ret = fda*fdiff; + + return clamp(ret,vec3(0.0), vec3(1.0)); +} + +void main() +{ + vec2 pos_screen = vary_fragcoord.xy; + vec4 pos = getPosition(pos_screen); + + float rad = gi_range*0.5; + + vec3 norm = texture2DRect(normalMap, pos_screen).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + float dist = max(length(pos.xyz)-rad, 0.0); + + float da = clamp(1.0-dist/rad, 0.0, 1.0); + + vec3 ambient = da > 0.0 ? giAmbient(pos.xyz, norm) : vec3(0); + + + gl_FragData[0].xyz = mix(vec3(0), ambient, da); +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/giFinalF.glsl b/indra/newview/app_settings/shaders/class3/deferred/giFinalF.glsl new file mode 100644 index 000000000..b2f8b2c63 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/giFinalF.glsl @@ -0,0 +1,27 @@ +/** + * @file giFinalF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2D bloomMap; +uniform sampler2DRect edgeMap; + +uniform vec2 screen_res; +varying vec2 vary_fragcoord; + + +void main() +{ + vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res); + vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); + + gl_FragColor = bloom + diff; + //gl_FragColor.rgb = vec3(texture2DRect(edgeMap, vary_fragcoord.xy).a); +} \ No newline at end of file diff --git a/indra/newview/app_settings/shaders/class3/deferred/giFinalV.glsl b/indra/newview/app_settings/shaders/class3/deferred/giFinalV.glsl new file mode 100644 index 000000000..19c4e07b8 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/giFinalV.glsl @@ -0,0 +1,19 @@ +/** + * @file giFinalV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/giV.glsl b/indra/newview/app_settings/shaders/class3/deferred/giV.glsl new file mode 100644 index 000000000..8dc1410ea --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/giV.glsl @@ -0,0 +1,24 @@ +/** + * @file giV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; + vec4 tex = gl_MultiTexCoord0; + tex.w = 1.0; + + gl_FrontColor = gl_Color; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl new file mode 100644 index 000000000..5f3bf68b2 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl @@ -0,0 +1,21 @@ +/** + * @file luminanceF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect lightMap; +uniform sampler2DRect diffuseRect; + +varying vec2 vary_fragcoord; +void main() +{ + float i = texture2DRect(lightMap, vary_fragcoord.xy).r; + gl_FragColor.rgb = vec3(i); + gl_FragColor.a = 1.0; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl b/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl new file mode 100644 index 000000000..a24eda35d --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl @@ -0,0 +1,22 @@ +/** + * @file giV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; + + gl_FrontColor = gl_Color; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl new file mode 100644 index 000000000..ab99a8897 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl @@ -0,0 +1,82 @@ +/** + * @file postDeferredF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; + +uniform sampler2DRect localLightMap; +uniform sampler2DRect sunLightMap; +uniform sampler2DRect giLightMap; +uniform sampler2DRect edgeMap; + +uniform sampler2D luminanceMap; + +uniform sampler2DRect lightMap; + +uniform sampler2D lightFunc; +uniform sampler2D noiseMap; + +uniform float sun_lum_scale; +uniform float sun_lum_offset; +uniform float lum_scale; +uniform float lum_lod; +uniform vec4 ambient; +uniform float gi_brightness; +uniform float gi_luminance; + +uniform vec4 sunlight_color; + +uniform vec2 screen_res; +varying vec2 vary_fragcoord; + +void main() +{ + vec2 tc = vary_fragcoord.xy; + vec4 lcol = texture2DLod(luminanceMap, vec2(0.5, 0.5), lum_lod); + + vec3 gi_col = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; + vec4 sun_col = texture2DRect(sunLightMap, vary_fragcoord.xy); + vec3 local_col = texture2DRect(localLightMap, vary_fragcoord.xy).rgb; + + float scol = texture2DRect(lightMap, vary_fragcoord.xy).r; + + vec3 diff = texture2DRect(diffuseRect, vary_fragcoord.xy).rgb; + vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); + + gi_col = gi_col*(diff.rgb+spec.rgb*spec.a); + + float lum = 1.0-clamp(pow(lcol.r, gi_brightness)+sun_lum_offset, 0.0, 1.0); + + lum *= sun_lum_scale; + + sun_col *= 1.0+(lum*lum_scale*scol); + + vec4 col; + col.rgb = gi_col+sun_col.rgb+local_col; + + col.a = sun_col.a; + + vec3 bcol = vec3(0,0,0); + float tweight = 0.0; + for (int i = 0; i < 16; i++) + { + float weight = (float(i)+1.0)/2.0; + bcol += texture2DLod(luminanceMap, vary_fragcoord.xy/screen_res, weight).rgb*weight*weight*weight; + tweight += weight*weight; + } + + bcol /= tweight; + bcol *= gi_luminance; + col.rgb += bcol*lum; + + gl_FragColor = col; + //gl_FragColor.rgb = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl b/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl new file mode 100644 index 000000000..12983baa9 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl @@ -0,0 +1,19 @@ +/** + * @file postDeferredV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl new file mode 100644 index 000000000..f03775470 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl @@ -0,0 +1,71 @@ +/** + * @file postgiF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2DRect giLightMap; +uniform sampler2D noiseMap; +uniform sampler2D giMip; +uniform sampler2DRect edgeMap; + + +uniform vec2 delta; +uniform float kern_scale; +uniform float gi_edge_weight; +uniform float gi_blur_brightness; + +varying vec2 vary_fragcoord; + +void main() +{ + vec2 dlt = kern_scale*delta; + float defined_weight = 0.0; + vec3 col = vec3(0.0); + + float e = 1.0; + + for (int i = 1; i < 8; i++) + { + vec2 tc = vary_fragcoord.xy + float(i) * dlt; + + e = max(e, 0.0); + float wght = e; + + col += texture2DRect(giLightMap, tc).rgb*wght; + defined_weight += wght; + + e *= e; + e -=(texture2DRect(edgeMap, tc.xy-dlt*0.25).a+ + texture2DRect(edgeMap, tc.xy+dlt*0.25).a)*gi_edge_weight; + } + + e = 1.0; + + for (int i = 1; i < 8; i++) + { + vec2 tc = vary_fragcoord.xy - float(i) * dlt; + + e = max(e,0.0); + float wght = e; + + col += texture2DRect(giLightMap, tc).rgb*wght; + defined_weight += wght; + + e *= e; + e -= (texture2DRect(edgeMap, tc.xy-dlt*0.25).a+ + texture2DRect(edgeMap, tc.xy+dlt*0.25).a)*gi_edge_weight; + + } + + col /= max(defined_weight, 0.01); + + gl_FragColor.rgb = col * gi_blur_brightness; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl b/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl new file mode 100644 index 000000000..ae57227fe --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl @@ -0,0 +1,19 @@ +/** + * @file postgiV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl new file mode 100644 index 000000000..ce32f6600 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -0,0 +1,358 @@ +/** + * @file softenLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect normalMap; +uniform sampler2DRect lightMap; +uniform sampler2D noiseMap; +uniform samplerCube environmentMap; +uniform sampler2D lightFunc; +uniform vec3 gi_quad; + +uniform float blur_size; +uniform float blur_fidelity; + +// Inputs +uniform vec4 morphFactor; +uniform vec3 camPosLocal; +//uniform vec4 camPosWorld; +uniform vec4 gamma; +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +uniform vec4 blue_density; +uniform vec4 haze_horizon; +uniform vec4 haze_density; +uniform vec4 cloud_shadow; +uniform vec4 density_multiplier; +uniform vec4 distance_multiplier; +uniform vec4 max_y; +uniform vec4 glow; +uniform float scene_light_strength; +uniform vec3 env_mat[3]; +uniform vec4 shadow_clip; +uniform mat3 ssao_effect_mat; + +uniform sampler2DRect depthMap; +uniform mat4 inv_proj; +uniform vec2 screen_res; + +varying vec4 vary_light; +varying vec2 vary_fragcoord; + +vec3 vary_PositionEye; + +vec3 vary_SunlitColor; +vec3 vary_AmblitColor; +vec3 vary_AdditiveColor; +vec3 vary_AtmosAttenuation; +uniform float gi_ambiance; + +vec4 getPosition_d(vec2 pos_screen, float depth) +{ + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +vec4 getPosition(vec2 pos_screen) +{ //get position in screen space (world units) given window coordinate and depth map + float depth = texture2DRect(depthMap, pos_screen.xy).a; + return getPosition_d(pos_screen, depth); +} + +vec3 getPositionEye() +{ + return vary_PositionEye; +} +vec3 getSunlitColor() +{ + return vary_SunlitColor; +} +vec3 getAmblitColor() +{ + return vary_AmblitColor; +} +vec3 getAdditiveColor() +{ + return vary_AdditiveColor; +} +vec3 getAtmosAttenuation() +{ + return vary_AtmosAttenuation; +} + + +void setPositionEye(vec3 v) +{ + vary_PositionEye = v; +} + +void setSunlitColor(vec3 v) +{ + vary_SunlitColor = v; +} + +void setAmblitColor(vec3 v) +{ + vary_AmblitColor = v; +} + +void setAdditiveColor(vec3 v) +{ + vary_AdditiveColor = v; +} + +void setAtmosAttenuation(vec3 v) +{ + vary_AtmosAttenuation = v; +} + +void calcAtmospherics(vec3 inPositionEye, float ambFactor) { + + vec3 P = inPositionEye; + setPositionEye(P); + + //(TERRAIN) limit altitude + if (P.y > max_y.x) P *= (max_y.x / P.y); + if (P.y < -max_y.x) P *= (-max_y.x / P.y); + + vec3 tmpLightnorm = lightnorm.xyz; + + vec3 Pn = normalize(P); + float Plen = length(P); + + vec4 temp1 = vec4(0); + vec3 temp2 = vec3(0); + vec4 blue_weight; + vec4 haze_weight; + vec4 sunlight = sunlight_color; + vec4 light_atten; + + //sunlight attenuation effect (hue and brightness) due to atmosphere + //this is used later for sunlight modulation at various altitudes + light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x); + //I had thought blue_density and haze_density should have equal weighting, + //but attenuation due to haze_density tends to seem too strong + + temp1 = blue_density + vec4(haze_density.r); + blue_weight = blue_density / temp1; + haze_weight = vec4(haze_density.r) / temp1; + + //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) + temp2.y = max(0.0, tmpLightnorm.y); + temp2.y = 1. / temp2.y; + sunlight *= exp( - light_atten * temp2.y); + + // main atmospheric scattering line integral + temp2.z = Plen * density_multiplier.x; + + // Transparency (-> temp1) + // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati + // compiler gets confused. + temp1 = exp(-temp1 * temp2.z * distance_multiplier.x); + + //final atmosphere attenuation factor + setAtmosAttenuation(temp1.rgb); + + //compute haze glow + //(can use temp2.x as temp because we haven't used it yet) + temp2.x = dot(Pn, tmpLightnorm.xyz); + temp2.x = 1. - temp2.x; + //temp2.x is 0 at the sun and increases away from sun + temp2.x = max(temp2.x, .03); //was glow.y + //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) + temp2.x *= glow.x; + //higher glow.x gives dimmer glow (because next step is 1 / "angle") + temp2.x = pow(temp2.x, glow.z); + //glow.z should be negative, so we're doing a sort of (1 / "angle") function + + //add "minimum anti-solar illumination" + temp2.x += .25; + + //increase ambient when there are more clouds + vec4 tmpAmbient = ambient*gi_ambiance + (vec4(1.) - ambient*gi_ambiance) * cloud_shadow.x * 0.5; + + /* decrease value and saturation (that in HSV, not HSL) for occluded areas + * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html + * // The following line of code performs the equivalent of: + * float ambAlpha = tmpAmbient.a; + * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis + * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); + * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); + */ + tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); + + //haze color + setAdditiveColor( + vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient) + + (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x + + tmpAmbient))); + + //brightness of surface both sunlight and ambient + setSunlitColor(vec3(sunlight * .5)); + setAmblitColor(vec3(tmpAmbient * .25)); + setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); +} + +vec3 atmosLighting(vec3 light) +{ + light *= getAtmosAttenuation().r; + light += getAdditiveColor(); + return (2.0 * light); +} + +vec3 atmosTransport(vec3 light) { + light *= getAtmosAttenuation().r; + light += getAdditiveColor() * 2.0; + return light; +} +vec3 atmosGetDiffuseSunlightColor() +{ + return getSunlitColor(); +} + +vec3 scaleDownLight(vec3 light) +{ + return (light / scene_light_strength ); +} + +vec3 scaleUpLight(vec3 light) +{ + return (light * scene_light_strength); +} + +vec3 atmosAmbient(vec3 light) +{ + return getAmblitColor() + light / 2.0; +} + +vec3 atmosAffectDirectionalLight(float lightIntensity) +{ + return getSunlitColor() * lightIntensity; +} + +vec3 scaleSoftClip(vec3 light) +{ + //soft clip effect: + light = 1. - clamp(light, vec3(0.), vec3(1.)); + light = 1. - pow(light, gamma.xxx); + + return light; +} + +void main() +{ + vec2 tc = vary_fragcoord.xy; + float depth = texture2DRect(depthMap, tc.xy).a; + vec3 pos = getPosition_d(tc, depth).xyz; + vec3 norm = texture2DRect(normalMap, tc).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm + //vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz; + + float da = max(dot(norm.xyz, vary_light.xyz), 0.0); + + vec4 diffuse = texture2DRect(diffuseRect, tc); + vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); + + da = texture2D(lightFunc, vec2(da, 0.0)).a; + + vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; + float scol = max(scol_ambocc.r, diffuse.a); + float ambocc = scol_ambocc.g; + + calcAtmospherics(pos.xyz, ambocc); + + vec3 col = atmosAmbient(vec3(0)); + col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a)); + + col *= diffuse.rgb; + + if (spec.a > 0.0) // specular reflection + { + // the old infinite-sky shiny reflection + // + vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); + float sa = dot(refnormpersp, vary_light.xyz); + vec3 dumbshiny = vary_SunlitColor*scol*texture2D(lightFunc, vec2(sa, spec.a)).a; + + /* + // screen-space cheap fakey reflection map + // + vec3 refnorm = normalize(reflect(vec3(0,0,-1), norm.xyz)); + depth -= 0.5; // unbias depth + // first figure out where we'll make our 2D guess from + vec2 ref2d = (0.25 * screen_res.y) * (refnorm.xy) * abs(refnorm.z) / depth; + // Offset the guess source a little according to a trivial + // checkerboard dither function and spec.a. + // This is meant to be similar to sampling a blurred version + // of the diffuse map. LOD would be better in that regard. + // The goal of the blur is to soften reflections in surfaces + // with low shinyness, and also to disguise our lameness. + float checkerboard = floor(mod(tc.x+tc.y, 2.0)); // 0.0, 1.0 + float checkoffset = (3.0 + (7.0*(1.0-spec.a)))*(checkerboard-0.5); + + ref2d += vec2(checkoffset, checkoffset); + ref2d += tc.xy; // use as offset from destination + // Get attributes from the 2D guess point. + // We average two samples of diffuse (not of anything else) per + // pixel to try to reduce aliasing some more. + vec3 refcol = 0.5 * (texture2DRect(diffuseRect, ref2d + vec2(0.0, -checkoffset)).rgb + + texture2DRect(diffuseRect, ref2d + vec2(-checkoffset, 0.0)).rgb); + float refdepth = texture2DRect(depthMap, ref2d).a; + vec3 refpos = getPosition_d(ref2d, refdepth).xyz; + float refshad = texture2DRect(lightMap, ref2d).r; + vec3 refn = texture2DRect(normalMap, ref2d).rgb; + refn = vec3((refn.xy-0.5)*2.0,refn.z); // unpack norm + refn = normalize(refn); + // figure out how appropriate our guess actually was + float refapprop = max(0.0, dot(-refnorm, normalize(pos - refpos))); + // darken reflections from points which face away from the reflected ray - our guess was a back-face + //refapprop *= step(dot(refnorm, refn), 0.0); + refapprop = min(refapprop, max(0.0, -dot(refnorm, refn))); // more conservative variant + // get appropriate light strength for guess-point. + // reflect light direction to increase the illusion that + // these are reflections. + vec3 reflight = reflect(lightnorm.xyz, norm.xyz); + float reflit = min(max(dot(refn, reflight.xyz), 0.0), refshad); + // apply sun color to guess-point, dampen according to inappropriateness of guess + float refmod = min(refapprop, reflit); + vec3 refprod = vary_SunlitColor * refcol.rgb * refmod; + vec3 ssshiny = (refprod * spec.a); + ssshiny *= 0.3; // dampen it even more + */ + vec3 ssshiny = vec3(0,0,0); + + // add the two types of shiny together + col += (ssshiny + dumbshiny) * spec.rgb; + } + + col = atmosLighting(col); + col = scaleSoftClip(col); + + gl_FragColor.rgb = col; + + //gl_FragColor.rgb = gi_col.rgb; + gl_FragColor.a = 0.0; + + //gl_FragColor.rg = scol_ambocc.rg; + //gl_FragColor.rgb = texture2DRect(lightMap, vary_fragcoord.xy).rgb; + //gl_FragColor.rgb = norm.rgb*0.5+0.5; + //gl_FragColor.rgb = vec3(ambocc); + //gl_FragColor.rgb = vec3(scol); +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl new file mode 100644 index 000000000..8f0bcca76 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl @@ -0,0 +1,26 @@ +/** + * @file softenLightF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +uniform vec2 screen_res; + +varying vec4 vary_light; +varying vec2 vary_fragcoord; +void main() +{ + //transform vertex + gl_Position = ftransform(); + + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; + + vec4 tex = gl_MultiTexCoord0; + tex.w = 1.0; + + vary_light = gl_MultiTexCoord0; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl new file mode 100644 index 000000000..c54d9a1e3 --- /dev/null +++ b/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl @@ -0,0 +1,21 @@ +/** + * @file treeF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +uniform sampler2D diffuseMap; + +varying vec3 vary_normal; + +void main() +{ + vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy); + gl_FragData[0] = vec4(gl_Color.rgb*col.rgb, col.a <= 0.5 ? 0.0 : 0.005); + gl_FragData[1] = vec4(0,0,0,0); + vec3 nvn = normalize(vary_normal); + gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); +} diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl index bf5c78f3e..ee61162c0 100644 --- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da); vec3 calcPointLightSpecular(inout vec4 specular, vec3 view, vec3 v, vec3 n, vec3 l, float r, float pw, vec3 lightCol); diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl index 1c5234c45..ae84fcb9c 100644 --- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl +++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl @@ -4,9 +4,11 @@ * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 float calcDirectionalLight(vec3 n, vec3 l); -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight); vec3 atmosAmbient(vec3 light); vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -15,24 +17,21 @@ vec3 scaleUpLight(vec3 light); vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight) { - vec4 col; - col.a = color.a; + vec4 col = vec4(0.0, 0.0, 0.0, color.a); - // Add windlight lights - col.rgb = atmosAffectDirectionalLight(calcDirectionalLight(norm, gl_LightSource[0].position.xyz)); - col.rgb += atmosAmbient(baseLight.rgb); - col.rgb = scaleUpLight(col.rgb); - // Collect normal lights (need to be divided by two, as we later multiply by 2) - col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); - col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); - col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); - col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation); - col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation); - col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation); + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a); col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); col.rgb = scaleDownLight(col.rgb); - + + // Add windlight lights + col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, gl_LightSource[0].position.xyz)); + col.rgb += atmosAmbient(baseLight.rgb); col.rgb = min(col.rgb*color.rgb, 1.0); diff --git a/indra/newview/app_settings/ultra_graphics.xml b/indra/newview/app_settings/ultra_graphics.xml index f16ec6c30..78213ff87 100644 --- a/indra/newview/app_settings/ultra_graphics.xml +++ b/indra/newview/app_settings/ultra_graphics.xml @@ -13,7 +13,7 @@ - + diff --git a/indra/newview/chatbar_as_cmdline.cpp b/indra/newview/chatbar_as_cmdline.cpp index 818df6279..e43a185c6 100644 --- a/indra/newview/chatbar_as_cmdline.cpp +++ b/indra/newview/chatbar_as_cmdline.cpp @@ -41,6 +41,7 @@ #include "llviewerregion.h" #include "llworld.h" #include "lluuid.h" +#include "lleventtimer.h" #include "llviewercontrol.h" #include "material_codes.h" diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index a587d10ac..e3a8ca0de 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -34,18 +34,16 @@ RenderFogRatio 1 4.0 RenderGamma 1 0 RenderGlowResolutionPow 1 9 RenderGround 1 1 -RenderLightingDetail 1 1 +RenderLocalLights 1 1 RenderMaxPartCount 1 8192 -RenderNightBrightness 1 1.0 RenderObjectBump 1 1 -RenderReflectionDetail 1 3 +RenderReflectionDetail 1 4 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 RenderTreeLODFactor 1 1.0 RenderUseImpostors 1 1 RenderVBOEnable 1 1 RenderVolumeLODFactor 1 2.0 -RenderWaterReflections 1 1 UseStartScreen 1 1 UseOcclusion 1 1 VertexShaderEnable 1 1 @@ -55,9 +53,12 @@ Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 RenderShaderLightingMaxLevel 1 3 RenderTextureMemoryMultiple 1 1.0 -RenderUseFBO 1 1 -RenderDeferred 1 1 -RenderFastAlpha 1 1 +RenderUseFBO 1 1 +RenderFastAlpha 1 1 +RenderDeferred 1 1 +RenderDeferredGI 1 1 +RenderShadowDetail 1 2 +RenderAvatarPhysicsLODFactor 1 1.0 // // Low Graphics Settings @@ -70,7 +71,7 @@ RenderAvatarVP 1 0 RenderFarClip 1 64 RenderFlexTimeFactor 1 0.1 RenderGlowResolutionPow 1 8 -RenderLightingDetail 1 0 +RenderLocalLights 1 0 RenderMaxPartCount 1 1024 RenderObjectBump 1 0 RenderReflectionDetail 1 0 @@ -79,13 +80,15 @@ RenderTerrainLODFactor 1 1 RenderTreeLODFactor 1 0.25 RenderUseImpostors 1 1 RenderVolumeLODFactor 1 0.5 -RenderWaterReflections 1 0 VertexShaderEnable 1 0 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -RenderUseFBO 0 0 -RenderDeferred 0 0 -RenderFastAlpha 0 0 +RenderUseFBO 0 0 +RenderFastAlpha 1 1 +RenderDeferred 0 0 +RenderDeferredGI 0 0 +RenderShadowDetail 0 0 +RenderAvatarPhysicsLODFactor 1 0.0 // // Mid Graphics Settings @@ -98,7 +101,7 @@ RenderAvatarVP 1 1 RenderFarClip 1 96 RenderFlexTimeFactor 1 0.5 RenderGlowResolutionPow 1 8 -RenderLightingDetail 1 1 +RenderLocalLights 1 1 RenderMaxPartCount 1 2048 RenderObjectBump 1 1 RenderReflectionDetail 1 0 @@ -107,13 +110,15 @@ RenderTerrainLODFactor 1 1.0 RenderTreeLODFactor 1 0.5 RenderUseImpostors 1 1 RenderVolumeLODFactor 1 1.125 -RenderWaterReflections 1 0 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -RenderUseFBO 1 0 -RenderDeferred 1 0 -RenderFastAlpha 1 0 +RenderUseFBO 1 0 +RenderFastAlpha 1 0 +RenderDeferred 1 0 +RenderDeferredGI 1 0 +RenderShadowDetail 1 0 +RenderAvatarPhysicsLODFactor 1 0.5 // @@ -127,7 +132,7 @@ RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 -RenderLightingDetail 1 1 +RenderLocalLights 1 1 RenderMaxPartCount 1 4096 RenderObjectBump 1 1 RenderReflectionDetail 1 2 @@ -136,13 +141,15 @@ RenderTerrainLODFactor 1 2.0 RenderTreeLODFactor 1 0.5 RenderUseImpostors 1 1 RenderVolumeLODFactor 1 1.125 -RenderWaterReflections 1 0 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 WLSkyDetail 1 48 -RenderUseFBO 1 0 -RenderDeferred 1 0 -RenderFastAlpha 1 0 +RenderUseFBO 1 0 +RenderFastAlpha 1 0 +RenderDeferred 1 0 +RenderDeferredGI 1 0 +RenderShadowDetail 1 0 +RenderAvatarPhysicsLODFactor 1 0.75 // @@ -156,22 +163,24 @@ RenderAvatarVP 1 1 RenderFarClip 1 256 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 -RenderLightingDetail 1 1 +RenderLocalLights 1 1 RenderMaxPartCount 1 8192 RenderObjectBump 1 1 -RenderReflectionDetail 1 3 +RenderReflectionDetail 1 4 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 RenderTreeLODFactor 1 1.0 RenderUseImpostors 1 1 RenderVolumeLODFactor 1 2.0 -RenderWaterReflections 1 1 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 WLSkyDetail 1 128 -RenderUseFBO 1 1 -RenderDeferred 1 1 -RenderFastAlpha 1 1 +RenderUseFBO 1 1 +RenderFastAlpha 1 0 +RenderDeferred 1 1 +RenderDeferredGI 1 0 +RenderShadowDetail 1 0 +RenderAvatarPhysicsLODFactor 1 1.0 // // Class Unknown Hardware (unknown) @@ -209,9 +218,10 @@ RenderVBOEnable 1 1 list NoPixelShaders RenderAvatarVP 0 0 RenderAvatarCloth 0 0 -RenderWaterReflections 0 0 +RenderReflectionDetail 0 0 VertexShaderEnable 0 0 WindLightUseAtmosShaders 0 0 +RenderDeferred 0 0 // // No Vertex Shaders available @@ -219,9 +229,10 @@ WindLightUseAtmosShaders 0 0 list NoVertexShaders RenderAvatarVP 0 0 RenderAvatarCloth 0 0 -RenderWaterReflections 0 0 +RenderReflectionDetail 0 0 VertexShaderEnable 0 0 WindLightUseAtmosShaders 0 0 +RenderDeferred 0 0 // "Default" setups for safe, low, medium, high // @@ -229,14 +240,16 @@ list safe RenderAnisotropic 1 0 RenderAvatarCloth 0 0 RenderAvatarVP 0 0 -RenderLightingDetail 1 0 +RenderLocalLights 1 0 RenderObjectBump 0 0 RenderMaxPartCount 1 1024 RenderTerrainDetail 1 0 RenderUseImpostors 0 0 RenderVBOEnable 1 0 -RenderWaterReflections 0 0 +RenderReflectionDetail 0 0 WindLightUseAtmosShaders 0 0 +RenderUseFBO 1 0 +RenderDeferred 1 0 // // CPU based feature masks @@ -260,12 +273,13 @@ RenderVBOEnable 1 0 list Intel RenderAnisotropic 1 0 -RenderLightingDetail 1 0 +RenderLocalLights 1 0 RenderUseImpostors 0 0 +RenderDeferred 1 0 list GeForce2 RenderAnisotropic 1 0 -RenderLightingDetail 1 0 +RenderLocalLights 1 0 RenderMaxPartCount 1 2048 RenderTerrainDetail 1 0 RenderVBOEnable 1 1 diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index c8245ae93..e64bfa3e3 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -34,18 +34,16 @@ RenderFogRatio 1 4.0 RenderGamma 1 0 RenderGlowResolutionPow 1 9 RenderGround 1 1 -RenderLightingDetail 1 1 +RenderLocalLights 1 1 RenderMaxPartCount 1 8192 -RenderNightBrightness 1 1.0 RenderObjectBump 1 1 -RenderReflectionDetail 1 3 +RenderReflectionDetail 1 4 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 RenderTreeLODFactor 1 1.0 RenderUseImpostors 1 1 RenderVBOEnable 1 1 RenderVolumeLODFactor 1 2.0 -RenderWaterReflections 1 1 UseStartScreen 1 1 UseOcclusion 1 1 VertexShaderEnable 1 1 @@ -55,9 +53,12 @@ Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 RenderShaderLightingMaxLevel 1 3 RenderTextureMemoryMultiple 1 1.0 -RenderUseFBO 1 1 -RenderDeferred 1 1 -RenderFastAlpha 1 1 +RenderUseFBO 1 1 +RenderFastAlpha 1 1 +RenderDeferred 1 1 +RenderDeferredGI 1 1 +RenderShadowDetail 1 2 +RenderAvatarPhysicsLODFactor 1 1.0 // // Low Graphics Settings @@ -70,7 +71,7 @@ RenderAvatarVP 1 0 RenderFarClip 1 64 RenderFlexTimeFactor 1 0.1 RenderGlowResolutionPow 1 8 -RenderLightingDetail 1 0 +RenderLocalLights 1 0 RenderMaxPartCount 1 1024 RenderObjectBump 1 0 RenderReflectionDetail 1 0 @@ -79,13 +80,15 @@ RenderTerrainLODFactor 1 1 RenderTreeLODFactor 1 0.25 RenderUseImpostors 1 1 RenderVolumeLODFactor 1 0.5 -RenderWaterReflections 1 0 VertexShaderEnable 1 0 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -RenderUseFBO 0 0 -RenderDeferred 0 0 -RenderFastAlpha 0 0 +RenderUseFBO 0 0 +RenderFastAlpha 1 1 +RenderDeferred 0 0 +RenderDeferredGI 0 0 +RenderShadowDetail 0 0 +RenderAvatarPhysicsLODFactor 1 0.0 // // Mid Graphics Settings @@ -98,7 +101,7 @@ RenderAvatarVP 1 1 RenderFarClip 1 96 RenderFlexTimeFactor 1 0.5 RenderGlowResolutionPow 1 8 -RenderLightingDetail 1 1 +RenderLocalLights 1 1 RenderMaxPartCount 1 2048 RenderObjectBump 1 1 RenderReflectionDetail 1 0 @@ -107,13 +110,15 @@ RenderTerrainLODFactor 1 1.0 RenderTreeLODFactor 1 0.5 RenderUseImpostors 1 1 RenderVolumeLODFactor 1 1.125 -RenderWaterReflections 1 0 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -RenderUseFBO 1 0 -RenderDeferred 1 0 -RenderFastAlpha 1 0 +RenderUseFBO 1 0 +RenderFastAlpha 1 0 +RenderDeferred 1 0 +RenderDeferredGI 1 0 +RenderShadowDetail 1 0 +RenderAvatarPhysicsLODFactor 1 0.5 // @@ -127,7 +132,7 @@ RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 -RenderLightingDetail 1 1 +RenderLocalLights 1 1 RenderMaxPartCount 1 4096 RenderObjectBump 1 1 RenderReflectionDetail 1 2 @@ -136,13 +141,15 @@ RenderTerrainLODFactor 1 2.0 RenderTreeLODFactor 1 0.5 RenderUseImpostors 1 1 RenderVolumeLODFactor 1 1.125 -RenderWaterReflections 1 0 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 WLSkyDetail 1 48 -RenderUseFBO 1 0 -RenderDeferred 1 0 -RenderFastAlpha 1 0 +RenderUseFBO 1 0 +RenderFastAlpha 1 0 +RenderDeferred 1 0 +RenderDeferredGI 1 0 +RenderShadowDetail 1 0 +RenderAvatarPhysicsLODFactor 1 0.75 // @@ -156,22 +163,24 @@ RenderAvatarVP 1 1 RenderFarClip 1 256 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 -RenderLightingDetail 1 1 +RenderLocalLights 1 1 RenderMaxPartCount 1 8192 RenderObjectBump 1 1 -RenderReflectionDetail 1 3 +RenderReflectionDetail 1 4 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 RenderTreeLODFactor 1 1.0 RenderUseImpostors 1 1 RenderVolumeLODFactor 1 2.0 -RenderWaterReflections 1 1 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 WLSkyDetail 1 128 -RenderUseFBO 1 1 -RenderDeferred 1 1 -RenderFastAlpha 1 1 +RenderUseFBO 1 1 +RenderFastAlpha 1 0 +RenderDeferred 1 1 +RenderDeferredGI 1 0 +RenderShadowDetail 1 0 +RenderAvatarPhysicsLODFactor 1 1.0 // @@ -210,9 +219,10 @@ RenderVBOEnable 1 1 list NoPixelShaders RenderAvatarVP 0 0 RenderAvatarCloth 0 0 -RenderWaterReflections 0 0 +RenderReflectionDetail 0 0 VertexShaderEnable 0 0 WindLightUseAtmosShaders 0 0 +RenderDeferred 0 0 // // No Vertex Shaders available @@ -220,9 +230,10 @@ WindLightUseAtmosShaders 0 0 list NoVertexShaders RenderAvatarVP 0 0 RenderAvatarCloth 0 0 -RenderWaterReflections 0 0 +RenderReflectionDetail 0 0 VertexShaderEnable 0 0 WindLightUseAtmosShaders 0 0 +RenderDeferred 0 0 // "Default" setups for safe, low, medium, high // @@ -230,16 +241,16 @@ list safe RenderAnisotropic 1 0 RenderAvatarCloth 0 0 RenderAvatarVP 0 0 -RenderLightingDetail 1 0 +RenderLocalLights 1 0 RenderObjectBump 0 0 RenderMaxPartCount 1 1024 RenderTerrainDetail 1 0 RenderUseImpostors 0 0 RenderVBOEnable 1 0 -RenderWaterReflections 0 0 +RenderReflectionDetail 0 0 WindLightUseAtmosShaders 0 0 -RenderUseFBO 1 0 -RenderDeferred 1 0 +RenderUseFBO 1 0 +RenderDeferred 1 0 // @@ -264,13 +275,14 @@ RenderVBOEnable 1 0 list Intel RenderAnisotropic 1 0 -RenderLightingDetail 1 0 +RenderLocalLights 1 0 // Avoid some Intel crashes on Linux RenderCubeMap 0 0 +RenderDeferred 1 0 list GeForce2 RenderAnisotropic 1 0 -RenderLightingDetail 1 0 +RenderLocalLights 1 0 RenderMaxPartCount 1 2048 RenderTerrainDetail 1 0 RenderVBOEnable 1 1 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 86df881f9..16156fe42 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -34,18 +34,16 @@ RenderFogRatio 1 4.0 RenderGamma 1 0 RenderGlowResolutionPow 1 9 RenderGround 1 1 -RenderLightingDetail 1 1 +RenderLocalLights 1 1 RenderMaxPartCount 1 8192 -RenderNightBrightness 1 1.0 RenderObjectBump 1 1 -RenderReflectionDetail 1 3 +RenderReflectionDetail 1 4 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 RenderTreeLODFactor 1 1.0 RenderUseImpostors 1 1 RenderVBOEnable 1 1 RenderVolumeLODFactor 1 2.0 -RenderWaterReflections 1 1 UseStartScreen 1 1 UseOcclusion 1 1 VertexShaderEnable 1 1 @@ -55,9 +53,12 @@ Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 RenderShaderLightingMaxLevel 1 3 RenderTextureMemoryMultiple 1 1.0 -RenderUseFBO 1 1 -RenderDeferred 1 1 -RenderFastAlpha 1 1 +RenderUseFBO 1 1 +RenderFastAlpha 1 1 +RenderDeferred 1 1 +RenderDeferredGI 1 1 +RenderShadowDetail 1 2 +RenderAvatarPhysicsLODFactor 1 1.0 // // Low Graphics Settings @@ -70,7 +71,7 @@ RenderAvatarVP 1 0 RenderFarClip 1 64 RenderFlexTimeFactor 1 0.1 RenderGlowResolutionPow 1 8 -RenderLightingDetail 1 0 +RenderLocalLights 1 0 RenderMaxPartCount 1 1024 RenderObjectBump 1 0 RenderReflectionDetail 1 0 @@ -79,13 +80,15 @@ RenderTerrainLODFactor 1 1 RenderTreeLODFactor 1 0.25 RenderUseImpostors 1 1 RenderVolumeLODFactor 1 0.5 -RenderWaterReflections 1 0 VertexShaderEnable 1 0 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -RenderUseFBO 0 0 -RenderDeferred 0 0 -RenderFastAlpha 0 0 +RenderUseFBO 0 0 +RenderFastAlpha 1 1 +RenderDeferred 0 0 +RenderDeferredGI 0 0 +RenderShadowDetail 0 0 +RenderAvatarPhysicsLODFactor 1 0.0 // // Mid Graphics Settings @@ -98,7 +101,7 @@ RenderAvatarVP 1 1 RenderFarClip 1 96 RenderFlexTimeFactor 1 0.5 RenderGlowResolutionPow 1 8 -RenderLightingDetail 1 1 +RenderLocalLights 1 1 RenderMaxPartCount 1 2048 RenderObjectBump 1 1 RenderReflectionDetail 1 0 @@ -107,13 +110,15 @@ RenderTerrainLODFactor 1 1.0 RenderTreeLODFactor 1 0.5 RenderUseImpostors 1 1 RenderVolumeLODFactor 1 1.125 -RenderWaterReflections 1 0 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -RenderUseFBO 1 0 -RenderDeferred 1 0 -RenderFastAlpha 1 0 +RenderUseFBO 1 0 +RenderFastAlpha 1 0 +RenderDeferred 1 0 +RenderDeferredGI 1 0 +RenderShadowDetail 1 0 +RenderAvatarPhysicsLODFactor 1 0.5 // @@ -127,7 +132,7 @@ RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 -RenderLightingDetail 1 1 +RenderLocalLights 1 1 RenderMaxPartCount 1 4096 RenderObjectBump 1 1 RenderReflectionDetail 1 2 @@ -136,13 +141,15 @@ RenderTerrainLODFactor 1 2.0 RenderTreeLODFactor 1 0.5 RenderUseImpostors 1 1 RenderVolumeLODFactor 1 1.125 -RenderWaterReflections 1 0 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 WLSkyDetail 1 48 -RenderUseFBO 1 0 -RenderDeferred 1 0 -RenderFastAlpha 1 0 +RenderUseFBO 1 0 +RenderFastAlpha 1 0 +RenderDeferred 1 0 +RenderDeferredGI 1 0 +RenderShadowDetail 1 0 +RenderAvatarPhysicsLODFactor 1 0.75 // @@ -156,22 +163,24 @@ RenderAvatarVP 1 1 RenderFarClip 1 256 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 -RenderLightingDetail 1 1 +RenderLocalLights 1 1 RenderMaxPartCount 1 8192 RenderObjectBump 1 1 -RenderReflectionDetail 1 3 +RenderReflectionDetail 1 4 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 RenderTreeLODFactor 1 1.0 RenderUseImpostors 1 1 RenderVolumeLODFactor 1 2.0 -RenderWaterReflections 1 1 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 WLSkyDetail 1 128 -RenderUseFBO 1 1 -RenderDeferred 1 1 -RenderFastAlpha 1 1 +RenderUseFBO 1 1 +RenderFastAlpha 1 0 +RenderDeferred 1 1 +RenderDeferredGI 1 0 +RenderShadowDetail 1 0 +RenderAvatarPhysicsLODFactor 1 1.0 // // Class Unknown Hardware (unknown) @@ -209,9 +218,10 @@ RenderVBOEnable 1 1 list NoPixelShaders RenderAvatarVP 0 0 RenderAvatarCloth 0 0 -RenderWaterReflections 0 0 +RenderReflectionDetail 0 0 VertexShaderEnable 0 0 WindLightUseAtmosShaders 0 0 +RenderDeferred 0 0 // // No Vertex Shaders available @@ -219,9 +229,10 @@ WindLightUseAtmosShaders 0 0 list NoVertexShaders RenderAvatarVP 0 0 RenderAvatarCloth 0 0 -RenderWaterReflections 0 0 +RenderReflectionDetail 0 0 VertexShaderEnable 0 0 WindLightUseAtmosShaders 0 0 +RenderDeferred 0 0 // "Default" setups for safe, low, medium, high // @@ -229,14 +240,16 @@ list safe RenderAnisotropic 1 0 RenderAvatarCloth 0 0 RenderAvatarVP 0 0 -RenderLightingDetail 1 0 +RenderLocalLights 1 0 RenderObjectBump 0 0 RenderMaxPartCount 1 1024 RenderTerrainDetail 1 0 RenderUseImpostors 0 0 RenderVBOEnable 1 0 -RenderWaterReflections 0 0 +RenderReflectionDetail 0 0 WindLightUseAtmosShaders 0 0 +RenderUseFBO 1 0 +RenderDeferred 1 0 // // CPU based feature masks @@ -260,11 +273,12 @@ RenderVBOEnable 1 0 list Intel RenderAnisotropic 1 0 -RenderLightingDetail 1 0 +RenderLocalLights 1 0 +RenderDeferred 1 0 list GeForce2 RenderAnisotropic 1 0 -RenderLightingDetail 1 0 +RenderLocalLights 1 0 RenderMaxPartCount 1 2048 RenderTerrainDetail 1 0 RenderVBOEnable 1 1 diff --git a/indra/newview/floaterao.h b/indra/newview/floaterao.h index cf8ee2252..55cc7c052 100644 --- a/indra/newview/floaterao.h +++ b/indra/newview/floaterao.h @@ -5,6 +5,7 @@ #include "llfloater.h" #include "llviewercontrol.h" #include "llagent.h" +#include "lleventtimer.h" class AONoteCardDropTarget; diff --git a/indra/newview/floaterlocalassetbrowse.h b/indra/newview/floaterlocalassetbrowse.h index 42620e314..fb26cdccc 100644 --- a/indra/newview/floaterlocalassetbrowse.h +++ b/indra/newview/floaterlocalassetbrowse.h @@ -42,6 +42,7 @@ tag: vaa emerald local_asset_browser #include "llscrolllistctrl.h" #include "lltexturectrl.h" #include "lldrawable.h" +#include "lleventtimer.h" /*=======================================*/ diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index cb373dd66..2f8b41b73 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -44,6 +44,7 @@ #include "lltexteditor.h" #include "llalertdialog.h" #include "llerrorcontrol.h" +#include "lleventtimer.h" #include "llviewertexturelist.h" #include "llgroupmgr.h" #include "llagent.h" diff --git a/indra/newview/llbuildnewviewsscheduler.h b/indra/newview/llbuildnewviewsscheduler.h index a3d5af66c..2f819288f 100644 --- a/indra/newview/llbuildnewviewsscheduler.h +++ b/indra/newview/llbuildnewviewsscheduler.h @@ -1,6 +1,7 @@ // #include "llinventoryview.h" #include "llinventory.h" +#include "lleventtimer.h" class LLBuildNewViewsScheduler : public LLEventTimer { typedef struct diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index e8d6daca4..fce802f77 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -803,8 +803,7 @@ void LLDrawable::shiftPos(const LLVector3 &shift_vector) if (!volume && facep->hasGeometry()) { - facep->mVertexBuffer = NULL; - facep->mLastVertexBuffer = NULL; + facep->clearVertexBuffer(); } } @@ -913,6 +912,18 @@ void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp) { mSpatialGroupp->setState(LLSpatialGroup::GEOM_DIRTY); }*/ + + if (mSpatialGroupp != groupp && getVOVolume()) + { //NULL out vertex buffer references for volumes on spatial group change to maintain + //requirement that every face vertex buffer is either NULL or points to a vertex buffer + //contained by its drawable's spatial group + for (S32 i = 0; i < getNumFaces(); ++i) + { + LLFace* facep = getFace(i); + facep->clearVertexBuffer(); + } + } + mSpatialGroupp = groupp; } @@ -1030,7 +1041,7 @@ BOOL LLDrawable::isVisible() const //======================================= LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask) -: LLSpatialPartition(data_mask, render_by_group, FALSE) +: LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB) { mDrawable = root; root->setSpatialBridge(this); diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 7202f3476..32049da0d 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -68,6 +68,17 @@ const U32 SILHOUETTE_HIGHLIGHT = 0; class LLDrawable : public LLRefCount { public: + LLDrawable(const LLDrawable& rhs) + { + *this = rhs; + } + + const LLDrawable& operator=(const LLDrawable& rhs) + { + llerrs << "Illegal operation!" << llendl; + return *this; + } + static void initClass(); LLDrawable() { init(); } @@ -103,7 +114,7 @@ public: const LLQuaternion& getRotation() const { return mXform.getRotation(); } F32 getIntensity() const { return llmin(mXform.getScale().mV[0], 4.f); } S32 getLOD() const { return mVObjp ? mVObjp->getLOD() : 1; } - F64 getBinRadius() const { return mBinRadius; } + F32 getBinRadius() const { return mBinRadius; } void getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); } LLXformMatrix* getXform() { return &mXform; } @@ -301,9 +312,9 @@ private: F32 mRadius; LLVector3 mExtents[2]; LLVector3d mPositionGroup; - F64 mBinRadius; + F32 mBinRadius; S32 mGeneration; - + LLVector3 mCurrentScale; static U32 sCurVisible; // Counter for what value of mVisible means currently visible diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 0d41ab85f..474538a17 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -296,13 +296,6 @@ void LLFacePool::drawLoop() } } -void LLFacePool::renderFaceSelected(LLFace *facep, - LLViewerTexture *image, - const LLColor4 &color, - const S32 index_offset, const S32 index_count) -{ -} - void LLFacePool::enqueue(LLFace* facep) { mDrawFace.push_back(facep); diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index f92756ae3..440a2a845 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -169,10 +169,10 @@ public: LLFacePool(const U32 type); virtual ~LLFacePool(); - virtual void renderForSelect() = 0; + virtual void renderForSelect() {}; //Override if neded. BOOL isDead() { return mReferences.empty(); } virtual void renderFaceSelected(LLFace *facep, LLViewerTexture *image, const LLColor4 &color, - const S32 index_offset = 0, const S32 index_count = 0); + const S32 index_offset = 0, const S32 index_count = 0) {}; //Override if neded. virtual LLViewerTexture *getTexture(); virtual void dirtyTextures(const std::set& textures); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 08c430e62..d6ea59ff7 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -198,7 +198,10 @@ void LLDrawPoolAlpha::render(S32 pass) simple_shader->bind(); pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask()); } - fullbright_shader->bind(); + if (fullbright_shader) + { + fullbright_shader->bind(); + } pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask()); LLGLSLShader::bindNoShader(); } @@ -238,7 +241,7 @@ void LLDrawPoolAlpha::render(S32 pass) gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); glColor4f(1,0,0,1); LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f*1024.f); - gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep.get(), TRUE); + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep, TRUE) ; renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); } @@ -280,6 +283,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) { BOOL initialized_lighting = FALSE; BOOL light_enabled = TRUE; + S32 diffuse_channel = 0; + //BOOL is_particle = FALSE; BOOL use_shaders = (LLPipeline::sUnderWaterRender && gPipeline.canUseVertexShaders()) || gPipeline.canUseWindLightShadersOnObjects(); @@ -360,11 +365,13 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) if (deferred_render && current_shader != NULL) { gPipeline.unbindDeferredShader(*current_shader); + diffuse_channel = 0; } current_shader = target_shader; if (deferred_render) { gPipeline.bindDeferredShader(*current_shader); + diffuse_channel = current_shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); } else { @@ -373,10 +380,10 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) } else if (!use_shaders && current_shader != NULL) { - if (deferred_render) { gPipeline.unbindDeferredShader(*current_shader); + diffuse_channel = 0; } LLGLSLShader::bindNoShader(); current_shader = NULL; @@ -390,7 +397,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) if (params.mTexture.notNull()) { - gGL.getTexUnit(0)->bind(params.mTexture.get()); + gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get()); if(params.mTexture.notNull()) { params.mTexture->addTextureStats(params.mVSize); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index a6e43e5b5..92d257734 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -94,6 +94,7 @@ BOOL gAvatarEmbossBumpMap = FALSE; static BOOL sRenderingSkinned = FALSE; S32 normal_channel = -1; S32 specular_channel = -1; +S32 diffuse_channel = -1; LLDrawPoolAvatar::LLDrawPoolAvatar() : LLFacePool(POOL_AVATAR) @@ -400,6 +401,7 @@ void LLDrawPoolAvatar::beginImpostor() } gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); + diffuse_channel = 0; } void LLDrawPoolAvatar::endImpostor() @@ -452,6 +454,7 @@ void LLDrawPoolAvatar::beginDeferredImpostor() normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL); specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP); + diffuse_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); sVertexProgram->bind(); } @@ -461,6 +464,7 @@ void LLDrawPoolAvatar::endDeferredImpostor() sShaderLevel = mVertexShaderLevel; sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL); sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP); + sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); sVertexProgram->unbind(); gGL.getTexUnit(0)->activate(); } @@ -659,8 +663,10 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) gGL.translatef((F32)(pos.mV[VX]), (F32)(pos.mV[VY]), (F32)(pos.mV[VZ])); - gGL.scalef(0.15f, 0.15f, 0.3f); - gSphere.render(); + gGL.scalef(0.15f, 0.15f, 0.3f); + + gSphere.renderGGL(); + gGL.popMatrix(); gGL.setColorMask(true, false); } @@ -702,7 +708,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) avatarp->mImpostor.bindTexture(1, specular_channel); } } - avatarp->renderImpostor(); + avatarp->renderImpostor(LLColor4U(255,255,255,255), diffuse_channel); } else if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS) && !LLPipeline::sRenderDeferred) { diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index fc5f9dbff..d24726052 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -39,8 +39,6 @@ class LLVOAvatar; class LLDrawPoolAvatar : public LLFacePool { -protected: - S32 mNumFaces; public: enum { diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 6ca90c2be..38837a8cc 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -152,12 +152,7 @@ void LLStandardBumpmap::addstandard() // llinfos << "Loading bumpmap: " << bump_file << " from viewerart" << llendl; gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label; gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage = - LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id), - TRUE, - LLViewerTexture::BOOST_NONE, - LLViewerTexture::LOD_TEXTURE, - 0, - 0); + LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id)); gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLViewerTexture::BOOST_BUMP) ; gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL ); LLStandardBumpmap::sStandardBumpmapCount++; @@ -342,30 +337,43 @@ void LLDrawPoolBump::beginShiny(bool invisible) sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0; } - if (LLPipeline::sUnderWaterRender) + if (getVertexShaderLevel() > 0) { - shader = &gObjectShinyWaterProgram; + if (LLPipeline::sUnderWaterRender) + { + shader = &gObjectShinyWaterProgram; + } + else + { + shader = &gObjectShinyProgram; + } + shader->bind(); } else { - shader = &gObjectShinyProgram; + shader = NULL; } + bindCubeMap(shader, mVertexShaderLevel, diffuse_channel, cube_channel, invisible); +} + +//static +void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible) +{ LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; if( cube_map ) { - if (!invisible && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0 ) + if (!invisible && shader ) { LLMatrix4 mat; mat.initRows(LLVector4(gGLModelView+0), LLVector4(gGLModelView+4), LLVector4(gGLModelView+8), LLVector4(gGLModelView+12)); - shader->bind(); LLVector3 vec = LLVector3(gShinyOrigin) * mat; LLVector4 vec4(vec, gShinyOrigin.mV[3]); shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV); - if (mVertexShaderLevel > 1) + if (shader_level > 1) { cube_map->setMatrix(1); // Make sure that texture coord generation happens for tex unit 1, as that's the one we use for @@ -427,22 +435,16 @@ void LLDrawPoolBump::renderShiny(bool invisible) } } -void LLDrawPoolBump::endShiny(bool invisible) +//static +void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible) { - LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); - if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))|| - (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))) - { - return; - } - LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; if( cube_map ) { cube_map->disable(); cube_map->restoreMatrix(); - if (!invisible && mVertexShaderLevel > 1) + if (!invisible && shader_level > 1) { shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); @@ -453,7 +455,6 @@ void LLDrawPoolBump::endShiny(bool invisible) shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); } } - shader->unbind(); } } gGL.getTexUnit(diffuse_channel)->disable(); @@ -461,6 +462,22 @@ void LLDrawPoolBump::endShiny(bool invisible) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +} + +void LLDrawPoolBump::endShiny(bool invisible) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); + if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))|| + (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))) + { + return; + } + + unbindCubeMap(shader, mVertexShaderLevel, diffuse_channel, cube_channel, invisible); + if (shader) + { + shader->unbind(); + } diffuse_channel = -1; cube_channel = 0; @@ -481,7 +498,7 @@ void LLDrawPoolBump::beginFullbrightShiny() if (LLPipeline::sUnderWaterRender) { - shader = &gObjectShinyWaterProgram; + shader = &gObjectFullbrightShinyWaterProgram; } else { @@ -588,18 +605,37 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL // static BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel) { - LLViewerTexture* bump = NULL; - U8 bump_code = params.mBump; + return bindBumpMap(bump_code, params.mTexture, params.mVSize, channel); +} + +//static +BOOL LLDrawPoolBump::bindBumpMap(LLFace* face, S32 channel) +{ + const LLTextureEntry* te = face->getTextureEntry(); + if (te) + { + U8 bump_code = te->getBumpmap(); + return bindBumpMap(bump_code, face->getTexture(), face->getVirtualSize(), channel); + } + + return FALSE; +} + +//static +BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsize, S32 channel) +{ //Note: texture atlas does not support bump texture now. - LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(params.mTexture) ; + LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(texture) ; if(!tex) { //if the texture is not a fetched texture return FALSE; } + LLViewerTexture* bump = NULL; + switch( bump_code ) { case BE_NO_BUMP: @@ -613,7 +649,7 @@ BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel) if( bump_code < LLStandardBumpmap::sStandardBumpmapCount ) { bump = gStandardBumpmapList[bump_code].mImage; - gBumpImageList.addTextureStats(bump_code, tex->getID(), params.mVSize); + gBumpImageList.addTextureStats(bump_code, tex->getID(), vsize); } break; } @@ -968,25 +1004,28 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText } bump_image_map_t::iterator iter = entries_list->find(src_image->getID()); - if (iter != entries_list->end()) + if (iter != entries_list->end() && iter->second.notNull()) { bump = iter->second; } else { LLPointer raw = new LLImageRaw(1,1,1); - raw->clear(0x77, 0x77, 0x77, 0xFF); + raw->clear(0x77, 0x77, 0xFF, 0xFF); (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( raw.get(), TRUE); - (*entries_list)[src_image->getID()]->setExplicitFormat(GL_ALPHA8, GL_ALPHA); - - // Note: this may create an LLImageGL immediately - src_image->setBoostLevel(LLViewerTexture::BOOST_BUMP) ; - src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL ); bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image + } -// bump_total++; -// llinfos << "*** Creating " << (void*)bump << " " << bump_total << llendl; + if (!src_image->hasCallbacks()) + { //if image has no callbacks but resolutions don't match, trigger raw image loaded callback again + if (src_image->getWidth() != bump->getWidth() || + src_image->getHeight() != bump->getHeight() || + (LLPipeline::sRenderDeferred && bump->getComponents() != 4)) + { + src_image->setBoostLevel(LLViewerTexture::BOOST_BUMP) ; + src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL ); + } } } @@ -1089,7 +1128,21 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI { bump_image_map_t& entries_list(bump_code == BE_BRIGHTNESS ? gBumpImageList.mBrightnessEntries : gBumpImageList.mDarknessEntries ); bump_image_map_t::iterator iter = entries_list.find(source_asset_id); - if (iter != entries_list.end()) + + if (iter == entries_list.end() || + iter->second.isNull() || + iter->second->getWidth() != src->getWidth() || + iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution + { //make sure an entry exists for this image + LLPointer raw = new LLImageRaw(1,1,1); + raw->clear(0x77, 0x77, 0xFF, 0xFF); + + entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture( raw.get(), TRUE); + iter = entries_list.find(src_vi->getID()); + } + + //if (iter->second->getWidth() != src->getWidth() || + // iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution { LLPointer dst_image = new LLImageRaw(src->getWidth(), src->getHeight(), 1); U8* dst_data = dst_image->getData(); @@ -1216,18 +1269,10 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI bump->setExplicitFormat(GL_RGBA, GL_RGBA); bump->createGLTexture(0, nrm_image); } - - + iter->second = bump; // derefs (and deletes) old image //--------------------------------------------------- } - else - { - // entry should have been added in LLBumpImageList::getImage(). - - // Not a legit assertion - the bump texture could have been flushed by the bump image manager - //llassert(0); - } } } diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index f67ba7d3d..9c6569665 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -41,6 +41,7 @@ class LLImageRaw; class LLSpatialGroup; class LLDrawInfo; +class LLGLSLShader; class LLViewerFetchedTexture; class LLDrawPoolBump : public LLRenderPass @@ -79,6 +80,9 @@ public: void renderBump(U32 pass = LLRenderPass::PASS_BUMP); void endBump(U32 pass = LLRenderPass::PASS_BUMP); + static void bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible); + static void unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible); + virtual S32 getNumDeferredPasses(); /*virtual*/ void beginDeferredPass(S32 pass); /*virtual*/ void endDeferredPass(S32 pass); @@ -89,7 +93,12 @@ public: /*virtual*/ void endPostDeferredPass(S32 pass); /*virtual*/ void renderPostDeferred(S32 pass); - BOOL bindBumpMap(LLDrawInfo& params, S32 channel = -2); + static BOOL bindBumpMap(LLDrawInfo& params, S32 channel = -2); + static BOOL bindBumpMap(LLFace* face, S32 channel = -2); + +private: + static BOOL bindBumpMap(U8 bump_code, LLViewerTexture* tex, F32 vsize, S32 channel); + }; enum EBumpEffect diff --git a/indra/newview/lldrawpoolclouds.cpp b/indra/newview/lldrawpoolclouds.cpp index 1d159998a..8844c3c71 100644 --- a/indra/newview/lldrawpoolclouds.cpp +++ b/indra/newview/lldrawpoolclouds.cpp @@ -101,6 +101,3 @@ void LLDrawPoolClouds::render(S32 pass) } -void LLDrawPoolClouds::renderForSelect() -{ -} diff --git a/indra/newview/lldrawpoolclouds.h b/indra/newview/lldrawpoolclouds.h index c70dd41f7..7c95b3ec0 100644 --- a/indra/newview/lldrawpoolclouds.h +++ b/indra/newview/lldrawpoolclouds.h @@ -55,7 +55,6 @@ public: /*virtual*/ void enqueue(LLFace *face); /*virtual*/ void beginRenderPass(S32 pass); /*virtual*/ void render(S32 pass = 0); - /*virtual*/ void renderForSelect(); }; #endif // LL_LLDRAWPOOLSKY_H diff --git a/indra/newview/lldrawpoolground.cpp b/indra/newview/lldrawpoolground.cpp index c65524b7c..9d63113d5 100644 --- a/indra/newview/lldrawpoolground.cpp +++ b/indra/newview/lldrawpoolground.cpp @@ -91,7 +91,3 @@ void LLDrawPoolGround::render(S32 pass) glPopMatrix(); } -void LLDrawPoolGround::renderForSelect() -{ -} - diff --git a/indra/newview/lldrawpoolground.h b/indra/newview/lldrawpoolground.h index 6c7d20bec..9ac96ca59 100644 --- a/indra/newview/lldrawpoolground.h +++ b/indra/newview/lldrawpoolground.h @@ -53,7 +53,6 @@ public: /*virtual*/ void prerender(); /*virtual*/ void render(S32 pass = 0); - /*virtual*/ void renderForSelect(); }; #endif // LL_LLDRAWPOOLGROUND_H diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp index 98c729dfe..4d34f7cd2 100644 --- a/indra/newview/lldrawpoolsky.cpp +++ b/indra/newview/lldrawpoolsky.cpp @@ -43,7 +43,6 @@ #include "llviewercamera.h" #include "llviewertexturelist.h" #include "llviewerregion.h" -#include "llviewerwindow.h" #include "llvosky.h" #include "llworld.h" // To get water height #include "pipeline.h" @@ -118,13 +117,14 @@ void LLDrawPoolSky::render(S32 pass) S32 face_count = (S32)mDrawFace.size(); + LLVertexBuffer::unbind(); + glColor4f(1,1,1,1); + for (S32 i = 0; i < llmin(6, face_count); ++i) { renderSkyCubeFace(i); } - LLGLEnable blend(GL_BLEND); - glPopMatrix(); } @@ -136,6 +136,7 @@ void LLDrawPoolSky::renderSkyCubeFace(U8 side) return; } + llassert(mSkyTex); mSkyTex[side].bindTexture(TRUE); face.renderIndexed(); @@ -149,10 +150,6 @@ void LLDrawPoolSky::renderSkyCubeFace(U8 side) } } -void LLDrawPoolSky::renderForSelect() -{ -} - void LLDrawPoolSky::endRenderPass( S32 pass ) { } diff --git a/indra/newview/lldrawpoolsky.h b/indra/newview/lldrawpoolsky.h index 8595d73ae..3da493cc9 100644 --- a/indra/newview/lldrawpoolsky.h +++ b/indra/newview/lldrawpoolsky.h @@ -64,7 +64,6 @@ public: /*virtual*/ void prerender(); /*virtual*/ void render(S32 pass = 0); - /*virtual*/ void renderForSelect(); /*virtual*/ void endRenderPass(S32 pass); void setSkyTex(LLSkyTex* const st) { mSkyTex = st; } diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 957869004..762a087ff 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -114,11 +114,12 @@ void LLDrawPoolTree::render(S32 pass) iter != mDrawFace.end(); iter++) { LLFace *face = *iter; - if(face->mVertexBuffer.notNull()) + LLVertexBuffer* buff = face->getVertexBuffer(); + if(buff) { - face->mVertexBuffer->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); - face->mVertexBuffer->drawRange(LLRender::TRIANGLES, 0, face->mVertexBuffer->getRequestedVerts()-1, face->mVertexBuffer->getRequestedIndices(), 0); - gPipeline.addTrianglesDrawn(face->mVertexBuffer->getRequestedIndices()); + buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); + buff->drawRange(LLRender::TRIANGLES, 0, buff->getRequestedVerts()-1, buff->getRequestedIndices(), 0); + gPipeline.addTrianglesDrawn(buff->getRequestedIndices()); } } } @@ -167,6 +168,10 @@ void LLDrawPoolTree::beginShadowPass(S32 pass) { LLFastTimer t(LLFastTimer::FTM_SHADOW_TREE); gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); + static const LLCachedControl render_deferred_offset("RenderDeferredTreeShadowOffset",1.f); + static const LLCachedControl render_deferred_bias("RenderDeferredTreeShadowBias",1.f); + glPolygonOffset(render_deferred_offset,render_deferred_bias); + gDeferredShadowProgram.bind(); } @@ -179,7 +184,11 @@ void LLDrawPoolTree::endShadowPass(S32 pass) { LLFastTimer t(LLFastTimer::FTM_SHADOW_TREE); gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); - gDeferredShadowProgram.unbind(); + static const LLCachedControl render_deferred_offset("RenderDeferredTreeShadowOffset",1.f); + static const LLCachedControl render_deferred_bias("RenderDeferredTreeShadowBias",1.f); + glPolygonOffset(render_deferred_offset,render_deferred_bias); + + //gDeferredShadowProgram.unbind(); } @@ -216,7 +225,7 @@ void LLDrawPoolTree::renderForSelect() LLFace *face = *iter; LLDrawable *drawablep = face->getDrawable(); - if (drawablep->isDead() || face->mVertexBuffer.isNull()) + if (drawablep->isDead() || face->getVertexBuffer()) { continue; } @@ -233,9 +242,10 @@ void LLDrawPoolTree::renderForSelect() LLFacePool::LLOverrideFaceColor col(this, color); - face->mVertexBuffer->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); - face->mVertexBuffer->drawRange(LLRender::TRIANGLES, 0, face->mVertexBuffer->getRequestedVerts()-1, face->mVertexBuffer->getRequestedIndices(), 0); - gPipeline.addTrianglesDrawn(face->mVertexBuffer->getRequestedIndices()/3); + LLVertexBuffer *buff = face->getVertexBuffer(); + buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); + buff->drawRange(LLRender::TRIANGLES, 0, buff->getRequestedVerts()-1, buff->getRequestedIndices(), 0); + gPipeline.addTrianglesDrawn(buff->getRequestedIndices()/3); } } } @@ -263,13 +273,13 @@ void LLDrawPoolTree::renderTree(BOOL selecting) LLFace *face = *iter; LLDrawable *drawablep = face->getDrawable(); - if (drawablep->isDead() || face->mVertexBuffer.isNull()) + if (drawablep->isDead() || !face->getVertexBuffer()) { continue; } - face->mVertexBuffer->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); - U16* indicesp = (U16*) face->mVertexBuffer->getIndicesPointer(); + face->getVertexBuffer()->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); + U16* indicesp = (U16*) face->getVertexBuffer()->getIndicesPointer(); // Render each of the trees LLVOTree *treep = (LLVOTree *)drawablep->getVObj().get(); @@ -323,15 +333,16 @@ void LLDrawPoolTree::renderTree(BOOL selecting) scale_mat *= rot_mat; + //TO-DO: Make these set-able? const F32 THRESH_ANGLE_FOR_BILLBOARD = 7.5f; //Made LoD now a little less aggressive here -Shyotl - /*const F32 BLEND_RANGE_FOR_BILLBOARD = 1.5f;*/ //Unused, really + const F32 BLEND_RANGE_FOR_BILLBOARD = 1.5f; F32 droop = treep->mDroop + 25.f*(1.f - treep->mTrunkBend.magVec()); S32 stop_depth = 0; F32 app_angle = treep->getAppAngle()*LLVOTree::sTreeFactor; F32 alpha = 1.0; - S32 trunk_LOD = 0; + S32 trunk_LOD = LLVOTree::sMAX_NUM_TREE_LOD_LEVELS; for (S32 j = 0; j < 4; j++) { @@ -342,8 +353,12 @@ void LLDrawPoolTree::renderTree(BOOL selecting) break; } } + if(trunk_LOD >= LLVOTree::sMAX_NUM_TREE_LOD_LEVELS) + { + continue ; //do not render. + } - if (app_angle < (THRESH_ANGLE_FOR_BILLBOARD/* - BLEND_RANGE_FOR_BILLBOARD*/)) + if (app_angle < (THRESH_ANGLE_FOR_BILLBOARD - BLEND_RANGE_FOR_BILLBOARD)) { // // Draw only the billboard diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 3e260f8b1..69e811905 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -55,7 +55,8 @@ #include "llviewershadermgr.h" #include "llwaterparammanager.h" -const LLUUID WATER_TEST("2bfd3884-7e27-69b9-ba3a-3e673f680004"); +const LLUUID TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004"); +const LLUUID OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055"); static float sTime; @@ -79,9 +80,11 @@ LLDrawPoolWater::LLDrawPoolWater() : mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP); - mWaterImagep = LLViewerTextureManager::getFetchedTexture(WATER_TEST); + mWaterImagep = LLViewerTextureManager::getFetchedTexture(TRANSPARENT_WATER_TEXTURE); llassert(mWaterImagep); - mWaterImagep->setNoDelete() ; + mWaterImagep->setNoDelete(); + mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(OPAQUE_WATER_TEXTURE); + llassert(mOpaqueWaterImagep); mWaterNormp = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL); mWaterNormp->setNoDelete(); @@ -169,6 +172,13 @@ void LLDrawPoolWater::render(S32 pass) } std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater()); + static const LLCachedControl render_transparent_water("RenderTransparentWater",false); + if(!render_transparent_water) + { + // render water for low end hardware + renderOpaqueLegacyWater(); + return; + } LLGLEnable blend(GL_BLEND); @@ -323,6 +333,87 @@ void LLDrawPoolWater::render(S32 pass) gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); } +// for low end hardware +void LLDrawPoolWater::renderOpaqueLegacyWater() +{ + LLVOSky *voskyp = gSky.mVOSkyp; + + stop_glerror(); + + // Depth sorting and write to depth buffer + // since this is opaque, we should see nothing + // behind the water. No blending because + // of no transparency. And no face culling so + // that the underside of the water is also opaque. + LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE); + LLGLDisable no_cull(GL_CULL_FACE); + LLGLDisable no_blend(GL_BLEND); + + gPipeline.disableLights(); + + mOpaqueWaterImagep->addTextureStats(1024.f*1024.f); + + // Activate the texture binding and bind one + // texture since all images will have the same texture + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->bind(mOpaqueWaterImagep); + + // Automatically generate texture coords for water texture + glEnable(GL_TEXTURE_GEN_S); //texture unit 0 + glEnable(GL_TEXTURE_GEN_T); //texture unit 0 + glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + + // Use the fact that we know all water faces are the same size + // to save some computation + + // Slowly move texture coordinates over time so the watter appears + // to be moving. + F32 movement_period_secs = 50.f; + + F32 offset = fmod(gFrameTimeSeconds, movement_period_secs); + + if (movement_period_secs != 0) + { + offset /= movement_period_secs; + } + else + { + offset = 0; + } + + F32 tp0[4] = { 16.f / 256.f, 0.0f, 0.0f, offset }; + F32 tp1[4] = { 0.0f, 16.f / 256.f, 0.0f, offset }; + + glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0); + glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1); + + glColor3f(1.f, 1.f, 1.f); + + for (std::vector::iterator iter = mDrawFace.begin(); + iter != mDrawFace.end(); iter++) + { + LLFace *face = *iter; + if (voskyp->isReflFace(face)) + { + continue; + } + + face->renderIndexed(); + } + + stop_glerror(); + + // Reset the settings back to expected values + glDisable(GL_TEXTURE_GEN_S); //texture unit 0 + glDisable(GL_TEXTURE_GEN_T); //texture unit 0 + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +} + + void LLDrawPoolWater::renderReflection(LLFace* face) { LLVOSky *voskyp = gSky.mVOSkyp; @@ -603,23 +694,6 @@ void LLDrawPoolWater::shade() } -void LLDrawPoolWater::renderForSelect() -{ - // Can't select water! - return; -} - - -void LLDrawPoolWater::renderFaceSelected(LLFace *facep, - LLViewerTexture *image, - const LLColor4 &color, - const S32 index_offset, const S32 index_count) -{ - // Can't select water - return; -} - - LLViewerTexture *LLDrawPoolWater::getDebugTexture() { return LLViewerFetchedTexture::sSmokeImagep; diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h index 0ce14eae3..fe579ec26 100644 --- a/indra/newview/lldrawpoolwater.h +++ b/indra/newview/lldrawpoolwater.h @@ -45,6 +45,7 @@ class LLDrawPoolWater: public LLFacePool protected: LLPointer mHBTex[2]; LLPointer mWaterImagep; + LLPointer mOpaqueWaterImagep; LLPointer mWaterNormp; public: @@ -79,16 +80,16 @@ public: /*virtual*/ S32 getNumPasses(); /*virtual*/ void render(S32 pass = 0); - /*virtual*/ void renderFaceSelected(LLFace *facep, LLViewerTexture *image, const LLColor4 &color, - const S32 index_offset = 0, const S32 index_count = 0); /*virtual*/ void prerender(); - /*virtual*/ void renderForSelect(); /*virtual*/ LLViewerTexture *getDebugTexture(); /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display void renderReflection(LLFace* face); void shade(); + +protected: + void renderOpaqueLegacyWater(); }; void cgErrorCallback(); diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 07ce6c59c..f72da554c 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -209,7 +209,7 @@ void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const &gWLCloudProgram; LLGLEnable blend(GL_BLEND); - LLGLSBlendFunc blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.setSceneBlendType(LLRender::BT_ALPHA); gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); gGL.getTexUnit(0)->bind(sCloudNoiseTexture); diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp index 9e79d93d7..8469bcda5 100644 --- a/indra/newview/lleventpoll.cpp +++ b/indra/newview/lleventpoll.cpp @@ -39,8 +39,9 @@ #include "llhttpclient.h" #include "llhttpstatuscodes.h" #include "llsdserialize.h" -#include "llsdutil.h" -#include "lltimer.h" +#include "lleventtimer.h" +#include "llsdutil.h" + #include "llviewerregion.h" #include "message.h" #include "lltrans.h" diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 186870a80..6d66cd4c3 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -228,6 +228,11 @@ void LLFace::setWorldMatrix(const LLMatrix4 &mat) llerrs << "Faces on this drawable are not independently modifiable\n" << llendl; } +void LLFace::setPool(LLFacePool* pool) +{ + mDrawPoolp = pool; +} + void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep) { LLMemType mt1(LLMemType::MTYPE_DRAWABLE); @@ -329,8 +334,13 @@ void LLFace::setDrawable(LLDrawable *drawable) mXform = &drawable->mXform; } -void LLFace::setSize(const S32 num_vertices, const S32 num_indices) +void LLFace::setSize(S32 num_vertices, const S32 num_indices, bool align) { + if (align) + { + //allocate vertices in blocks of 4 for alignment + num_vertices = (num_vertices + 0x3) & ~0x3; + } if (mGeomCount != num_vertices || mIndicesCount != num_indices) { @@ -339,6 +349,8 @@ void LLFace::setSize(const S32 num_vertices, const S32 num_indices) mVertexBuffer = NULL; mLastVertexBuffer = NULL; } + + llassert(verify()); } //============================================================================ @@ -952,6 +964,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, const U16 &index_offset) { + llassert(verify()); const LLVolumeFace &vf = volume.getVolumeFace(f); S32 num_vertices = (S32)vf.mVertices.size(); S32 num_indices = (S32)vf.mIndices.size(); @@ -1678,3 +1691,16 @@ LLViewerTexture* LLFace::getTexture() const { return mTexture ; } + +void LLFace::setVertexBuffer(LLVertexBuffer* buffer) +{ + mVertexBuffer = buffer; + llassert(verify()); +} + +void LLFace::clearVertexBuffer() +{ + mVertexBuffer = NULL; + mLastVertexBuffer = NULL; +} + diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 9825d4dc2..edbf0bafd 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -64,6 +64,17 @@ class LLFace { public: + LLFace(const LLFace& rhs) + { + *this = rhs; + } + + const LLFace& operator=(const LLFace& rhs) + { + llerrs << "Illegal operation!" << llendl; + return *this; + } + enum EMasks { LIGHT = 0x0001, @@ -124,13 +135,13 @@ public: LLDrawable* getDrawable() const { return mDrawablep; } LLViewerObject* getViewerObject() const { return mVObjp; } S32 getLOD() const { return mVObjp.notNull() ? mVObjp->getLOD() : 0; } - LLVertexBuffer* getVertexBuffer() const { return mVertexBuffer; } void setPoolType(U32 type) { mPoolType = type; } S32 getTEOffset() { return mTEOffset; } LLViewerTexture* getTexture() const; - + void setViewerObject(LLViewerObject* object); void setPool(LLFacePool *pool, LLViewerTexture *texturep); + void setPool(LLFacePool* pool); void setDrawable(LLDrawable *drawable); void setTEOffset(const S32 te_offset); @@ -167,7 +178,7 @@ public: S32 getColors(LLStrider &colors); S32 getIndices(LLStrider &indices); - void setSize(const S32 numVertices, const S32 num_indices = 0); + void setSize(S32 numVertices, const S32 num_indices = 0, bool align = false); BOOL genVolumeBBoxes(const LLVolume &volume, S32 f, const LLMatrix4& mat, const LLMatrix3& inv_trans_mat, BOOL global_volume = FALSE); @@ -196,6 +207,10 @@ public: F32 getTextureVirtualSize() ; F32 getImportanceToCamera()const {return mImportanceToCamera ;} + //vertex buffer tracking + void setVertexBuffer(LLVertexBuffer* buffer); + void clearVertexBuffer(); //sets mVertexBuffer and mLastVertexBuffer to NULL + LLVertexBuffer* getVertexBuffer() const { return mVertexBuffer; } private: F32 adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius ); @@ -211,8 +226,6 @@ public: LLVector3 mExtents[2]; LLVector2 mTexExtents[2]; F32 mDistance; - LLPointer mVertexBuffer; - LLPointer mLastVertexBuffer; F32 mLastUpdateTime; F32 mLastMoveTime; LLMatrix4* mTextureMatrix; @@ -222,6 +235,9 @@ private: friend class LLGeometryManager; friend class LLVolumeGeometryManager; + LLPointer mVertexBuffer; + LLPointer mLastVertexBuffer; + U32 mState; LLFacePool* mDrawPoolp; U32 mPoolType; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 418ea1bf0..5a6a3339d 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -81,6 +81,7 @@ static struct ft_display_info ft_display_table[] = { LLFastTimer::FTM_MESSAGES, " System Messages", &LLColor4::grey1, 1 }, { LLFastTimer::FTM_MOUSEHANDLER, " Mouse", &LLColor4::grey1, 0 }, { LLFastTimer::FTM_KEYHANDLER, " Keyboard", &LLColor4::grey1, 0 }, + { LLFastTimer::FT_STRING_FORMAT, " String Format", &LLColor4::grey3, 0 }, { LLFastTimer::FTM_SLEEP, " Sleep", &LLColor4::grey2, 0 }, { LLFastTimer::FTM_IDLE, " Idle", &blue0, 0 }, { LLFastTimer::FTM_STATEMACHINE, " State Machines", &LLColor4::yellow1, 0 }, diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 091c2b82b..ce55c7a69 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -39,7 +39,6 @@ #include "llglheaders.h" #include "llrendersphere.h" #include "llviewerobject.h" -#include "llimagegl.h" #include "llagent.h" #include "llsky.h" #include "llviewercamera.h" @@ -318,11 +317,13 @@ BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6 return FALSE; // (we are not initialized or updated) } - if (force_update) + bool visible = mVO->mDrawable->isVisible(); + + if (force_update && visible) { gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE); } - else if (mVO->mDrawable->isVisible() && + else if (visible && !mVO->mDrawable->isState(LLDrawable::IN_REBUILD_Q1) && mVO->getPixelArea() > 256.f) { @@ -365,8 +366,10 @@ void LLVolumeImplFlexible::doFlexibleUpdate() { LLVolume* volume = mVO->getVolume(); LLPath *path = &volume->getPath(); - if (mSimulateRes == 0) + if ((mSimulateRes == 0 || !mInitialized)) // if its uninitialized but not visible, what then? - Nyx { + if(!mVO->mDrawable->isVisible()) + return; //avoiding the assert below... mVO->markForUpdate(TRUE); if (!doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0)) { @@ -693,7 +696,11 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable) } volume->updateRelativeXform(); - doFlexibleUpdate(); + + if (mRenderRes > -1) + { + doFlexibleUpdate(); + } // Object may have been rotated, which means it needs a rebuild. See SL-47220 BOOL rotated = FALSE; diff --git a/indra/newview/llfloatercustomize.cpp b/indra/newview/llfloatercustomize.cpp index 96008bbdb..f2a12f984 100644 --- a/indra/newview/llfloatercustomize.cpp +++ b/indra/newview/llfloatercustomize.cpp @@ -2509,7 +2509,6 @@ void LLFloaterCustomize::initWearablePanels() panel->addSubpart("Breast Sway", SUBPART_PHYSICS_BREASTS_LEFTRIGHT, part); part = new LLSubpart(); - part->mSex = SEX_FEMALE; part->mTargetJoint = "mTorso"; part->mEditGroup = "physics_belly_updown"; part->mTargetOffset.setVec(0.f, 0.f, -.05f); diff --git a/indra/newview/llfloaterexploresounds.h b/indra/newview/llfloaterexploresounds.h index 11a181377..4bdcae820 100644 --- a/indra/newview/llfloaterexploresounds.h +++ b/indra/newview/llfloaterexploresounds.h @@ -5,6 +5,7 @@ #include "llfloater.h" #include "llaudioengine.h" +#include "lleventtimer.h" class LLFloaterExploreSounds : public LLFloater, public LLEventTimer diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp index 1d2e9142a..865e9aafc 100644 --- a/indra/newview/llfloaterfriends.cpp +++ b/indra/newview/llfloaterfriends.cpp @@ -62,7 +62,7 @@ #include "llmenucommands.h" #include "llviewercontrol.h" #include "llviewermessage.h" -#include "lltimer.h" +#include "lleventtimer.h" #include "lltextbox.h" #include "llvoiceclient.h" diff --git a/indra/newview/llfloaterfriends.h b/indra/newview/llfloaterfriends.h index e6223cfb2..acac9f590 100644 --- a/indra/newview/llfloaterfriends.h +++ b/indra/newview/llfloaterfriends.h @@ -38,7 +38,7 @@ #include "llpanel.h" #include "llstring.h" #include "lluuid.h" -#include "lltimer.h" +#include "lleventtimer.h" #include "llcallingcard.h" class LLFriendObserver; diff --git a/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp index 81a787967..2e5a4a7f5 100644 --- a/indra/newview/llfloaterhardwaresettings.cpp +++ b/indra/newview/llfloaterhardwaresettings.cpp @@ -108,7 +108,7 @@ void LLFloaterHardwareSettings::refreshEnabledState() childSetEnabled("vbo_stream", LLVertexBuffer::sEnableVBOs); } - childSetEnabled("fbo",gGLManager.mHasFramebufferObject); + childSetEnabled("fbo",gGLManager.mHasFramebufferObject && !LLPipeline::sRenderDeferred); // if no windlight shaders, turn off nighttime brightness, gamma, and fog distance childSetEnabled("gamma", !gPipeline.canUseWindLightShaders()); diff --git a/indra/newview/llfloatermessagelog.cpp b/indra/newview/llfloatermessagelog.cpp index 3ee8018ad..74241d35e 100644 --- a/indra/newview/llfloatermessagelog.cpp +++ b/indra/newview/llfloatermessagelog.cpp @@ -10,6 +10,7 @@ #include "llmessagetemplate.h" #include #include "llmenugl.h" +#include "lleventtimer.h" #include "llagent.h" diff --git a/indra/newview/llfloatermessagelog.h b/indra/newview/llfloatermessagelog.h index 104f57ebb..1fa01c5af 100644 --- a/indra/newview/llfloatermessagelog.h +++ b/indra/newview/llfloatermessagelog.h @@ -2,6 +2,7 @@ #include "llfloater.h" #include "llmessagelog.h" #include "lltemplatemessagereader.h" +#include "lleventtimer.h" class LLNetListItem { diff --git a/indra/newview/llhudobject.h b/indra/newview/llhudobject.h index 84c2f84ac..b645ae07a 100644 --- a/indra/newview/llhudobject.h +++ b/indra/newview/llhudobject.h @@ -106,7 +106,7 @@ protected: ~LLHUDObject(); virtual void render() = 0; - virtual void renderForSelect() {}; + virtual void renderForSelect() {} //Only override when needed. virtual void renderForTimer() {}; protected: diff --git a/indra/newview/llhudrender.cpp b/indra/newview/llhudrender.cpp index 62ac19671..56fb13c87 100644 --- a/indra/newview/llhudrender.cpp +++ b/indra/newview/llhudrender.cpp @@ -40,7 +40,6 @@ #include "v3math.h" #include "llquaternion.h" #include "llfontgl.h" -#include "llimagegl.h" #include "llglheaders.h" #include "llviewerwindow.h" diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 0d4bca83d..f824939ec 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -45,7 +45,6 @@ #include "llfontgl.h" #include "llglheaders.h" #include "llhudrender.h" -#include "llimagegl.h" #include "llui.h" #include "llviewercamera.h" #include "llviewertexturelist.h" diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 1cc9393d7..69de63bb2 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2000,6 +2000,23 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item) //llinfos << "LLInventoryModel::addItem()" << llendl; if(item) { + // This can happen if assettype enums from llassettype.h ever change. + // For example, there is a known backwards compatibility issue in some viewer prototypes prior to when + // the AT_LINK enum changed from 23 to 24. + if ((item->getType() == LLAssetType::AT_NONE) + || LLAssetType::lookup(item->getType()) == LLAssetType::badLookup()) + { + llwarns << "Got bad asset type for item [ name: " << item->getName() << " type: " << item->getType() << " inv-type: " << item->getInventoryType() << " ], ignoring." << llendl; + return; + } + + // This condition means that we tried to add a link without the baseobj being in memory. + // The item will show up as a broken link. + if (item->getIsBrokenLink()) + { + llinfos << "Adding broken link [ name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ) parent: " << item->getParentUUID() << llendl; + } + mItemMap[item->getUUID()] = item; } } diff --git a/indra/newview/llnotify.cpp b/indra/newview/llnotify.cpp index 9a36b6542..ffd264b6c 100644 --- a/indra/newview/llnotify.cpp +++ b/indra/newview/llnotify.cpp @@ -99,7 +99,9 @@ bool LLNotifyBox::onNotification(const LLSD& notify) if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change") { //bring existing notification to top - LLNotifyBox* boxp = LLNotifyBox::getInstance(notification->getID()); + //This getInstance is ugly, as LLNotifyBox is derived from both LLInstanceTracker and LLEventTimer, which also is derived from its own LLInstanceTracker + //Have to explicitly determine which getInstance function to use. + LLNotifyBox* boxp = LLNotifyBox::LLInstanceTracker::getInstance(notification->getID()); if (boxp && !boxp->isDead()) { gNotifyBoxView->showOnly(boxp); @@ -116,7 +118,7 @@ bool LLNotifyBox::onNotification(const LLSD& notify) } else if (notify["sigtype"].asString() == "delete") { - LLNotifyBox* boxp = LLNotifyBox::getInstance(notification->getID()); + LLNotifyBox* boxp = LLNotifyBox::LLInstanceTracker::getInstance(notification->getID()); if (boxp && !boxp->isDead()) { boxp->close(); diff --git a/indra/newview/llnotify.h b/indra/newview/llnotify.h index 15b5a7302..439cae239 100644 --- a/indra/newview/llnotify.h +++ b/indra/newview/llnotify.h @@ -35,7 +35,7 @@ #include "llfontgl.h" #include "llpanel.h" -#include "lltimer.h" +#include "lleventtimer.h" #include "llnotifications.h" #include diff --git a/indra/newview/llpaneldisplay.cpp b/indra/newview/llpaneldisplay.cpp index c8906fc53..4a684a61a 100644 --- a/indra/newview/llpaneldisplay.cpp +++ b/indra/newview/llpaneldisplay.cpp @@ -230,11 +230,10 @@ BOOL LLPanelDisplay::postBuild() //---------------------------------------------------------------------------- // Enable Reflections - mCtrlReflections = getChild("Reflections"); - mCtrlReflections->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable); - mCtrlReflections->setCallbackUserData(this); mCtrlReflectionDetail = getChild("ReflectionDetailCombo"); - + mCtrlReflectionDetail->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable); + mCtrlReflectionDetail->setCallbackUserData(this); + // WindLight mCtrlWindLight = getChild("WindLightUseAtmosShaders"); mCtrlWindLight->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable); @@ -244,9 +243,12 @@ BOOL LLPanelDisplay::postBuild() mCtrlDeferred = getChild("RenderDeferred"); mCtrlDeferred->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable); mCtrlDeferred->setCallbackUserData(this); - mCtrlSunShadow = getChild("RenderDeferredSunShadow"); - mCtrlSunShadow->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable); - mCtrlSunShadow->setCallbackUserData(this); + mCtrlDeferredGI = getChild("RenderDeferredGI"); + mCtrlDeferredGI->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable); + mCtrlDeferredGI->setCallbackUserData(this); + mCtrlShadowDetail = getChild("ShadowDetailCombo"); + mCtrlShadowDetail->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable); + mCtrlShadowDetail->setCallbackUserData(this); //---------------------------------------------------------------------------- // Enable Avatar Shaders @@ -306,6 +308,12 @@ BOOL LLPanelDisplay::postBuild() mCtrlAvatarFactor->setCommitCallback(&LLPanelDisplay::updateSliderText); mCtrlAvatarFactor->setCallbackUserData(mAvatarFactorText); + // Avatar physics detail slider + mCtrlAvatarPhysicsFactor = getChild("AvatarPhysicsDetail"); + mAvatarPhysicsFactorText = getChild("AvatarPhysicsDetailText"); + mCtrlAvatarPhysicsFactor->setCommitCallback(&LLPanelDisplay::updateSliderText); + mCtrlAvatarPhysicsFactor->setCallbackUserData(mAvatarPhysicsFactorText); + // Terrain detail slider mCtrlTerrainFactor = getChild("TerrainMeshDetail"); mTerrainFactorText = getChild("TerrainMeshDetailText"); @@ -334,6 +342,7 @@ BOOL LLPanelDisplay::postBuild() mTerrainText = getChild("TerrainDetailText"); mLightingText = getChild("LightingDetailText"); mMeshDetailText = getChild("MeshDetailText"); + mShadowDetailText = getChild("ShadowDetailText"); refresh(); @@ -397,14 +406,15 @@ void LLPanelDisplay::refresh() mBumpShiny = gSavedSettings.getBOOL("RenderObjectBump"); mShaderEnable = gSavedSettings.getBOOL("VertexShaderEnable"); mWindLight = gSavedSettings.getBOOL("WindLightUseAtmosShaders"); - mReflections = gSavedSettings.getBOOL("RenderWaterReflections"); mAvatarVP = gSavedSettings.getBOOL("RenderAvatarVP"); mDeferred = gSavedSettings.getBOOL("RenderDeferred"); - mSunShadow = gSavedSettings.getBOOL("RenderDeferredSunShadow"); + mDeferredGI = gSavedSettings.getBOOL("RenderDeferredGI"); // reflection radio mReflectionDetail = gSavedSettings.getS32("RenderReflectionDetail"); + mShadowDetail = gSavedSettings.getS32("RenderShadowDetail"); + // avatar settings mAvatarImpostors = gSavedSettings.getBOOL("RenderUseImpostors"); mAvatarCloth = gSavedSettings.getBOOL("RenderAvatarCloth"); @@ -423,7 +433,7 @@ void LLPanelDisplay::refresh() mPostProcess = gSavedSettings.getS32("RenderGlowResolutionPow"); // lighting and terrain radios - mLightingDetail = gSavedSettings.getS32("RenderLightingDetail"); + mLocalLights = gSavedSettings.getBOOL("RenderLocalLights"); mTerrainDetail = gSavedSettings.getS32("RenderTerrainDetail"); // slider text boxes @@ -431,6 +441,7 @@ void LLPanelDisplay::refresh() updateSliderText(mCtrlFlexFactor, mFlexFactorText); updateSliderText(mCtrlTreeFactor, mTreeFactorText); updateSliderText(mCtrlAvatarFactor, mAvatarFactorText); + updateSliderText(mCtrlAvatarPhysicsFactor, mAvatarPhysicsFactorText); updateSliderText(mCtrlTerrainFactor, mTerrainFactorText); updateSliderText(mCtrlPostProcess, mPostProcessText); updateSliderText(mCtrlSkyFactor, mSkyFactorText); @@ -468,13 +479,11 @@ void LLPanelDisplay::refreshEnabledState() BOOL reflections = gSavedSettings.getBOOL("VertexShaderEnable") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps; - mCtrlReflections->setEnabled(reflections); + mCtrlReflectionDetail->setEnabled(reflections); // Bump & Shiny bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump"); mCtrlBumpShiny->setEnabled(bumpshiny ? TRUE : FALSE); - - mCtrlReflectionDetail->setEnabled(mCtrlReflections->get() && reflections); // Avatar Mode S32 max_avatar_shader = LLViewerShaderMgr::instance()->mMaxAvatarShaderLevel; @@ -501,8 +510,9 @@ void LLPanelDisplay::refreshEnabledState() mCtrlDeferred->setEnabled(can_defer); - mCtrlSunShadow->setEnabled(can_defer && gSavedSettings.getBOOL("RenderDeferred")); - mCtrlAvatarCloth->setValue(gSavedSettings.getBOOL("RenderAvatarVP")); //Enabling RenderDeferred changes this setting behind this floaters back. + mCtrlShadowDetail->setEnabled(can_defer && gSavedSettings.getBOOL("RenderDeferred")); + //GI won't do anything with shadows off, but disabling it here is less than intuitive. Ignore shadow setting for now. + mCtrlDeferredGI->setEnabled(mCtrlShadowDetail->getEnabled()/* && gSavedSettings.getS32("RenderShadowDetail") > 0*/); // Vertex Shaders // mCtrlShaderEnable->setEnabled(LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable")); @@ -551,8 +561,8 @@ void LLPanelDisplay::disableUnavailableSettings() mCtrlWindLight->setEnabled(FALSE); mCtrlWindLight->setValue(FALSE); - mCtrlReflections->setEnabled(FALSE); - mCtrlReflections->setValue(FALSE); + mCtrlReflectionDetail->setEnabled(FALSE); + mCtrlReflectionDetail->setValue(FALSE); mCtrlAvatarVP->setEnabled(FALSE); mCtrlAvatarVP->setValue(FALSE); @@ -562,8 +572,10 @@ void LLPanelDisplay::disableUnavailableSettings() mCtrlDeferred->setEnabled(FALSE); mCtrlDeferred->setValue(FALSE); - mCtrlSunShadow->setEnabled(FALSE); - mCtrlSunShadow->setValue(FALSE); + mCtrlDeferredGI->setEnabled(FALSE); + mCtrlDeferredGI->setValue(FALSE); + mCtrlShadowDetail->setEnabled(FALSE); + mCtrlShadowDetail->setValue(FALSE); } // disabled windlight @@ -574,10 +586,10 @@ void LLPanelDisplay::disableUnavailableSettings() } // disabled reflections - if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderWaterReflections")) + if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionDetail")) { - mCtrlReflections->setEnabled(FALSE); - mCtrlReflections->setValue(FALSE); + mCtrlReflectionDetail->setEnabled(FALSE); + mCtrlReflectionDetail->setValue(FALSE); } // disabled av @@ -606,8 +618,10 @@ void LLPanelDisplay::disableUnavailableSettings() { mCtrlDeferred->setEnabled(FALSE); mCtrlDeferred->setValue(FALSE); - mCtrlSunShadow->setEnabled(FALSE); - mCtrlSunShadow->setValue(FALSE); + mCtrlDeferredGI->setEnabled(FALSE); + mCtrlDeferredGI->setValue(FALSE); + mCtrlShadowDetail->setEnabled(FALSE); + mCtrlShadowDetail->setValue(FALSE); } } @@ -669,6 +683,7 @@ void LLPanelDisplay::setHiddenGraphicsState(bool isHidden) mCtrlFlexFactor->setVisible(!isHidden); mCtrlTreeFactor->setVisible(!isHidden); mCtrlAvatarFactor->setVisible(!isHidden); + mCtrlAvatarPhysicsFactor->setVisible(!isHidden); mCtrlTerrainFactor->setVisible(!isHidden); mCtrlSkyFactor->setVisible(!isHidden); mCtrlMaxParticle->setVisible(!isHidden); @@ -678,12 +693,12 @@ void LLPanelDisplay::setHiddenGraphicsState(bool isHidden) mFlexFactorText->setVisible(!isHidden); mTreeFactorText->setVisible(!isHidden); mAvatarFactorText->setVisible(!isHidden); + mAvatarPhysicsFactorText->setVisible(!isHidden); mTerrainFactorText->setVisible(!isHidden); mSkyFactorText->setVisible(!isHidden); mPostProcessText->setVisible(!isHidden); mCtrlBumpShiny->setVisible(!isHidden); - mCtrlReflections->setVisible(!isHidden); mCtrlWindLight->setVisible(!isHidden); mCtrlAvatarVP->setVisible(!isHidden); mCtrlShaderEnable->setVisible(!isHidden); @@ -695,7 +710,8 @@ void LLPanelDisplay::setHiddenGraphicsState(bool isHidden) mCtrlReflectionDetail->setVisible(!isHidden); mCtrlDeferred->setVisible(!isHidden); - mCtrlSunShadow->setVisible(!isHidden); + mCtrlDeferredGI->setVisible(!isHidden); + mCtrlShadowDetail->setVisible(!isHidden); // text boxes mShaderText->setVisible(!isHidden); @@ -705,6 +721,7 @@ void LLPanelDisplay::setHiddenGraphicsState(bool isHidden) mTerrainText->setVisible(!isHidden); mDrawDistanceMeterText1->setVisible(!isHidden); mDrawDistanceMeterText2->setVisible(!isHidden); + mShadowDetailText->setVisible(!isHidden); // hide one meter text if we're making things visible if(!isHidden) @@ -727,17 +744,18 @@ void LLPanelDisplay::cancel() gSavedSettings.setBOOL("RenderObjectBump", mBumpShiny); gSavedSettings.setBOOL("VertexShaderEnable", mShaderEnable); gSavedSettings.setBOOL("WindLightUseAtmosShaders", mWindLight); - gSavedSettings.setBOOL("RenderWaterReflections", mReflections); + gSavedSettings.setBOOL("RenderAvatarVP", mAvatarVP); gSavedSettings.setBOOL("RenderDeferred", mDeferred); - gSavedSettings.setBOOL("RenderDeferredSunShadow", mSunShadow); + gSavedSettings.setBOOL("RenderDeferredGI", mDeferredGI); gSavedSettings.setS32("RenderReflectionDetail", mReflectionDetail); + gSavedSettings.setS32("RenderShadowDetail", mShadowDetail); gSavedSettings.setBOOL("RenderUseImpostors", mAvatarImpostors); gSavedSettings.setBOOL("RenderAvatarCloth", mAvatarCloth); - gSavedSettings.setS32("RenderLightingDetail", mLightingDetail); + gSavedSettings.setBOOL("RenderLocalLights", mLocalLights); gSavedSettings.setS32("RenderTerrainDetail", mTerrainDetail); gSavedSettings.setF32("RenderFarClip", mRenderFarClip); @@ -990,6 +1008,13 @@ void LLPanelDisplay::updateSliderText(LLUICtrl* ctrl, void* user_data) return; } + //Hack to display 'Off' for avatar physics slider. + if(slider->getName() == "AvatarPhysicsDetail" && !slider->getValueF32()) + { + text_box->setText(std::string("Off")); + return; + } + // get range and points when text should change F32 range = slider->getMaxValue() - slider->getMinValue(); llassert(range > 0); @@ -1005,10 +1030,14 @@ void LLPanelDisplay::updateSliderText(LLUICtrl* ctrl, void* user_data) { text_box->setText(std::string("Mid")); } - else + else if(slider->getValueF32() < slider->getMaxValue()) { text_box->setText(std::string("High")); } + else + { + text_box->setText(std::string("Max")); + } } void LLPanelDisplay::updateMeterText(LLUICtrl* ctrl, void* user_data) diff --git a/indra/newview/llpaneldisplay.h b/indra/newview/llpaneldisplay.h index 677f1086c..a36311390 100644 --- a/indra/newview/llpaneldisplay.h +++ b/indra/newview/llpaneldisplay.h @@ -101,18 +101,19 @@ protected: LLSliderCtrl *mCtrlFlexFactor; // Timeslice for flexible objects LLSliderCtrl *mCtrlTreeFactor; // Control tree cutoff distance LLSliderCtrl *mCtrlAvatarFactor; // LOD for avatars + LLSliderCtrl *mCtrlAvatarPhysicsFactor; // Physics LOD for avatars LLSliderCtrl *mCtrlTerrainFactor; // LOD for terrain LLSliderCtrl *mCtrlSkyFactor; // LOD for terrain LLSliderCtrl *mCtrlMaxParticle; // Max Particle LLSliderCtrl *mCtrlPostProcess; // Max Particle LLCheckBoxCtrl *mCtrlBumpShiny; - LLCheckBoxCtrl *mCtrlReflections; LLCheckBoxCtrl *mCtrlWindLight; LLCheckBoxCtrl *mCtrlAvatarVP; LLCheckBoxCtrl *mCtrlShaderEnable; LLCheckBoxCtrl *mCtrlDeferred; - LLCheckBoxCtrl *mCtrlSunShadow; + LLCheckBoxCtrl *mCtrlDeferredGI; + LLComboBox *mCtrlShadowDetail; LLCheckBoxCtrl *mCtrlAvatarImpostors; LLCheckBoxCtrl *mCtrlAvatarCloth; LLRadioGroup *mRadioLightingDetail2; @@ -136,9 +137,11 @@ protected: LLTextBox *mFlexFactorText; LLTextBox *mTreeFactorText; LLTextBox *mAvatarFactorText; + LLTextBox *mAvatarPhysicsFactorText; LLTextBox *mTerrainFactorText; LLTextBox *mSkyFactorText; LLTextBox *mPostProcessText; + LLTextBox *mShadowDetailText; BOOL mFSAutoDetectAspect; F32 mAspectRatio; @@ -151,17 +154,17 @@ protected: BOOL mBumpShiny; BOOL mShaderEnable; BOOL mWindLight; - BOOL mReflections; BOOL mDeferred; - BOOL mSunShadow; + BOOL mDeferredGI; BOOL mAvatarVP; S32 mReflectionDetail; + S32 mShadowDetail; BOOL mAvatarImpostors; BOOL mAvatarCloth; S32 mAvatarMode; - S32 mLightingDetail; + BOOL mLocalLights; S32 mTerrainDetail; F32 mRenderFarClip; diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index d69ebd0b2..581043951 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -496,7 +496,9 @@ BOOL LLPhysicsMotionController::onUpdate(F32 time, U8* joint_mask) { // Skip if disabled globally. static const LLCachedControl avatar_physics("AvatarPhysics",false); - if (!avatar_physics || (!((LLVOAvatar*)mCharacter)->isSelf() && !((LLVOAvatar*)mCharacter)->mSupportsPhysics)) + bool supports_physics = !avatar_physics || (!((LLVOAvatar*)mCharacter)->isSelf() && !((LLVOAvatar*)mCharacter)->mSupportsPhysics); + //Treat lod 0 as AvatarPhyiscs:FALSE. AvatarPhyiscs setting is superfluous unless we decide to hook it into param sending. + if (supports_physics || !LLVOAvatar::sPhysicsLODFactor) { if(!mIsDefault) { @@ -507,6 +509,7 @@ BOOL LLPhysicsMotionController::onUpdate(F32 time, U8* joint_mask) } mCharacter->updateVisualParams(); } + if(!supports_physics) //Only use emerald physics if avatarphysiscs is really off, or the client doesn't seem to support new physics. ((LLVOAvatar*)mCharacter)->idleUpdateBoobEffect(); //Fall back to emerald physics return TRUE; } diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index aa03a6c2e..f4390927d 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -40,7 +40,7 @@ #include "llcombobox.h" #include "lliconctrl.h" #include "llframetimer.h" -#include "lltimer.h" +#include "lleventtimer.h" class LLMessageSystem; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index bbfd90177..0ca376345 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -4917,13 +4917,13 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) // set up transform to encompass bounding box of HUD glMatrixMode(GL_PROJECTION); - glPushMatrix(); + gGL.pushMatrix(); glLoadIdentity(); F32 depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f); glOrtho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, depth); glMatrixMode(GL_MODELVIEW); - glPushMatrix(); + gGL.pushMatrix(); glLoadIdentity(); glLoadMatrixf(OGL_TO_CFR_ROTATION); // Load Cory's favorite reference frame glTranslatef(-hud_bbox.getCenterLocal().mV[VX] + (depth *0.5f), 0.f, 0.f); @@ -5007,10 +5007,10 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) if (isAgentAvatarValid() && for_hud) { glMatrixMode(GL_PROJECTION); - glPopMatrix(); + gGL.popMatrix(); glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + gGL.popMatrix(); stop_glerror(); } @@ -5349,7 +5349,7 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) } glMatrixMode(GL_MODELVIEW); - glPushMatrix(); + gGL.pushMatrix(); if (!is_hud_object) { glLoadIdentity(); @@ -5468,7 +5468,7 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) gGL.end(); gGL.flush(); } - glPopMatrix(); + gGL.popMatrix(); } // diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index b9b9adafb..9546e3b04 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -392,7 +392,7 @@ void LLSpatialGroup::checkStates() void validate_draw_info(LLDrawInfo& params) { #if LL_OCTREE_PARANOIA_CHECK - if (params.mVertexBuffer.isNull()) + if (!params.mVertexBuffer) { llerrs << "Draw batch has no vertex buffer." << llendl; } @@ -1309,8 +1309,7 @@ void LLSpatialGroup::destroyGL() for (S32 j = 0; j < drawable->getNumFaces(); j++) { LLFace* facep = drawable->getFace(j); - facep->mVertexBuffer = NULL; - facep->mLastVertexBuffer = NULL; + facep->clearVertexBuffer(); } } } @@ -1519,7 +1518,6 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mSlopRatio = 0.25f; mInfiniteFarClip = FALSE; - LLGLNamePool::registerPool(&sQueryPool); mOctree = new LLSpatialGroup::OctreeRoot(LLVector3d(0,0,0), LLVector3d(1,1,1), @@ -1934,6 +1932,8 @@ public: void drawBox(const LLVector3& c, const LLVector3& r) { + LLVertexBuffer::unbind(); + gGL.begin(LLRender::TRIANGLE_STRIP); //left front gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV); @@ -2179,7 +2179,7 @@ void pushVerts(LLSpatialGroup* group, U32 mask) void pushVerts(LLFace* face, U32 mask) { - LLVertexBuffer* buffer = face->mVertexBuffer; + LLVertexBuffer* buffer = face->getVertexBuffer(); if (buffer) { @@ -2309,7 +2309,7 @@ void renderOctree(LLSpatialGroup* group) for (S32 j = 0; j < drawable->getNumFaces(); j++) { LLFace* face = drawable->getFace(j); - if (face->mVertexBuffer.notNull()) + if (face->getVertexBuffer()) { if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f) { @@ -2324,10 +2324,10 @@ void renderOctree(LLSpatialGroup* group) continue; } - face->mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX); + face->getVertexBuffer()->setBuffer(LLVertexBuffer::MAP_VERTEX); //drawBox((face->mExtents[0] + face->mExtents[1])*0.5f, // (face->mExtents[1]-face->mExtents[0])*0.5f); - face->mVertexBuffer->draw(LLRender::TRIANGLES, face->getIndicesCount(), face->getIndicesStart()); + face->getVertexBuffer()->draw(LLRender::TRIANGLES, face->getIndicesCount(), face->getIndicesStart()); } } diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index abf58a79b..093a13d78 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -295,6 +295,13 @@ public: virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child); virtual void handleChildRemoval(const OctreeNode* parent, const OctreeNode* child); + LLVector3 mBounds[2]; + LLVector3 mExtents[2]; + + LLVector3 mObjectExtents[2]; + LLVector3 mObjectBounds[2]; + LLVector3 mViewAngle; + LLVector3 mLastUpdateViewAngle; protected: virtual ~LLSpatialGroup(); @@ -310,11 +317,6 @@ public: F32 mBuilt; OctreeNode* mOctreeNode; LLSpatialPartition* mSpatialPartition; - LLVector3 mBounds[2]; - LLVector3 mExtents[2]; - - LLVector3 mObjectExtents[2]; - LLVector3 mObjectBounds[2]; LLPointer mVertexBuffer; F32* mOcclusionVerts; @@ -328,9 +330,6 @@ public: F32 mDepth; F32 mLastUpdateDistance; F32 mLastUpdateTime; - - LLVector3 mViewAngle; - LLVector3 mLastUpdateViewAngle; F32 mPixelArea; F32 mRadius; @@ -466,6 +465,7 @@ public: sg_list_t::iterator beginAlphaGroups(); sg_list_t::iterator endAlphaGroups(); + bool hasOcclusionGroups() { return mOcclusionGroupsSize > 0; } sg_list_t::iterator beginOcclusionGroups(); sg_list_t::iterator endOcclusionGroups(); diff --git a/indra/newview/llsprite.cpp b/indra/newview/llsprite.cpp index dce4e9d14..45d7165ca 100644 --- a/indra/newview/llsprite.cpp +++ b/indra/newview/llsprite.cpp @@ -192,14 +192,15 @@ void LLSprite::updateFace(LLFace &face) U16 index_offset; // Setup face - if (face.mVertexBuffer.isNull()) + if (!face.getVertexBuffer()) { - face.mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer* buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, GL_STREAM_DRAW_ARB); - face.mVertexBuffer->allocateBuffer(4, 12, TRUE); + buff->allocateBuffer(4, 12, TRUE); face.setGeomIndex(0); face.setIndicesIndex(0); + face.setVertexBuffer(buff); } index_offset = face.getGeometry(verticesp,normalsp,tex_coordsp, indicesp); @@ -248,7 +249,7 @@ void LLSprite::updateFace(LLFace &face) *indicesp++ = 3 + index_offset; } - face.mVertexBuffer->setBuffer(0); + face.getVertexBuffer()->setBuffer(0); face.mCenterAgent = mPosition; } diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index 260c6e253..022f7bc59 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -729,6 +729,10 @@ LLVector3 LLViewerCamera::roundToPixel(const LLVector3 &pos_agent) BOOL LLViewerCamera::cameraUnderWater() const { + if(!gAgent.getRegion()) + { + return FALSE ; + } return getOrigin().mV[VZ] < gAgent.getRegion()->getWaterHeight(); } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 47758492f..410dcc004 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -192,6 +192,12 @@ static bool handleSetSelfInvisible( const LLSD& newvalue) return true; } +bool handleRenderTransparentWaterChanged(const LLSD& newvalue) +{ + LLWorld::getInstance()->updateWaterObjects(); + return true; +} + static bool handleReleaseGLBufferChanged(const LLSD& newvalue) { if (gPipeline.isInit()) @@ -406,15 +412,6 @@ static bool handleWLSkyDetailChanged(const LLSD&) return true; } -static bool handleRenderLightingDetailChanged(const LLSD& newvalue) -{ - if (gPipeline.isInit()) - { - gPipeline.setLightingDetail(newvalue.asInteger()); - } - return true; -} - static bool handleResetVertexBuffersChanged(const LLSD&) { if (gPipeline.isInit()) @@ -430,6 +427,12 @@ static bool handleRenderDynamicLODChanged(const LLSD& newvalue) return true; } +static bool handleRenderLocalLightsChanged(const LLSD& newvalue) +{ + gPipeline.setLightingDetail(-1); + return true; +} + static bool handleRenderUseFBOChanged(const LLSD& newvalue) { LLRenderTarget::sUseFBO = newvalue.asBoolean(); @@ -588,8 +591,12 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderAnimateTrees")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _1)); gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); gSavedSettings.getControl("VertexShaderEnable")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); + gSavedSettings.getControl("RenderSpecularResX")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1)); + gSavedSettings.getControl("RenderSpecularResY")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1)); + gSavedSettings.getControl("RenderSpecularExponent")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1)); gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1)); gSavedSettings.getControl("RenderAnisotropic")->getSignal()->connect(boost::bind(&handleAnisotropicChanged, _1)); + gSavedSettings.getControl("RenderShadowResolutionScale")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1)); gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1)); gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); gSavedSettings.getControl("EnableRippleWater")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); @@ -601,22 +608,16 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderAvatarInvisible")->getSignal()->connect(boost::bind(&handleSetSelfInvisible, _1)); gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _1)); gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _1)); + gSavedSettings.getControl("RenderAvatarPhysicsLODFactor")->getSignal()->connect(boost::bind(&handleAvatarPhysicsLODChanged, _1)); gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _1)); gSavedSettings.getControl("RenderTreeLODFactor")->getSignal()->connect(boost::bind(&handleTreeLODChanged, _1)); - gSavedSettings.getControl("RenderAvatarPhysicsLODFactor")->getSignal()->connect(boost::bind(&handleAvatarPhysicsLODChanged, _1)); gSavedSettings.getControl("RenderFlexTimeFactor")->getSignal()->connect(boost::bind(&handleFlexLODChanged, _1)); gSavedSettings.getControl("ThrottleBandwidthKBPS")->getSignal()->connect(boost::bind(&handleBandwidthChanged, _1)); gSavedSettings.getControl("RenderGamma")->getSignal()->connect(boost::bind(&handleGammaChanged, _1)); - gSavedSettings.getControl("EmeraldBoobMass")->getSignal()->connect(boost::bind(&handleAvatarBoobMassChanged, _1)); - gSavedSettings.getControl("EmeraldBoobHardness")->getSignal()->connect(boost::bind(&handleAvatarBoobHardnessChanged, _1)); - gSavedSettings.getControl("EmeraldBoobVelMax")->getSignal()->connect(boost::bind(&handleAvatarBoobVelMaxChanged, _1)); - gSavedSettings.getControl("EmeraldBoobFriction")->getSignal()->connect(boost::bind(&handleAvatarBoobFrictionChanged, _1)); - gSavedSettings.getControl("EmeraldBoobVelMin")->getSignal()->connect(boost::bind(&handleAvatarBoobVelMinChanged, _1)); - gSavedSettings.getControl("EmeraldBreastPhysicsToggle")->getSignal()->connect(boost::bind(&handleAvatarBoobToggleChanged, _1)); - gSavedSettings.getControl("EmeraldBoobXYInfluence")->getSignal()->connect(boost::bind(&handleAvatarBoobXYInfluence, _1)); gSavedSettings.getControl("RenderFogRatio")->getSignal()->connect(boost::bind(&handleFogRatioChanged, _1)); gSavedSettings.getControl("RenderMaxPartCount")->getSignal()->connect(boost::bind(&handleMaxPartCountChanged, _1)); gSavedSettings.getControl("RenderDynamicLOD")->getSignal()->connect(boost::bind(&handleRenderDynamicLODChanged, _1)); + gSavedSettings.getControl("RenderLocalLights")->getSignal()->connect(boost::bind(&handleRenderLocalLightsChanged, _1)); gSavedSettings.getControl("RenderDebugTextureBind")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _1)); gSavedSettings.getControl("RenderFastAlpha")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _1)); gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _1)); @@ -631,7 +632,11 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _1)); gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _1)); gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); + gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); + gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); + gSavedSettings.getControl("RenderDeferredGI")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _1)); + gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _1)); gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _1)); gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _1)); gSavedSettings.getControl("UploadBakedTexOld")->getSignal()->connect(boost::bind(&handleUploadBakedTexOldChanged, _1)); @@ -646,7 +651,6 @@ void settings_setup_listeners() gSavedSettings.getControl("AudioLevelDoppler")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("AudioLevelRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("AudioStreamingMusic")->getSignal()->connect(boost::bind(&handleAudioStreamMusicChanged, _1)); - gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _1)); gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("MuteMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("MuteMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); @@ -655,8 +659,8 @@ void settings_setup_listeners() gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleRenderUseVBOChanged, _1)); gSavedSettings.getControl("RenderVBOMappingDisable")->getSignal()->connect(boost::bind(&handleRenderUseVBOMappingChanged, _1)); + gSavedSettings.getControl("RenderPreferStreamDraw")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _1)); gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _1)); - gSavedSettings.getControl("RenderLightingDetail")->getSignal()->connect(boost::bind(&handleRenderLightingDetailChanged, _1)); gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _1)); gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1)); gSavedSettings.getControl("JoystickAxis1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1)); @@ -725,7 +729,16 @@ void settings_setup_listeners() gSavedSettings.getControl("CloudsEnabled")->getSignal()->connect(boost::bind(&handleCloudSettingsChanged, _1)); gSavedSettings.getControl("SkyUseClassicClouds")->getSignal()->connect(boost::bind(&handleCloudSettingsChanged, _1)); + gSavedSettings.getControl("RenderTransparentWater")->getSignal()->connect(boost::bind(&handleRenderTransparentWaterChanged, _1)); + gSavedSettings.getControl("EmeraldBoobMass")->getSignal()->connect(boost::bind(&handleAvatarBoobMassChanged, _1)); + gSavedSettings.getControl("EmeraldBoobHardness")->getSignal()->connect(boost::bind(&handleAvatarBoobHardnessChanged, _1)); + gSavedSettings.getControl("EmeraldBoobVelMax")->getSignal()->connect(boost::bind(&handleAvatarBoobVelMaxChanged, _1)); + gSavedSettings.getControl("EmeraldBoobFriction")->getSignal()->connect(boost::bind(&handleAvatarBoobFrictionChanged, _1)); + gSavedSettings.getControl("EmeraldBoobVelMin")->getSignal()->connect(boost::bind(&handleAvatarBoobVelMinChanged, _1)); + gSavedSettings.getControl("EmeraldBreastPhysicsToggle")->getSignal()->connect(boost::bind(&handleAvatarBoobToggleChanged, _1)); + gSavedSettings.getControl("EmeraldBoobXYInfluence")->getSignal()->connect(boost::bind(&handleAvatarBoobXYInfluence, _1)); + gSavedSettings.getControl("AscentUseTag")->getSignal()->connect(boost::bind(&handleAscentSelfTag,_1)); gSavedSettings.getControl("AscentUseCustomTag")->getSignal()->connect(boost::bind(&handleAscentSelfTag,_1)); gSavedSettings.getControl("AscentCustomTagColor")->getSignal()->connect(boost::bind(&handleAscentSelfTag,_1)); @@ -854,7 +867,7 @@ static LLCachedControl test_BrowserHomePage("BrowserHomePage", "hah void test_cached_control() { -#define TEST_LLCC(T, V) if((T)mySetting_##T != V) llerrs << "Fail "#T << llendl +#define do { TEST_LLCC(T, V) if((T)mySetting_##T != V) llerrs << "Fail "#T << llendl; } while(0) TEST_LLCC(U32, 666); TEST_LLCC(S32, (S32)-666); TEST_LLCC(F32, (F32)-666.666); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index ab8dc18f8..29d201a22 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -655,7 +655,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo LLPipeline::sFastAlpha = gSavedSettings.getBOOL("RenderFastAlpha"); LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip"); - LLVOAvatar::sMaxVisible = gSavedSettings.getS32("RenderAvatarMaxVisible"); + LLVOAvatar::sMaxVisible = (U32)gSavedSettings.getS32("RenderAvatarMaxVisible"); LLPipeline::sDelayVBUpdate = gSavedSettings.getBOOL("RenderDelayVBUpdate"); S32 occlusion = LLPipeline::sUseOcclusion; @@ -784,7 +784,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo { LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; gFrameStats.start(LLFrameStats::STATE_SORT); - gPipeline.sAllowRebuildPriorityGroup = TRUE ; gPipeline.stateSort(*LLViewerCamera::getInstance(), result); stop_glerror(); @@ -904,6 +903,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo for (U32 i = 0; i < 16; i++) { gGLLastModelView[i] = gGLModelView[i]; + gGLLastProjection[i] = gGLProjection[i]; } stop_glerror(); } @@ -1338,7 +1338,7 @@ void render_ui_2d() // render outline for HUD if (gAgent.getAvatarObject() && gAgent.mHUDCurZoom < 0.98f) { - glPushMatrix(); + gGL.pushMatrix(); S32 half_width = (gViewerWindow->getWindowWidth() / 2); S32 half_height = (gViewerWindow->getWindowHeight() / 2); glScalef(LLUI::sGLScaleFactor.mV[0], LLUI::sGLScaleFactor.mV[1], 1.f); @@ -1347,7 +1347,7 @@ void render_ui_2d() glScalef(zoom,zoom,1.f); gGL.color4fv(LLColor4::white.mV); gl_rect_2d(-half_width, half_height, half_width, -half_height, FALSE); - glPopMatrix(); + gGL.popMatrix(); stop_glerror(); } gViewerWindow->draw(); diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index 055e488ff..926a9f9c7 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -509,7 +509,7 @@ int compare_int(const void *a, const void *b) U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) { if (!mValid || !mMesh || !mFace || !mVisible || - mFace->mVertexBuffer.isNull() || + !mFace->getVertexBuffer() || mMesh->getNumFaces() == 0) { return 0; @@ -599,7 +599,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) } } - mFace->mVertexBuffer->setBuffer(sRenderMask); + mFace->getVertexBuffer()->setBuffer(sRenderMask); U32 start = mMesh->mFaceVertexOffset; U32 end = start + mMesh->mFaceVertexCount - 1; @@ -616,14 +616,14 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) } } - mFace->mVertexBuffer->drawRange(LLRender::TRIANGLES, start, end, count, offset); + mFace->getVertexBuffer()->drawRange(LLRender::TRIANGLES, start, end, count, offset); } else { glPushMatrix(); LLMatrix4 jointToWorld = getWorldMatrix(); glMultMatrixf((GLfloat*)jointToWorld.mMatrix); - mFace->mVertexBuffer->drawRange(LLRender::TRIANGLES, start, end, count, offset); + mFace->getVertexBuffer()->drawRange(LLRender::TRIANGLES, start, end, count, offset); glPopMatrix(); } gPipeline.addTrianglesDrawn(count/3); @@ -672,7 +672,7 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w { mFace = face; - if (mFace->mVertexBuffer.isNull()) + if (!mFace->getVertexBuffer()) { return; } @@ -692,7 +692,7 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w stop_glerror(); face->getGeometryAvatar(verticesp, normalsp, tex_coordsp, vertex_weightsp, clothing_weightsp); stop_glerror(); - face->mVertexBuffer->getIndexStrider(indicesp); + face->getVertexBuffer()->getIndexStrider(indicesp); stop_glerror(); verticesp += mMesh->mFaceVertexOffset; @@ -809,7 +809,7 @@ void LLViewerJointMesh::updateGeometryOriginal(LLFace *mFace, LLPolyMesh *mMesh) LLStrider o_normals; //get vertex and normal striders - LLVertexBuffer *buffer = mFace->mVertexBuffer; + LLVertexBuffer *buffer = mFace->getVertexBuffer(); buffer->getVertexStrider(o_vertices, 0); buffer->getNormalStrider(o_normals, 0); @@ -966,7 +966,7 @@ void LLViewerJointMesh::updateJointGeometry() && mMesh && mFace && mMesh->hasWeights() - && mFace->mVertexBuffer.notNull() + && mFace->getVertexBuffer() && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) == 0)) { return; diff --git a/indra/newview/llviewerjointmesh_sse.cpp b/indra/newview/llviewerjointmesh_sse.cpp index f4056e1af..2f2635246 100644 --- a/indra/newview/llviewerjointmesh_sse.cpp +++ b/indra/newview/llviewerjointmesh_sse.cpp @@ -89,7 +89,7 @@ void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh) LLStrider o_vertices; LLStrider o_normals; - LLVertexBuffer *buffer = face->mVertexBuffer; + LLVertexBuffer *buffer = face->getVertexBuffer(); buffer->getVertexStrider(o_vertices, mesh->mFaceVertexOffset); buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset); diff --git a/indra/newview/llviewerjointmesh_sse2.cpp b/indra/newview/llviewerjointmesh_sse2.cpp index ac9d18778..bfd8bb69b 100644 --- a/indra/newview/llviewerjointmesh_sse2.cpp +++ b/indra/newview/llviewerjointmesh_sse2.cpp @@ -96,7 +96,7 @@ void LLViewerJointMesh::updateGeometrySSE2(LLFace *face, LLPolyMesh *mesh) LLStrider o_vertices; LLStrider o_normals; - LLVertexBuffer *buffer = face->mVertexBuffer; + LLVertexBuffer *buffer = face->getVertexBuffer(); buffer->getVertexStrider(o_vertices, mesh->mFaceVertexOffset); buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset); diff --git a/indra/newview/llviewerjointmesh_vec.cpp b/indra/newview/llviewerjointmesh_vec.cpp index 8fb9d1cf6..91b97b07d 100644 --- a/indra/newview/llviewerjointmesh_vec.cpp +++ b/indra/newview/llviewerjointmesh_vec.cpp @@ -79,7 +79,7 @@ void LLViewerJointMesh::updateGeometryVectorized(LLFace *face, LLPolyMesh *mesh) LLStrider o_vertices; LLStrider o_normals; - LLVertexBuffer *buffer = face->mVertexBuffer; + LLVertexBuffer *buffer = face->getVertexBuffer(); buffer->getVertexStrider(o_vertices, mesh->mFaceVertexOffset); buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index afff999fa..20ec61705 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -3752,29 +3752,6 @@ void handle_fake_away_status(void*) } } -void handle_hide_typing_notification(void*) -{ - if (!gSavedSettings.controlExists("HideTypingNotification")) - gSavedSettings.declareBOOL("HideTypingNotification", FALSE, "Hide your 'Name is typing...' message when Instant Messaging."); - - BOOL hide = gSavedSettings.getBOOL("HideTypingNotification"); - if (hide) - { - gSavedSettings.declareBOOL("HideTypingNotification", FALSE, "Hide your 'Name is typing...' message when Instant Messaging."); - gSavedSettings.setBOOL("HideTypingNotification", FALSE); - } - else - { - gSavedSettings.declareBOOL("HideTypingNotification", TRUE, "Hide your 'Name is typing...' message when Instant Messaging."); - gSavedSettings.setBOOL("HideTypingNotification", TRUE); - } - - LLChat chat; - chat.mSourceType = CHAT_SOURCE_SYSTEM; - chat.mText = llformat("IM Typing Notifications: %s",(hide ? "On" : "Off")); - LLFloaterChat::addChat(chat); -} - void handle_force_ground_sit(void*) { if (gAgent.getAvatarObject()) diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index e99b20306..e341631a8 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -63,7 +63,7 @@ #include "llxfermanager.h" #include "message.h" #include "sound_ids.h" -#include "lltimer.h" +#include "lleventtimer.h" #include "llmd5.h" #include "llagent.h" diff --git a/indra/newview/llviewerparcelmediaautoplay.h b/indra/newview/llviewerparcelmediaautoplay.h index 16279e7f1..243da2f38 100644 --- a/indra/newview/llviewerparcelmediaautoplay.h +++ b/indra/newview/llviewerparcelmediaautoplay.h @@ -33,7 +33,7 @@ #ifndef LLVIEWERPARCELMEDIAAUTOPLAY_H #define LLVIEWERPARCELMEDIAAUTOPLAY_H -#include "lltimer.h" +#include "lleventtimer.h" // timer to automatically play media class LLViewerParcelMediaAutoPlay : LLEventTimer diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 00d89e45d..50a57d827 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -79,6 +79,7 @@ LLGLSLShader gObjectFullbrightProgram(LLViewerShaderMgr::SHADER_OBJECT); LLGLSLShader gObjectFullbrightWaterProgram(LLViewerShaderMgr::SHADER_OBJECT); LLGLSLShader gObjectFullbrightShinyProgram(LLViewerShaderMgr::SHADER_OBJECT); +LLGLSLShader gObjectFullbrightShinyWaterProgram(LLViewerShaderMgr::SHADER_OBJECT); LLGLSLShader gObjectShinyProgram(LLViewerShaderMgr::SHADER_OBJECT); LLGLSLShader gObjectShinyWaterProgram(LLViewerShaderMgr::SHADER_OBJECT); @@ -106,6 +107,7 @@ LLGLSLShader gPostGaussianBlurProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not // Deferred rendering shaders LLGLSLShader gDeferredImpostorProgram(LLViewerShaderMgr::SHADER_DEFERRED); +LLGLSLShader gDeferredEdgeProgram(LLViewerShaderMgr::SHADER_DEFERRED); LLGLSLShader gDeferredWaterProgram(LLViewerShaderMgr::SHADER_DEFERRED); //calculatesAtmospherics LLGLSLShader gDeferredDiffuseProgram(LLViewerShaderMgr::SHADER_DEFERRED);//Not in mShaderList LLGLSLShader gDeferredBumpProgram(LLViewerShaderMgr::SHADER_DEFERRED); //Not in mShaderList @@ -115,14 +117,21 @@ LLGLSLShader gDeferredAvatarProgram(LLViewerShaderMgr::SHADER_DEFERRED); //Not LLGLSLShader gDeferredAvatarAlphaProgram(LLViewerShaderMgr::SHADER_DEFERRED); //calculatesAtmospherics LLGLSLShader gDeferredLightProgram(LLViewerShaderMgr::SHADER_DEFERRED); LLGLSLShader gDeferredMultiLightProgram(LLViewerShaderMgr::SHADER_DEFERRED); +LLGLSLShader gDeferredSpotLightProgram(LLViewerShaderMgr::SHADER_DEFERRED); //Not in mShaderList +LLGLSLShader gDeferredMultiSpotLightProgram(LLViewerShaderMgr::SHADER_DEFERRED); //Not in mShaderList LLGLSLShader gDeferredSunProgram(LLViewerShaderMgr::SHADER_DEFERRED); LLGLSLShader gDeferredBlurLightProgram(LLViewerShaderMgr::SHADER_DEFERRED); LLGLSLShader gDeferredSoftenProgram(LLViewerShaderMgr::SHADER_DEFERRED); -LLGLSLShader gDeferredShadowProgram(LLViewerShaderMgr::SHADER_DEFERRED); //Not in mShaderList +LLGLSLShader gDeferredShadowProgram(LLViewerShaderMgr::SHADER_DEFERRED); //Not in mShaderList LLGLSLShader gDeferredAvatarShadowProgram(LLViewerShaderMgr::SHADER_DEFERRED);//Not in mShaderList LLGLSLShader gDeferredAlphaProgram(LLViewerShaderMgr::SHADER_DEFERRED); //calculatesAtmospherics LLGLSLShader gDeferredFullbrightProgram(LLViewerShaderMgr::SHADER_DEFERRED); //calculatesAtmospherics +LLGLSLShader gDeferredGIProgram(LLViewerShaderMgr::SHADER_DEFERRED); +LLGLSLShader gDeferredGIFinalProgram(LLViewerShaderMgr::SHADER_DEFERRED); +LLGLSLShader gDeferredPostGIProgram(LLViewerShaderMgr::SHADER_DEFERRED); +LLGLSLShader gDeferredPostProgram(LLViewerShaderMgr::SHADER_DEFERRED); +LLGLSLShader gLuminanceGatherProgram(LLViewerShaderMgr::SHADER_DEFERRED); //current avatar shader parameter pointer GLint gAvatarMatrixParam; @@ -154,6 +163,7 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void) mReservedAttribs.push_back("materialColor"); mReservedAttribs.push_back("specularColor"); mReservedAttribs.push_back("binormal"); + mReservedAttribs.push_back("object_weight"); mAvatarAttribs.reserve(5); mAvatarAttribs.push_back("weight"); @@ -195,13 +205,35 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void) mReservedUniforms.push_back("shadowMap1"); mReservedUniforms.push_back("shadowMap2"); mReservedUniforms.push_back("shadowMap3"); + mReservedUniforms.push_back("shadowMap4"); + mReservedUniforms.push_back("shadowMap5"); + mReservedUniforms.push_back("normalMap"); mReservedUniforms.push_back("positionMap"); mReservedUniforms.push_back("diffuseRect"); mReservedUniforms.push_back("specularRect"); mReservedUniforms.push_back("noiseMap"); + mReservedUniforms.push_back("lightFunc"); mReservedUniforms.push_back("lightMap"); - + mReservedUniforms.push_back("luminanceMap"); + mReservedUniforms.push_back("giLightMap"); + mReservedUniforms.push_back("giMip"); + mReservedUniforms.push_back("edgeMap"); + mReservedUniforms.push_back("bloomMap"); + mReservedUniforms.push_back("sunLightMap"); + mReservedUniforms.push_back("localLightMap"); + mReservedUniforms.push_back("projectionMap"); + mReservedUniforms.push_back("diffuseGIMap"); + mReservedUniforms.push_back("specularGIMap"); + mReservedUniforms.push_back("normalGIMap"); + mReservedUniforms.push_back("minpGIMap"); + mReservedUniforms.push_back("maxpGIMap"); + mReservedUniforms.push_back("depthGIMap"); + mReservedUniforms.push_back("lastDiffuseGIMap"); + mReservedUniforms.push_back("lastNormalGIMap"); + mReservedUniforms.push_back("lastMinpGIMap"); + mReservedUniforms.push_back("lastMaxpGIMap"); + mWLUniforms.push_back("camPosLocal"); mTerrainUniforms.reserve(5); @@ -314,7 +346,21 @@ void LLViewerShaderMgr::setShaders() LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders") && gSavedSettings.getBOOL("WindLightUseAtmosShaders")) { - deferred_class = 1; + if (gSavedSettings.getS32("RenderShadowDetail") > 0) + { + if (gSavedSettings.getBOOL("RenderDeferredGI")) + { //shadows + gi + deferred_class = 3; + } + else + { //shadows + deferred_class = 2; + } + } + else + { //no shadows + deferred_class = 1; + } //make sure framebuffer objects are enabled gSavedSettings.setBOOL("RenderUseFBO", TRUE); @@ -322,6 +368,8 @@ void LLViewerShaderMgr::setShaders() //make sure hardware skinning is enabled gSavedSettings.setBOOL("RenderAvatarVP", TRUE); } + + if (!(LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders") && gSavedSettings.getBOOL("WindLightUseAtmosShaders"))) { @@ -520,7 +568,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders() // (in order of shader function call depth for reference purposes, deepest level first) shaders.clear(); - shaders.reserve(12); + shaders.reserve(13); shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); shaders.push_back( make_pair( "windlight/gammaF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT]) ); shaders.push_back( make_pair( "windlight/atmosphericsF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); @@ -533,6 +581,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders() shaders.push_back( make_pair( "lighting/lightShinyF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); + shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); for (U32 i = 0; i < shaders.size(); i++) { @@ -837,10 +886,41 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { + gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader"; + gDeferredSpotLightProgram.mShaderFiles.clear(); + gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredSpotLightProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader"; + gDeferredMultiSpotLightProgram.mShaderFiles.clear(); + gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredMultiSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL); + } + + if (success) + { + std::string fragment; + + if (gSavedSettings.getBOOL("RenderDeferredSSAO")) + { + fragment = "deferred/sunLightSSAOF.glsl"; + } + else + { + fragment = "deferred/sunLightF.glsl"; + } + gDeferredSunProgram.mName = "Deferred Sun Shader"; gDeferredSunProgram.mShaderFiles.clear(); gDeferredSunProgram.mShaderFiles.push_back(make_pair("deferred/sunLightV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredSunProgram.mShaderFiles.push_back(make_pair("deferred/sunLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB)); gDeferredSunProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredSunProgram.createShader(NULL, NULL); } @@ -966,6 +1046,72 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = gDeferredAvatarAlphaProgram.createShader(&mAvatarAttribs, &mAvatarUniforms); } + if (mVertexShaderLevel[SHADER_DEFERRED] > 1) + { + if (success) + { + gDeferredEdgeProgram.mName = "Deferred Edge Shader"; + gDeferredEdgeProgram.mShaderFiles.clear(); + gDeferredEdgeProgram.mShaderFiles.push_back(make_pair("deferred/edgeV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredEdgeProgram.mShaderFiles.push_back(make_pair("deferred/edgeF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredEdgeProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredEdgeProgram.createShader(NULL, NULL); + } + } + + if (mVertexShaderLevel[SHADER_DEFERRED] > 2) + { + if (success) + { + gDeferredPostProgram.mName = "Deferred Post Shader"; + gDeferredPostProgram.mShaderFiles.clear(); + gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredPostProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredPostProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredPostGIProgram.mName = "Deferred Post GI Shader"; + gDeferredPostGIProgram.mShaderFiles.clear(); + gDeferredPostGIProgram.mShaderFiles.push_back(make_pair("deferred/postgiV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredPostGIProgram.mShaderFiles.push_back(make_pair("deferred/postgiF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredPostGIProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredPostGIProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredGIProgram.mName = "Deferred GI Shader"; + gDeferredGIProgram.mShaderFiles.clear(); + gDeferredGIProgram.mShaderFiles.push_back(make_pair("deferred/giV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredGIProgram.mShaderFiles.push_back(make_pair("deferred/giF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredGIProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredGIProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredGIFinalProgram.mName = "Deferred GI Final Shader"; + gDeferredGIFinalProgram.mShaderFiles.clear(); + gDeferredGIFinalProgram.mShaderFiles.push_back(make_pair("deferred/giFinalV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredGIFinalProgram.mShaderFiles.push_back(make_pair("deferred/giFinalF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredGIFinalProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredGIFinalProgram.createShader(NULL, NULL); + } + + if (success) + { + gLuminanceGatherProgram.mName = "Luminance Gather Shader"; + gLuminanceGatherProgram.mShaderFiles.clear(); + gLuminanceGatherProgram.mShaderFiles.push_back(make_pair("deferred/luminanceV.glsl", GL_VERTEX_SHADER_ARB)); + gLuminanceGatherProgram.mShaderFiles.push_back(make_pair("deferred/luminanceF.glsl", GL_FRAGMENT_SHADER_ARB)); + gLuminanceGatherProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gLuminanceGatherProgram.createShader(NULL, NULL); + } + } + return success; } @@ -1085,6 +1231,22 @@ BOOL LLViewerShaderMgr::loadShadersObject() success = gObjectFullbrightShinyProgram.createShader(NULL, &mShinyUniforms); } + 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.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 = mVertexShaderLevel[SHADER_OBJECT]; + gObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectFullbrightShinyWaterProgram.createShader(NULL, &mShinyUniforms); + } if( !success ) { diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 8fa582909..1c4e912a4 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -82,6 +82,7 @@ public: MATERIAL_COLOR = 0, SPECULAR_COLOR, BINORMAL, + OBJECT_WEIGHT, END_RESERVED_ATTRIBS } eGLSLReservedAttribs; @@ -116,12 +117,33 @@ public: DEFERRED_SHADOW1, DEFERRED_SHADOW2, DEFERRED_SHADOW3, + DEFERRED_SHADOW4, + DEFERRED_SHADOW5, DEFERRED_NORMAL, DEFERRED_POSITION, DEFERRED_DIFFUSE, DEFERRED_SPECULAR, DEFERRED_NOISE, + DEFERRED_LIGHTFUNC, DEFERRED_LIGHT, + DEFERRED_LUMINANCE, + DEFERRED_GI_LIGHT, + DEFERRED_GI_MIP, + DEFERRED_EDGE, + DEFERRED_BLOOM, + DEFERRED_SUN_LIGHT, + DEFERRED_LOCAL_LIGHT, + DEFERRED_PROJECTION, + DEFERRED_GI_DIFFUSE, + DEFERRED_GI_SPECULAR, + DEFERRED_GI_NORMAL, + DEFERRED_GI_MIN_POS, + DEFERRED_GI_MAX_POS, + DEFERRED_GI_DEPTH, + DEFERRED_GI_LAST_DIFFUSE, + DEFERRED_GI_LAST_NORMAL, + DEFERRED_GI_LAST_MIN_POS, + DEFERRED_GI_LAST_MAX_POS, END_RESERVED_UNIFORMS } eGLSLReservedUniforms; @@ -293,6 +315,7 @@ extern LLGLSLShader gObjectSimpleLODProgram; extern LLGLSLShader gObjectFullbrightLODProgram; extern LLGLSLShader gObjectFullbrightShinyProgram; +extern LLGLSLShader gObjectFullbrightShinyWaterProgram; extern LLGLSLShader gObjectShinyProgram; extern LLGLSLShader gObjectShinyWaterProgram; @@ -324,6 +347,7 @@ extern LLGLSLShader gPostGaussianBlurProgram; // Deferred rendering shaders extern LLGLSLShader gDeferredImpostorProgram; +extern LLGLSLShader gDeferredEdgeProgram; extern LLGLSLShader gDeferredWaterProgram; extern LLGLSLShader gDeferredDiffuseProgram; extern LLGLSLShader gDeferredBumpProgram; @@ -331,16 +355,24 @@ extern LLGLSLShader gDeferredTerrainProgram; extern LLGLSLShader gDeferredTreeProgram; extern LLGLSLShader gDeferredLightProgram; extern LLGLSLShader gDeferredMultiLightProgram; +extern LLGLSLShader gDeferredSpotLightProgram; +extern LLGLSLShader gDeferredMultiSpotLightProgram; extern LLGLSLShader gDeferredSunProgram; +extern LLGLSLShader gDeferredGIProgram; +extern LLGLSLShader gDeferredGIFinalProgram; extern LLGLSLShader gDeferredBlurLightProgram; extern LLGLSLShader gDeferredAvatarProgram; extern LLGLSLShader gDeferredSoftenProgram; extern LLGLSLShader gDeferredShadowProgram; +extern LLGLSLShader gDeferredPostGIProgram; +extern LLGLSLShader gDeferredPostProgram; extern LLGLSLShader gDeferredAvatarShadowProgram; extern LLGLSLShader gDeferredAlphaProgram; extern LLGLSLShader gDeferredFullbrightProgram; extern LLGLSLShader gDeferredAvatarAlphaProgram; +extern LLGLSLShader gLuminanceGatherProgram; + //current avatar shader parameter pointer extern GLint gAvatarMatrixParam; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 5c1b22fa6..997a393ff 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -531,7 +531,7 @@ void update_statistics(U32 frame_count) } } LLViewerStats::getInstance()->setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable")); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gSavedSettings.getS32("RenderLightingDetail")); + //LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gSavedSettings.getS32("RenderLightingDetail")); LLViewerStats::getInstance()->setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip")); LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles")); #if 0 // 1.9.2 diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 385782247..4f2b44210 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2411,21 +2411,22 @@ void LLVOAvatar::updateMeshData() bool terse_update = false; - if(facep->mVertexBuffer.isNull()) + if(!facep->getVertexBuffer()) { - facep->mVertexBuffer = new LLVertexBufferAvatar(); - facep->mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE); + LLVertexBuffer *buff = new LLVertexBufferAvatar(); + buff->allocateBuffer(num_vertices, num_indices, TRUE); + facep->setVertexBuffer(buff); } else { - if (facep->mVertexBuffer->getRequestedIndices() == num_indices && - facep->mVertexBuffer->getRequestedVerts() == num_vertices) + if (facep->getVertexBuffer()->getRequestedIndices() == num_indices && + facep->getVertexBuffer()->getRequestedVerts() == num_vertices) { terse_update = true; } else { - facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ; + facep->getVertexBuffer()->resizeBuffer(num_vertices, num_indices) ; } } @@ -2445,7 +2446,7 @@ void LLVOAvatar::updateMeshData() } stop_glerror(); - facep->mVertexBuffer->setBuffer(0); + facep->getVertexBuffer()->setBuffer(0); if(!f_num) { @@ -4930,7 +4931,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) LLFace* face = mDrawable->getFace(0); - bool needs_rebuild = !face || face->mVertexBuffer.isNull() || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY); + bool needs_rebuild = !face || !face->getVertexBuffer() || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY); if (needs_rebuild || mDirtyMesh) { //LOD changed or new mesh created, allocate new vertex buffer if needed @@ -4964,7 +4965,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) } mNeedsSkin = FALSE; - LLVertexBuffer* vb = mDrawable->getFace(0)->mVertexBuffer; + LLVertexBuffer* vb = mDrawable->getFace(0)->getVertexBuffer(); if (vb) { vb->setBuffer(0); @@ -5236,7 +5237,7 @@ U32 LLVOAvatar::renderFootShadows() return num_indices; } -U32 LLVOAvatar::renderImpostor(LLColor4U color) +U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel) { if (!mImpostor.isComplete()) { @@ -5256,7 +5257,7 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color) gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f); gGL.color4ubv(color.mV); - gGL.getTexUnit(0)->bind(&mImpostor); + gGL.getTexUnit(diffuse_channel)->bind(&mImpostor); gGL.begin(LLRender::QUADS); gGL.texCoord2f(0,0); gGL.vertex3fv((pos+left-up).mV); @@ -10437,7 +10438,7 @@ BOOL LLVOAvatar::updateLOD() BOOL res = updateJointLODs(); LLFace* facep = mDrawable->getFace(0); - if (facep->mVertexBuffer.isNull()) + if (!facep->getVertexBuffer()) { dirtyMesh(2); } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 7da445414..6ec9179c8 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -348,7 +348,7 @@ private: public: // Graphical stuff for objects - maybe broken out into render class later? U32 renderFootShadows(); - U32 renderImpostor(LLColor4U color = LLColor4U(255,255,255,255)); + U32 renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0); U32 renderRigid(); U32 renderSkinned(EAvatarRenderPass pass); U32 renderTransparent(BOOL first_pass); diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 0cd754a8d..f13b973da 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -465,7 +465,7 @@ void LLVOGrass::plantBlades() face->setTexture(getTEImage(0)); face->setState(LLFace::GLOBAL); face->setSize(mNumBlades * 8, mNumBlades * 12); - face->mVertexBuffer = NULL; + face->setVertexBuffer(NULL); face->setTEOffset(0); face->mCenterLocal = mPosition + mRegionp->getOriginAgent(); diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp index 0ef0196cc..2c22deb7c 100644 --- a/indra/newview/llvoground.cpp +++ b/indra/newview/llvoground.cpp @@ -37,7 +37,6 @@ #include "llviewercontrol.h" -#include "llagent.h" #include "lldrawable.h" #include "llface.h" #include "llsky.h" @@ -104,13 +103,14 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable) drawable->addFace(poolp, NULL); face = drawable->getFace(0); - if (face->mVertexBuffer.isNull()) + if (!face->getVertexBuffer()) { face->setSize(5, 12); - face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolGround::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); - face->mVertexBuffer->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolGround::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); + buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); face->setGeomIndex(0); face->setIndicesIndex(0); + face->setVertexBuffer(buff); } index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); @@ -168,7 +168,7 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable) *(texCoordsp++) = LLVector2(0.f, 1.f); *(texCoordsp++) = LLVector2(0.5f, 0.5f); - face->mVertexBuffer->setBuffer(0); + face->getVertexBuffer()->setBuffer(0); LLPipeline::sCompiles++; return TRUE; } diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index b6ba7e50f..978fbd509 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -457,7 +457,7 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject(); facep->setGeomIndex(vertex_count); facep->setIndicesIndex(index_count); - facep->mVertexBuffer = buffer; + facep->setVertexBuffer(buffer); facep->setPoolType(LLDrawPool::POOL_ALPHA); object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, indicesp); @@ -486,7 +486,9 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) U32 end = start + facep->getGeomCount()-1; U32 offset = facep->getIndicesStart(); U32 count = facep->getIndicesCount(); - LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), buffer, fullbright); + LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), + //facep->getTexture(), + buffer, fullbright); info->mExtents[0] = group->mObjectExtents[0]; info->mExtents[1] = group->mObjectExtents[1]; info->mVSize = vsize; diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index f2f835220..00e48687d 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -309,7 +309,7 @@ void LLSkyTex::createGLImage(S32 which) void LLSkyTex::bindTexture(BOOL curr) { - gGL.getTexUnit(0)->bind(mTexture[getWhich(curr)]); + gGL.getTexUnit(0)->bind(mTexture[getWhich(curr)], true); } /*************************************** @@ -1039,7 +1039,7 @@ void LLVOSky::calcAtmospherics(void) // Since WL scales everything by 2, there should always be at least a 2:1 brightness ratio // between sunlight and point lights in windlight to normalize point lights. - static const LLCachedControl render_sun_dynamic_range("RenderSunDynamicRange", 1); + static const LLCachedControl render_sun_dynamic_range("RenderSunDynamicRange", 1.f); F32 sun_dynamic_range = llmax((float)render_sun_dynamic_range, 0.0001f); LLWLParamManager::instance()->mSceneLightStrength = 2.0f * (1.0f + sun_dynamic_range * dp); @@ -1190,7 +1190,7 @@ BOOL LLVOSky::updateSky() } } - if (mDrawable.notNull() && mDrawable->getFace(0) && mDrawable->getFace(0)->mVertexBuffer.isNull()) + if (mDrawable.notNull() && mDrawable->getFace(0) && !mDrawable->getFace(0)->getVertexBuffer()) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); } @@ -1241,10 +1241,11 @@ void LLVOSky::createDummyVertexBuffer() mFace[FACE_DUMMY] = mDrawable->addFace(poolp, NULL); } - if(mFace[FACE_DUMMY]->mVertexBuffer.isNull()) + if(!mFace[FACE_DUMMY]->getVertexBuffer()) { - mFace[FACE_DUMMY]->mVertexBuffer = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB); - mFace[FACE_DUMMY]->mVertexBuffer->allocateBuffer(1, 1, TRUE); + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB); + buff->allocateBuffer(1, 1, TRUE); + mFace[FACE_DUMMY]->setVertexBuffer(buff); } } @@ -1261,13 +1262,13 @@ void LLVOSky::updateDummyVertexBuffer() LLFastTimer t(LLFastTimer::FTM_RENDER_FAKE_VBO_UPDATE) ; - if(!mFace[FACE_DUMMY] || mFace[FACE_DUMMY]->mVertexBuffer.isNull()) + if(!mFace[FACE_DUMMY] || !mFace[FACE_DUMMY]->getVertexBuffer()) createDummyVertexBuffer() ; LLStrider vertices ; - mFace[FACE_DUMMY]->mVertexBuffer->getVertexStrider(vertices, 0); + mFace[FACE_DUMMY]->getVertexBuffer()->getVertexStrider(vertices, 0); *vertices = mCameraPosAgent ; - mFace[FACE_DUMMY]->mVertexBuffer->setBuffer(0) ; + mFace[FACE_DUMMY]->getVertexBuffer()->setBuffer(0) ; } //---------------------------------- //end of fake vertex buffer updating @@ -1309,14 +1310,15 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable) { face = mFace[FACE_SIDE0 + side]; - if (face->mVertexBuffer.isNull()) + if (!face->getVertexBuffer()) { face->setSize(4, 6); face->setGeomIndex(0); face->setIndicesIndex(0); - face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); - face->mVertexBuffer->allocateBuffer(4, 6, TRUE); - + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); + buff->allocateBuffer(4, 6, TRUE); + face->setVertexBuffer(buff); + index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); S32 vtx = 0; @@ -1349,7 +1351,7 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable) *indicesp++ = index_offset + 3; *indicesp++ = index_offset + 2; - face->mVertexBuffer->setBuffer(0); + buff->setBuffer(0); } } @@ -1476,13 +1478,14 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons facep = mFace[f]; - if (facep->mVertexBuffer.isNull()) + if (!facep->getVertexBuffer()) { - facep->setSize(4, 6); - facep->mVertexBuffer = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); - facep->mVertexBuffer->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE); + facep->setSize(4, 6); + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); + buff->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE); facep->setGeomIndex(0); facep->setIndicesIndex(0); + facep->setVertexBuffer(buff); } index_offset = facep->getGeometry(verticesp,normalsp,texCoordsp, indicesp); @@ -1511,7 +1514,7 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons *indicesp++ = index_offset + 2; *indicesp++ = index_offset + 3; - facep->mVertexBuffer->setBuffer(0); + facep->getVertexBuffer()->setBuffer(0); if (is_sun) { @@ -1880,13 +1883,14 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, LLFace *face = mFace[FACE_REFLECTION]; - if (face->mVertexBuffer.isNull() || quads*4 != face->getGeomCount()) + if (!face->getVertexBuffer() || quads*4 != face->getGeomCount()) { face->setSize(quads * 4, quads * 6); - face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); - face->mVertexBuffer->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); + buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); face->setIndicesIndex(0); face->setGeomIndex(0); + face->setVertexBuffer(buff); } LLStrider verticesp; @@ -2024,7 +2028,7 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, } } - face->mVertexBuffer->setBuffer(0); + face->getVertexBuffer()->setBuffer(0); } diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 0cb390f02..70ffbd794 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -845,7 +845,7 @@ void LLVOSurfacePatch::dirtyGeom() if (mDrawable) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); - mDrawable->getFace(0)->mVertexBuffer = NULL; + mDrawable->getFace(0)->setVertexBuffer(NULL); mDrawable->movePartition(); } } @@ -1064,7 +1064,7 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) facep->setIndicesIndex(indices_index); facep->setGeomIndex(index_offset); - facep->mVertexBuffer = buffer; + facep->setVertexBuffer(buffer); LLVOSurfacePatch* patchp = (LLVOSurfacePatch*) facep->getViewerObject(); patchp->getGeometry(vertices, normals, colors, texcoords, texcoords2, indices); diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 8e0d09f2a..51e44e739 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -388,12 +388,11 @@ BOOL LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) } } - S32 trunk_LOD = 0; + S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ; F32 app_angle = getAppAngle()*LLVOTree::sTreeFactor; - for (S32 j = 0; j < 4; j++) + for (S32 j = 0; j < sMAX_NUM_TREE_LOD_LEVELS; j++) { - if (app_angle > LLVOTree::sLODAngles[j]) { trunk_LOD = j; @@ -531,7 +530,14 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) { LLFastTimer ftm(LLFastTimer::FTM_UPDATE_TREE); - if (mReferenceBuffer.isNull() || mDrawable->getFace(0)->mVertexBuffer.isNull()) + if(mTrunkLOD >= sMAX_NUM_TREE_LOD_LEVELS) //do not display the tree. + { + mReferenceBuffer = NULL ; + mDrawable->getFace(0)->setVertexBuffer(NULL); + return TRUE ; + } + + if (mReferenceBuffer.isNull() || !mDrawable->getFace(0)->getVertexBuffer()) { const F32 SRR3 = 0.577350269f; // sqrt(1/3) const F32 SRR2 = 0.707106781f; // sqrt(1/2) @@ -869,7 +875,7 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) //Using an && here is incorrect, and will cause instability. if (/*gLLWindEnabled || */render_animate_trees) { - mDrawable->getFace(0)->mVertexBuffer = mReferenceBuffer; + mDrawable->getFace(0)->setVertexBuffer(mReferenceBuffer); } else { @@ -928,8 +934,9 @@ void LLVOTree::updateMesh() calcNumVerts(vert_count, index_count, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, mBranches); LLFace* facep = mDrawable->getFace(0); - facep->mVertexBuffer = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); - facep->mVertexBuffer->allocateBuffer(vert_count, index_count, TRUE); + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); + buff->allocateBuffer(vert_count, index_count, TRUE); + facep->setVertexBuffer(buff); LLStrider vertices; LLStrider normals; @@ -937,16 +944,15 @@ void LLVOTree::updateMesh() LLStrider indices; U16 idx_offset = 0; - facep->mVertexBuffer->getVertexStrider(vertices); - facep->mVertexBuffer->getNormalStrider(normals); - facep->mVertexBuffer->getTexCoord0Strider(tex_coords); - facep->mVertexBuffer->getIndexStrider(indices); + buff->getVertexStrider(vertices); + buff->getNormalStrider(normals); + buff->getTexCoord0Strider(tex_coords); + buff->getIndexStrider(indices); genBranchPipeline(vertices, normals, tex_coords, indices, idx_offset, scale_mat, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, 1.0, mTwist, droop, mBranches, alpha); mReferenceBuffer->setBuffer(0); - facep->mVertexBuffer->setBuffer(0); - + buff->setBuffer(0); } void LLVOTree::appendMesh(LLStrider& vertices, @@ -1330,7 +1336,7 @@ U32 LLVOTree::getPartitionType() const } LLTreePartition::LLTreePartition() -: LLSpatialPartition(0, FALSE, 0) +: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB) { mDrawableType = LLPipeline::RENDER_TYPE_TREE; mPartitionType = LLViewerRegion::PARTITION_TREE; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 62c9ec640..bddefa52b 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -95,6 +95,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mNumFaces = 0; mLODChanged = FALSE; mSculptChanged = FALSE; + mSpotLightPriority = 0.f; mIndexInTex = 0; } @@ -614,6 +615,19 @@ void LLVOVolume::updateTextureVirtualSize() } } + if (getLightTextureID().notNull()) + { + LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + LLUUID id = params->getLightTexture(); + mLightTexture = LLViewerTextureManager::getFetchedTexture(id); + if (mLightTexture.notNull()) + { + F32 rad = getLightRadius(); + mLightTexture->addTextureStats(gPipeline.calcPixelArea(getPositionAgent(), + LLVector3(rad,rad,rad), + *camera)); + } + } if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) { @@ -968,6 +982,11 @@ void LLVOVolume::updateFaceFlags() for (S32 i = 0; i < getVolume()->getNumFaces(); i++) { LLFace *face = mDrawable->getFace(i); + if (!face) + { + return; + } + BOOL fullbright = getTE(i)->getFullbright(); face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT); @@ -1040,6 +1059,10 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) for (S32 i = 0; i < getVolume()->getNumFaces(); i++) { LLFace *face = mDrawable->getFace(i); + if (!face) + { + continue; + } res &= face->genVolumeBBoxes(*getVolume(), i, mRelativeXform, mRelativeXformInvTrans, (mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global); @@ -1258,6 +1281,17 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) regenFaces(); } genBBoxes(FALSE); + + if (mSculptChanged) + { //changes in sculpt maps can thrash an object bounding box without + //triggering a spatial group bounding box update -- force spatial group + //to update bounding boxes + LLSpatialGroup* group = mDrawable->getSpatialGroup(); + if (group) + { + group->unbound(); + } + } } } } @@ -1494,6 +1528,41 @@ void LLVOVolume::updateTEData() //---------------------------------------------------------------------------- +void LLVOVolume::setLightTextureID(LLUUID id) +{ + if (id.notNull()) + { + if (!hasLightTexture()) + { + setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, TRUE, true); + } + LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block && param_block->getLightTexture() != id) + { + param_block->setLightTexture(id); + parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); + } + } + else + { + if (hasLightTexture()) + { + setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, FALSE, true); + mLightTexture = NULL; + } + } +} + +void LLVOVolume::setSpotLightParams(LLVector3 params) +{ + LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block && param_block->getParams() != params) + { + param_block->setParams(params); + parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); + } +} + void LLVOVolume::setIsLight(BOOL is_light) { if (is_light != getIsLight()) @@ -1620,6 +1689,94 @@ LLColor3 LLVOVolume::getLightColor() const } } +LLUUID LLVOVolume::getLightTextureID() const +{ + if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) + { + const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block) + { + return param_block->getLightTexture(); + } + } + + return LLUUID::null; +} + + +LLVector3 LLVOVolume::getSpotLightParams() const +{ + if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) + { + const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block) + { + return param_block->getParams(); + } + } + + return LLVector3(); +} + +F32 LLVOVolume::getSpotLightPriority() const +{ + return mSpotLightPriority; +} + +void LLVOVolume::updateSpotLightPriority() +{ + LLVector3 pos = mDrawable->getPositionAgent(); + LLVector3 at(0,0,-1); + at *= getRenderRotation(); + + F32 r = getLightRadius()*0.5f; + + pos += at * r; + + at = LLViewerCamera::getInstance()->getAtAxis(); + + pos -= at * r; + + mSpotLightPriority = gPipeline.calcPixelArea(pos, LLVector3(r,r,r), *LLViewerCamera::getInstance()); + + if (mLightTexture.notNull()) + { + mLightTexture->addTextureStats(mSpotLightPriority); + mLightTexture->setBoostLevel(LLViewerTexture::BOOST_CLOUDS); + } +} + + +bool LLVOVolume::isLightSpotlight() const +{ + LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (params) + { + return params->isLightSpotlight(); + } + return false; +} + + +LLViewerTexture* LLVOVolume::getLightTexture() +{ + LLUUID id = getLightTextureID(); + + if (id.notNull()) + { + if (mLightTexture.isNull() || id != mLightTexture->getID()) + { + mLightTexture = LLViewerTextureManager::getFetchedTexture(id); + } + } + else + { + mLightTexture = NULL; + } + + return mLightTexture; +} + F32 LLVOVolume::getLightIntensity() const { const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); @@ -1711,6 +1868,16 @@ BOOL LLVOVolume::isSculpted() const return FALSE; } +BOOL LLVOVolume::hasLightTexture() const +{ + if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) + { + return TRUE; + } + + return FALSE; +} + BOOL LLVOVolume::isVolumeGlobal() const { if (mVolumeImpl) @@ -2200,7 +2367,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, (type == LLRenderPass::PASS_INVISIBLE) || (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)); - if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL)) + if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_NORMAL)) { llwarns << "Non fullbright face has no normals!" << llendl; return; @@ -2236,13 +2403,13 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, glow = (U8) (facep->getTextureEntry()->getGlow() * 255); } - if (facep->mVertexBuffer.isNull()) + if (!facep->getVertexBuffer()) { llerrs << "WTF?" << llendl; } if (idx >= 0 && - draw_vec[idx]->mVertexBuffer == facep->mVertexBuffer && + draw_vec[idx]->mVertexBuffer == facep->getVertexBuffer() && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && (LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex) && #if LL_DARWIN @@ -2269,7 +2436,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 offset = facep->getIndicesStart(); U32 count = facep->getIndicesCount(); LLPointer draw_info = new LLDrawInfo(start,end,count,offset,tex, - facep->mVertexBuffer, fullbright, bump); + facep->getVertexBuffer(), fullbright, bump); draw_info->mGroup = group; draw_info->mVSize = facep->getVirtualSize(); draw_vec.push_back(draw_info); @@ -2366,20 +2533,23 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) //for each face for (S32 i = 0; i < drawablep->getNumFaces(); i++) { + LLFace* facep = drawablep->getFace(i); + + //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render + // batch, it will recover its vertex buffer reference from the spatial group + facep->setVertexBuffer(NULL); //sum up face verts and indices drawablep->updateFaceSize(i); - LLFace* facep = drawablep->getFace(i); if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0) { - facep->mVertexBuffer = NULL; - facep->mLastVertexBuffer = NULL; + facep->clearVertexBuffer(); continue; } cur_total += facep->getGeomCount(); - if (facep->hasGeometry() && facep->mPixelArea > FORCE_CULL_AREA) + if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA) { const LLTextureEntry* te = facep->getTextureEntry(); LLViewerTexture* tex = facep->getTexture(); @@ -2392,7 +2562,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } - BOOL force_simple = (facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA); + BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA); U32 type = gPipeline.getPoolTypeFromTE(te, tex); if (type != LLDrawPool::POOL_ALPHA && force_simple) { @@ -2478,8 +2648,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } else { //face has no renderable geometry - facep->mVertexBuffer = NULL; - facep->mLastVertexBuffer = NULL; + facep->clearVertexBuffer(); } } } @@ -2550,7 +2719,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) for (S32 i = 0; i < drawablep->getNumFaces(); ++i) { LLFace* face = drawablep->getFace(i); - if (face && face->mVertexBuffer.notNull()) + if (face && face->getVertexBuffer()) { face->getGeometryVolume(*volume, face->getTEOffset(), vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()); @@ -2601,9 +2770,10 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) for (S32 i = 0; i < drawablep->getNumFaces(); ++i) { LLFace* face = drawablep->getFace(i); - if (face && face->mVertexBuffer.notNull() && face->mVertexBuffer->isLocked()) + LLVertexBuffer* buff = face ? face->getVertexBuffer() : NULL; + if (buff && buff->isLocked()) { - face->mVertexBuffer->setBuffer(0) ; + buff->setBuffer(0) ; } } } @@ -2705,14 +2875,13 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: buffer->allocateBuffer(geom_count, index_count, TRUE); } else - { - if (LLVertexBuffer::sEnableVBOs && buffer->getUsage() != group->mBufferUsage) + { //resize pre-existing buffer + if (LLVertexBuffer::sEnableVBOs && buffer->getUsage() != group->mBufferUsage || + buffer->getTypeMask() != mask) { - //Using group->mSpatialPartition->mVertexDataMask may be dropping MAP_BINORMAL on RENDER_BUMP... - buffer = createVertexBuffer(mask /*group->mSpatialPartition->mVertexDataMask*/, + buffer = createVertexBuffer(mask, group->mBufferUsage); buffer->allocateBuffer(geom_count, index_count, TRUE); - llassert_always(buffer->getTypeMask() == mask); } else { @@ -2728,11 +2897,12 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: U16 index_offset = 0; while (face_iter < i) - { + { //update face indices for new buffer facep = *face_iter; - facep->mIndicesIndex = indices_index; - facep->mGeomIndex = index_offset; - facep->mVertexBuffer = buffer; + facep->setIndicesIndex(indices_index); + facep->setGeomIndex(index_offset); + facep->setVertexBuffer(buffer); + { facep->updateRebuildFlags(); if (!LLPipeline::sDelayVBUpdate) @@ -2753,9 +2923,12 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } index_offset += facep->getGeomCount(); - indices_index += facep->mIndicesCount; + indices_index += facep->getIndicesCount(); - BOOL force_simple = facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA; + + //append face to appropriate render batch + + BOOL force_simple = facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA; BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); if ((mask & LLVertexBuffer::MAP_NORMAL) == 0) { //paranoia check to make sure GL doesn't try to read non-existant normals @@ -2924,7 +3097,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun //sum up face verts and indices drawablep->updateFaceSize(i); LLFace* facep = drawablep->getFace(i); - if (facep->hasGeometry() && facep->mPixelArea > FORCE_CULL_AREA) + if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA) { vertex_count += facep->getGeomCount(); index_count += facep->getIndicesCount(); @@ -2934,8 +3107,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun } else { - facep->mVertexBuffer = NULL; - facep->mLastVertexBuffer = NULL; + facep->clearVertexBuffer(); } } } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 8f1b11bae..8b7dc172e 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -201,9 +201,19 @@ public: void setLightRadius(F32 radius); void setLightFalloff(F32 falloff); void setLightCutoff(F32 cutoff); + void setLightTextureID(LLUUID id); + void setSpotLightParams(LLVector3 params); + BOOL getIsLight() const; LLColor3 getLightBaseColor() const; // not scaled by intensity LLColor3 getLightColor() const; // scaled by intensity + LLUUID getLightTextureID() const; + bool isLightSpotlight() const; + LLVector3 getSpotLightParams() const; + void updateSpotLightPriority(); + F32 getSpotLightPriority() const; + + LLViewerTexture* getLightTexture(); F32 getLightIntensity() const; F32 getLightRadius() const; F32 getLightFalloff() const; @@ -213,6 +223,8 @@ public: U32 getVolumeInterfaceID() const; virtual BOOL isFlexible() const; virtual BOOL isSculpted() const; + virtual BOOL hasLightTexture() const; + BOOL isVolumeGlobal() const; BOOL canBeFlexible() const; BOOL setIsFlexible(BOOL is_flexible); @@ -237,12 +249,14 @@ private: S32 mLOD; BOOL mLODChanged; BOOL mSculptChanged; + F32 mSpotLightPriority; LLMatrix4 mRelativeXform; LLMatrix3 mRelativeXformInvTrans; BOOL mVolumeChanged; F32 mVObjRadius; LLVolumeInterface *mVolumeImpl; LLPointer mSculptTexture; + LLPointer mLightTexture; S32 mIndexInTex; // statics diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 0e80c62b2..347eb21b3 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -37,7 +37,6 @@ #include "imageids.h" #include "llviewercontrol.h" -#include "llagent.h" #include "lldrawable.h" #include "lldrawpoolwater.h" #include "llface.h" @@ -56,8 +55,6 @@ const BOOL gUseRoam = FALSE; /////////////////////////////////// -#include "randgauss.h" - template inline T LERP(T a, T b, F32 factor) { return a + (b - a) * factor; @@ -69,7 +66,9 @@ const U32 WIDTH = (N_RES * WAVE_STEP); //128.f //64 // width of wave tile, in const F32 WAVE_STEP_INV = (1. / WAVE_STEP); -LLVOWater::LLVOWater(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) : +LLVOWater::LLVOWater(const LLUUID &id, + const LLPCode pcode, + LLViewerRegion *regionp) : LLStaticViewerObject(id, pcode, regionp), mRenderType(LLPipeline::RENDER_TYPE_WATER) { @@ -160,21 +159,29 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) LLStrider indicesp; U16 index_offset; - S32 size = 16; - S32 num_quads = size*size; - face->setSize(4*num_quads, 6*num_quads); + // A quad is 4 vertices and 6 indices (making 2 triangles) + static const unsigned int vertices_per_quad = 4; + static const unsigned int indices_per_quad = 6; - if (face->mVertexBuffer.isNull()) + static const LLCachedControl render_transparent_water("RenderTransparentWater",false); + const S32 size = render_transparent_water ? 16 : 1; + const S32 num_quads = size * size; + face->setSize(vertices_per_quad * num_quads, + indices_per_quad * num_quads); + + LLVertexBuffer* buff = face->getVertexBuffer(); + if (!buff) { - face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB); - face->mVertexBuffer->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); + buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB); + buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); face->setIndicesIndex(0); face->setGeomIndex(0); + face->setVertexBuffer(buff); } else { - face->mVertexBuffer->resizeBuffer(face->getGeomCount(), face->getIndicesCount()); + buff->resizeBuffer(face->getGeomCount(), face->getIndicesCount()); } index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); @@ -228,7 +235,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) } } - face->mVertexBuffer->setBuffer(0); + buff->setBuffer(0); mDrawable->movePartition(); LLPipeline::sCompiles++; @@ -282,7 +289,7 @@ U32 LLVOVoidWater::getPartitionType() const } LLWaterPartition::LLWaterPartition() -: LLSpatialPartition(0, FALSE, 0) +: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB) { mInfiniteFarClip = TRUE; mDrawableType = LLPipeline::RENDER_TYPE_WATER; diff --git a/indra/newview/llwindebug.cpp b/indra/newview/llwindebug.cpp index bc8281480..4d175a071 100644 --- a/indra/newview/llwindebug.cpp +++ b/indra/newview/llwindebug.cpp @@ -429,7 +429,7 @@ void WINAPI Get_Call_Stack(const EXCEPTION_RECORD* exception_record, if (Get_Module_By_Ret_Addr(Ebp->Ret_Addr, Module_Name, Module_Addr)) { // Save module's address and full path. - tmp_info["CallStack"][Ret_Addr_I]["ModuleName"] = ll_convert_wide_to_string(Module_Name); + tmp_info["CallStack"][Ret_Addr_I]["ModuleName"] = ll_convert_wide_to_string(Module_Name,CP_ACP); tmp_info["CallStack"][Ret_Addr_I]["ModuleAddress"] = (int)Module_Addr; tmp_info["CallStack"][Ret_Addr_I]["CallOffset"] = (int)(Ebp->Ret_Addr - Module_Addr); @@ -548,7 +548,7 @@ LLSD WINAPI Get_Exception_Info(PEXCEPTION_POINTERS pException) Get_Version_Str(info); GetModuleFileName(NULL, Str, MAX_PATH); - info["Process"] = ll_convert_wide_to_string(Str); + info["Process"] = ll_convert_wide_to_string(Str,CP_ACP); info["ThreadID"] = (S32)GetCurrentThreadId(); // If exception occurred. @@ -560,7 +560,7 @@ LLSD WINAPI Get_Exception_Info(PEXCEPTION_POINTERS pException) // If module with E.ExceptionAddress found - save its path and date. if (Get_Module_By_Ret_Addr((PBYTE)E.ExceptionAddress, Module_Name, Module_Addr)) { - info["Module"] = ll_convert_wide_to_string(Module_Name); + info["Module"] = ll_convert_wide_to_string(Module_Name,CP_ACP); if ((hFile = CreateFile(Module_Name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index ac8e8e2db..827afec95 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -166,6 +166,9 @@ std::string gPoolNames[] = "POOL_INVALID_OUCH_CATASTROPHE_ERROR" }; +void drawBox(const LLVector3& c, const LLVector3& r); +void drawBoxOutline(const LLVector3& pos, const LLVector3& size); + U32 nhpo2(U32 v) { U32 r = 1; @@ -195,6 +198,16 @@ glh::matrix4f glh_get_current_projection() return glh_copy_matrix(gGLProjection); } +glh::matrix4f glh_get_last_modelview() +{ + return glh_copy_matrix(gGLLastModelView); +} + +glh::matrix4f glh_get_last_projection() +{ + return glh_copy_matrix(gGLLastProjection); +} + void glh_copy_matrix(const glh::matrix4f& src, GLdouble* dst) { for (U32 i = 0; i < 16; i++) @@ -258,7 +271,6 @@ BOOL LLPipeline::sRenderFrameTest = FALSE; BOOL LLPipeline::sRenderAttachedLights = TRUE; BOOL LLPipeline::sRenderAttachedParticles = TRUE; BOOL LLPipeline::sRenderDeferred = FALSE; -BOOL LLPipeline::sAllowRebuildPriorityGroup = FALSE ; S32 LLPipeline::sVisibleLightCount = 0; F32 LLPipeline::sMinRenderSize = 0.f; @@ -277,11 +289,11 @@ static const U32 gl_cube_face[] = void validate_framebuffer_object(); + void addDeferredAttachments(LLRenderTarget& target) { - target.addColorAttachment(GL_RGBA16F_ARB); //specular - target.addColorAttachment(GL_RGBA16F_ARB); //normal+z - target.addColorAttachment(GL_RGBA16F_ARB); //position + target.addColorAttachment(GL_RGBA); //specular + target.addColorAttachment(GL_RGBA); //normal+z } LLPipeline::LLPipeline() : @@ -305,6 +317,8 @@ LLPipeline::LLPipeline() : mRenderDebugFeatureMask(0), mRenderDebugMask(0), mOldRenderDebugMask(0), + mGroupQ1Locked(false), + mGroupQ2Locked(false), mLastRebuildPool(NULL), mAlphaPool(NULL), mSkyPool(NULL), @@ -322,6 +336,8 @@ LLPipeline::LLPipeline() : mLightingDetail(0) { mNoiseMap = 0; + mTrueNoiseMap = 0; + mLightFunc = 0; } void LLPipeline::init() @@ -332,6 +348,7 @@ void LLPipeline::init() sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("ShyotlRenderUseStreamVBO"); LLVertexBuffer::sOmitBlank = gSavedSettings.getBOOL("SianaRenderOmitBlankVBO"); + LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw"); sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights"); sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles"); @@ -377,6 +394,11 @@ void LLPipeline::init() LLViewerShaderMgr::instance()->setShaders(); stop_glerror(); + + for (U32 i = 0; i < 2; ++i) + { + mSpotLightFade[i] = 1.f; + } setLightingDetail(-1); } @@ -503,26 +525,119 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) if (LLPipeline::sRenderDeferred) { - //allocate deferred rendering color buffers - mDeferredScreen.allocate(resX, resY, GL_RGBA16F_ARB, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); - addDeferredAttachments(mDeferredScreen); - mScreen.allocate(resX, resY, GL_RGBA16F_ARB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); - - for (U32 i = 0; i < 2; i++) - { - mDeferredLight[i].allocate(resX, resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); - } - - //HACK: make alpha masking work on ATI depth shadows (work around for ATI driver bug) - U32 shadow_fmt = 0;/*gGLManager.mIsATI ? GL_ALPHA : 0;*/ + S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail"); + BOOL ssao = gSavedSettings.getBOOL("RenderDeferredSSAO"); + bool gi = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED); - for (U32 i = 0; i < 4; i++) - { - mSunShadow[i].allocate(1024,1024, shadow_fmt, TRUE, FALSE); + //allocate deferred rendering color buffers + static const LLCachedControl shadow_precision("DeferredHighPrecision",true); + const GLuint format = shadow_precision ? GL_RGBA : GL_RGBA16F_ARB; //TO-DO: Profile 16bit format later + mDeferredScreen.allocate(resX, resY, format, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + addDeferredAttachments(mDeferredScreen); + + mScreen.allocate(resX, resY, format, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + mEdgeMap.allocate(resX, resY, GL_ALPHA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + + if (shadow_detail > 0 || ssao) + { //only need mDeferredLight[0] for shadows OR ssao + mDeferredLight[0].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); } + else + { + mDeferredLight[0].release(); + } + + if (ssao) + { //only need mDeferredLight[1] for ssao + mDeferredLight[1].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + } + else + { + mDeferredLight[1].release(); + } + + if (gi) + { //only need mDeferredLight[2] and mGIMapPost for gi + mDeferredLight[2].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + for (U32 i = 0; i < 2; i++) + { + mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + } + } + else + { + mDeferredLight[2].release(); + + for (U32 i = 0; i < 2; i++) + { + mGIMapPost[i].release(); + } + } + + F32 scale = gSavedSettings.getF32("RenderShadowResolutionScale"); + + //HACK: make alpha masking work on ATI depth shadows (work around for ATI driver bug) + //TO-DO: Test if this is actually needed. + U32 shadow_fmt = gGLManager.mIsATI ? GL_ALPHA : 0; + + if (shadow_detail > 0) + { //allocate 4 sun shadow maps + for (U32 i = 0; i < 4; i++) + { + mShadow[i].allocate(U32(resX*scale),U32(resY*scale), shadow_fmt, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + } + } + else + { + for (U32 i = 0; i < 4; i++) + { + mShadow[i].release(); + } + } + + U32 width = nhpo2(U32(resX*scale))/2; + U32 height = width; + + if (shadow_detail > 1) + { //allocate two spot shadow maps + for (U32 i = 4; i < 6; i++) + { + mShadow[i].allocate(width, height, shadow_fmt, TRUE, FALSE); + } + } + else + { + for (U32 i = 4; i < 6; i++) + { + mShadow[i].release(); + } + } + + width = nhpo2(resX)/2; + height = nhpo2(resY)/2; + mLuminanceMap.allocate(width,height, GL_RGBA, FALSE, FALSE); } else { + for (U32 i = 0; i < 3; i++) + { + mDeferredLight[i].release(); + } + for (U32 i = 0; i < 2; i++) + { + mGIMapPost[i].release(); + } + for (U32 i = 0; i < 6; i++) + { + mShadow[i].release(); + } + mScreen.release(); + mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first + mDeferredDepth.release(); + mEdgeMap.release(); + mLuminanceMap.release(); + mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); } @@ -531,9 +646,12 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) { if (LLPipeline::sRenderDeferred) { - mSampleBuffer.allocate(resX,resY,GL_RGBA16F_ARB,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples); + static const LLCachedControl shadow_precision("DeferredHighPrecision",true); + const GLuint format = shadow_precision ? GL_RGBA : GL_RGBA16F_ARB; //TO-DO: Profile 16bit format later + mSampleBuffer.allocate(resX,resY,format,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples); addDeferredAttachments(mSampleBuffer); mDeferredScreen.setSampleBuffer(&mSampleBuffer); + mEdgeMap.setSampleBuffer(&mSampleBuffer); } else { @@ -544,12 +662,20 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) stop_glerror(); } + else + { + mSampleBuffer.release(); + } + if (LLPipeline::sRenderDeferred) { //share depth buffer between deferred targets mDeferredScreen.shareDepthBuffer(mScreen); - for (U32 i = 0; i < 2; i++) - { - mDeferredScreen.shareDepthBuffer(mDeferredLight[i]); + for (U32 i = 0; i < 3; i++) + { //share stencil buffer with screen space lightmap to stencil out sky + if (mDeferredLight[i].getTexture(0)) + { + mDeferredScreen.shareDepthBuffer(mDeferredLight[i]); + } } } @@ -565,10 +691,15 @@ void LLPipeline::updateRenderDeferred() sRenderDeferred = (gSavedSettings.getBOOL("RenderDeferred") && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && LLRenderTarget::sUseFBO && + LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && gSavedSettings.getBOOL("VertexShaderEnable") && gSavedSettings.getBOOL("RenderAvatarVP") && gSavedSettings.getBOOL("WindLightUseAtmosShaders") && !gUseWireframe); + if (sRenderDeferred) + { //must render glow when rendering deferred since post effect pass is needed to present any lighting at all + sRenderGlow = TRUE; + } } void LLPipeline::releaseGLBuffers() @@ -581,21 +712,40 @@ void LLPipeline::releaseGLBuffers() mNoiseMap = 0; } + if (mTrueNoiseMap) + { + LLImageGL::deleteTextures(1, &mTrueNoiseMap); + mTrueNoiseMap = 0; + } + + if (mLightFunc) + { + LLImageGL::deleteTextures(1, &mLightFunc); + mLightFunc = 0; + } + mWaterRef.release(); mWaterDis.release(); mScreen.release(); - mSampleBuffer.releaseSampleBuffer(); + mSampleBuffer.release(); mDeferredScreen.release(); - - - for (U32 i = 0; i < 2; i++) + mDeferredDepth.release(); + for (U32 i = 0; i < 3; i++) { mDeferredLight[i].release(); } - for (U32 i = 0; i < 4; i++) + + mEdgeMap.release(); + mGIMap.release(); + mGIMapPost[0].release(); + mGIMapPost[1].release(); + mLuminanceMap.release(); + + for (U32 i = 0; i < 6; i++) { - mSunShadow[i].release(); + mShadow[i].release(); } + for (U32 i = 0; i < 3; i++) { mGlow[i].release(); @@ -635,11 +785,11 @@ void LLPipeline::createGLBuffers() } allocateScreenBuffer(resX,resY); + } if (sRenderDeferred) { - if (!mNoiseMap) { const U32 noiseRes = 128; @@ -659,6 +809,66 @@ void LLPipeline::createGLBuffers() LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise); 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); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + + if (!mLightFunc) + { + U32 lightResX = gSavedSettings.getU32("RenderSpecularResX"); + U32 lightResY = gSavedSettings.getU32("RenderSpecularResY"); + U8* lg = new U8[lightResX*lightResY]; + + for (U32 y = 0; y < lightResY; ++y) + { + for (U32 x = 0; x < lightResX; ++x) + { + //spec func + F32 sa = (F32) x/(lightResX-1); + F32 spec = (F32) y/(lightResY-1); + //lg[y*lightResX+x] = (U8) (powf(sa, 128.f*spec*spec)*255); + + //F32 sp = acosf(sa)/(1.f-spec); + + sa = powf(sa, gSavedSettings.getF32("RenderSpecularExponent")); + F32 a = acosf(sa*0.25f+0.75f); + F32 m = llmax(0.5f-spec*0.5f, 0.001f); + F32 t2 = tanf(a)/m; + t2 *= t2; + + F32 c4a = (3.f+4.f*cosf(2.f*a)+cosf(4.f*a))/8.f; + F32 bd = 1.f/(4.f*m*m*c4a)*powf(F_E, -t2); + + lg[y*lightResX+x] = (U8) (llclamp(bd, 0.f, 1.f)*255); + } + } + + LLImageGL::generateTextures(1, &mLightFunc); + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); + LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_ALPHA, lightResX, lightResY, GL_ALPHA, GL_UNSIGNED_BYTE, lg); + gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); + + delete [] lg; + } + + if (gSavedSettings.getBOOL("RenderDeferredGI")) + { + mGIMap.allocate(512,512,GL_RGBA, TRUE, FALSE); + addDeferredAttachments(mGIMap); + } } } @@ -749,24 +959,24 @@ S32 LLPipeline::getMaxLightingDetail() const S32 LLPipeline::setLightingDetail(S32 level) { - assertInitialized(); - if (level < 0) { - level = gSavedSettings.getS32("RenderLightingDetail"); - } - level = llclamp(level, 0, getMaxLightingDetail()); - if (level != mLightingDetail) - { - gSavedSettings.setS32("RenderLightingDetail", level); - - mLightingDetail = level; - - if (mVertexShadersLoaded == 1) + if (gSavedSettings.getBOOL("RenderLocalLights")) { - LLViewerShaderMgr::instance()->setShaders(); + level = 1; + } + else + { + level = 0; } } + level = llclamp(level, 0, getMaxLightingDetail()); + //Bugfix: If setshaders was called with RenderLocalLights off then enabling RenderLocalLights later will not work. Reloading shaders fixes this. + if (level != mLightingDetail && mVertexShadersLoaded) + { + LLViewerShaderMgr::instance()->setShaders(); + } + mLightingDetail = level; return mLightingDetail; } @@ -1036,6 +1246,21 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) break; } } + + for (U32 i = 0; i < 2; ++i) + { + if (mShadowSpotLight[i] == drawablep) + { + mShadowSpotLight[i] = NULL; + } + + if (mTargetShadowSpotLight[i] == drawablep) + { + mTargetShadowSpotLight[i] = NULL; + } + } + + } U32 LLPipeline::addObject(LLViewerObject *vobj) @@ -1300,7 +1525,7 @@ F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera //get area of circle around node F32 app_angle = atanf(size.length()/dist); F32 radius = app_angle*LLDrawable::sCurPixelAngle; - return radius*radius * 3.14159f; + return radius*radius * F_PI; } void LLPipeline::grabReferences(LLCullResult& result) @@ -1336,8 +1561,10 @@ BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera) BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& max) { - min = LLVector3(F32_MAX, F32_MAX, F32_MAX); - max = LLVector3(-F32_MAX, -F32_MAX, -F32_MAX); + const F32 X = 65536.f; + + min = LLVector3(X,X,X); + max = LLVector3(-X,-X,-X); U32 saved_camera_id = LLViewerCamera::sCurCameraID; LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; @@ -1371,7 +1598,7 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& } -void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip) +void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip, LLPlane* planep) { LLFastTimer t(LLFastTimer::FTM_CULL); LLMemType mt(LLMemType::MTYPE_PIPELINE); @@ -1391,10 +1618,15 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl mScreen.bindTarget(); } - /*glMatrixMode(GL_PROJECTION); + if (sUseOcclusion > 1) + { + gGL.setColorMask(false, false); + } + + glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadMatrixd(gGLLastProjection); - glMatrixMode(GL_MODELVIEW);*/ + glMatrixMode(GL_MODELVIEW); glPushMatrix(); gGLLastMatrix = NULL; glLoadMatrixd(gGLLastModelView); @@ -1405,10 +1637,37 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl LLGLDisable test(GL_ALPHA_TEST); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - if (sUseOcclusion > 1) + + //setup a clip plane in projection matrix for reflection renders (prevents flickering from occlusion culling) + LLViewerRegion* region = gAgent.getRegion(); + LLPlane plane; + + if (planep) { - gGL.setColorMask(false, false); + plane = *planep; } + else + { + if (region) + { + LLVector3 pnorm; + F32 height = region->getWaterHeight(); + if (water_clip < 0) + { //camera is above water, clip plane points up + pnorm.setVec(0,0,1); + plane.setVec(pnorm, -height); + } + else if (water_clip > 0) + { //camera is below water, clip plane points down + pnorm = LLVector3(0,0,-1); + plane.setVec(pnorm, height); + } + } + } + + glh::matrix4f modelview = glh_get_last_modelview(); + glh::matrix4f proj = glh_get_last_projection(); + LLGLUserClipPlane clip(plane, modelview, proj, water_clip != 0 && LLPipeline::sReflectionRender); LLGLDepthTest depth(GL_TRUE, GL_FALSE); @@ -1463,9 +1722,9 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl } - /*glMatrixMode(GL_PROJECTION); + glMatrixMode(GL_PROJECTION); glPopMatrix(); - glMatrixMode(GL_MODELVIEW);*/ + glMatrixMode(GL_MODELVIEW); glPopMatrix(); if (sUseOcclusion > 1) @@ -1477,10 +1736,10 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl { mScreen.flush(); } - else if (LLPipeline::sUseOcclusion > 1) + /*else if (LLPipeline::sUseOcclusion > 1) { glFlush(); - } + }*/ } void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) @@ -1549,33 +1808,34 @@ void LLPipeline::markOccluder(LLSpatialGroup* group) void LLPipeline::doOcclusion(LLCamera& camera) { - LLVertexBuffer::unbind(); + if (LLPipeline::sUseOcclusion > 1 && sCull->hasOcclusionGroups()) + { + 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); + 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); - if (LLPipeline::sUseOcclusion > 1) - { + LLGLDisable cull(GL_CULL_FACE); + for (LLCullResult::sg_list_t::iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter) { LLSpatialGroup* group = *iter; group->doOcclusion(&camera); group->clearOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION); } + + gGL.setColorMask(true, false); } - - gGL.setColorMask(true, false); } BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) @@ -1602,17 +1862,13 @@ void LLPipeline::updateGL() void LLPipeline::rebuildPriorityGroups() { - if(!sAllowRebuildPriorityGroup) - { - return ; - } - sAllowRebuildPriorityGroup = FALSE ; - LLTimer update_timer; LLMemType mt(LLMemType::MTYPE_PIPELINE); assertInitialized(); + + mGroupQ1Locked = true; // Iterate through all drawables on the priority build queue, for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin(); iter != mGroupQ1.end(); ++iter) @@ -1623,10 +1879,18 @@ void LLPipeline::rebuildPriorityGroups() } mGroupQ1.clear(); + mGroupQ1Locked = false; + } void LLPipeline::rebuildGroups() { + if (mGroupQ2.empty()) + { + return; + } + + 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); @@ -1636,33 +1900,30 @@ void LLPipeline::rebuildGroups() 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(); ++iter) + iter != mGroupQ2.end() && count <= min_count; ++iter) { LLSpatialGroup* group = *iter; + last_iter = iter; - if (group->isDead()) + if (!group->isDead()) { - continue; - } - - group->rebuildGeom(); - - if (group->mSpatialPartition->mRenderByGroup) - { - count++; - } + group->rebuildGeom(); - group->clearState(LLSpatialGroup::IN_BUILD_Q2); - - if (count > min_count) - { - ++iter; - break; + if (group->mSpatialPartition->mRenderByGroup) + { + count++; + } } + + group->clearState(LLSpatialGroup::IN_BUILD_Q2); } - mGroupQ2.erase(mGroupQ2.begin(), iter); + mGroupQ2.erase(mGroupQ2.begin(), ++last_iter); + + mGroupQ2Locked = false; updateMovedList(mMovedBridge); } @@ -1774,41 +2035,39 @@ void LLPipeline::updateGeom(F32 max_dtime) void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) { LLMemType mt(LLMemType::MTYPE_PIPELINE); - if(!drawablep || drawablep->isDead()) + + if(drawablep && !drawablep->isDead()) { - return; - } - - 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()) + if (drawablep->isSpatialBridge()) { - LLDrawable* rootparent = root->getParent(); - if (rootparent) // this IS sometimes NULL + 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()) { - LLViewerObject *vobj = rootparent->getVObj(); - llassert(vobj); // trying to catch a bad assumption - if (vobj) // this test may not be needed, see above + LLDrawable* rootparent = root->getParent(); + if (rootparent) // this IS sometimes NULL { - if (vobj->isAvatar() && ((LLVOAvatar*)vobj)->isImpostor()) + LLViewerObject *vobj = rootparent->getVObj(); + llassert(vobj); // trying to catch a bad assumption + if (vobj) // this test may not be needed, see above { - return; + if (vobj->isAvatar() && ((LLVOAvatar*)vobj)->isImpostor()) + { + return; + } } } } + sCull->pushBridge((LLSpatialBridge*) drawablep); + } + else + { + sCull->pushDrawable(drawablep); } - - sCull->pushBridge((LLSpatialBridge*) drawablep); - } - else - { - sCull->pushDrawable(drawablep); - } - drawablep->setVisible(camera); + drawablep->setVisible(camera); + } } void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) @@ -1955,6 +2214,8 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) { if (!group->isState(LLSpatialGroup::IN_BUILD_Q1)) { + llassert_always(!mGroupQ1Locked); + mGroupQ1.push_back(group); group->setState(LLSpatialGroup::IN_BUILD_Q1); @@ -1971,6 +2232,7 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) } else if (!group->isState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1)) { + llassert_always(!mGroupQ2Locked); //llerrs << "Non-priority updates not yet supported!" << llendl; if (std::find(mGroupQ2.begin(), mGroupQ2.end(), group) != mGroupQ2.end()) { @@ -2258,7 +2520,8 @@ void renderScriptedBeacons(LLDrawable* drawablep) { 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), gSavedSettings.getS32("DebugBeaconLineWidth")); + static const LLCachedControl debug_beacon_line_width("DebugBeaconLineWidth",1); + gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), debug_beacon_line_width); } if (gPipeline.sRenderHighlight) @@ -2284,7 +2547,8 @@ void renderScriptedTouchBeacons(LLDrawable* drawablep) { 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), gSavedSettings.getS32("DebugBeaconLineWidth")); + static const LLCachedControl debug_beacon_line_width("DebugBeaconLineWidth",1); + gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), debug_beacon_line_width); } if (gPipeline.sRenderHighlight) @@ -2309,7 +2573,8 @@ void renderPhysicalBeacons(LLDrawable* drawablep) { 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), gSavedSettings.getS32("DebugBeaconLineWidth")); + static const LLCachedControl debug_beacon_line_width("DebugBeaconLineWidth",1); + gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(0.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), debug_beacon_line_width); } if (gPipeline.sRenderHighlight) @@ -2334,7 +2599,8 @@ void renderParticleBeacons(LLDrawable* drawablep) 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), gSavedSettings.getS32("DebugBeaconLineWidth")); + static const LLCachedControl debug_beacon_line_width("DebugBeaconLineWidth",1); + gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", light_blue, LLColor4(1.f, 1.f, 1.f, 0.5f), debug_beacon_line_width); } if (gPipeline.sRenderHighlight) @@ -2548,12 +2814,14 @@ void LLPipeline::postSort(LLCamera& camera) LLVector3 pos = gAgent.getPosAgentFromGlobal(pos_global); if (gPipeline.sRenderBeacons) { + // LLAudioChannel* channel = sourcep->getChannel(); bool const is_playing = channel && channel->isPlaying(); S32 width = 2; LLColor4 color = LLColor4(0.f, 0.f, 1.f, 0.5f); if (is_playing) { + static const LLCachedControl debug_beacon_line_width("DebugBeaconLineWidth",1); llassert(!sourcep->isMuted()); F32 gain = sourcep->getGain() * channel->getSecondaryGain(); if (gain == 0.f) @@ -2563,18 +2831,20 @@ void LLPipeline::postSort(LLCamera& camera) else if (gain == 1.f) { color = LLColor4(0.f, 1.f, 0.f, 0.5f); - width = gSavedSettings.getS32("DebugBeaconLineWidth"); + width = debug_beacon_line_width; } else { color = LLColor4(1.f, 1.f, 0.f, 0.5f); - width = 1 + gain * (gSavedSettings.getS32("DebugBeaconLineWidth") - 1); + width = 1 + gain * (debug_beacon_line_width - 1); } } else if (sourcep->isMuted()) color = LLColor4(0.f, 1.f, 1.f, 0.5f); gObjectList.addDebugBeacon(pos, "", color, LLColor4(1.f, 1.f, 1.f, 0.5f), width); } + // + //gObjectList.addDebugBeacon(pos, "", LLColor4(1.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), debug_beacon_line_width); } // now deal with highlights for all those seeable sound sources forAllVisibleDrawables(renderSoundHighlights); @@ -2630,7 +2900,8 @@ void render_hud_elements() gGL.color4f(1,1,1,1); if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + static const LLCachedControl fsaa_samples("RenderFSAASamples",0); + LLGLEnable multisample(fsaa_samples > 0 ? GL_MULTISAMPLE_ARB : 0); gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d() // Draw the tracking overlays @@ -2641,15 +2912,8 @@ void render_hud_elements() LLViewerParcelMgr::getInstance()->render(); LLViewerParcelMgr::getInstance()->renderParcelCollision(); - // Render debugging beacons. - //gObjectList.renderObjectBeacons(); - - //TO-DO: - //V2 moved this line from LLPipeline::renderGeom - //Uncomment once multisample z-buffer issues are figured out on ati cards. - LLHUDObject::renderAll(); - - //gObjectList.resetObjectBeacons(); + // Render name tags. + LLHUDObject::renderAll(); } else if (gForceRenderLandFence) { @@ -2792,7 +3056,8 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) glMatrixMode(GL_MODELVIEW); LLGLSPipeline gls_pipeline; - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + static const LLCachedControl fsaa_samples("RenderFSAASamples",0); + LLGLEnable multisample(fsaa_samples > 0 ? GL_MULTISAMPLE_ARB : 0); LLGLState gls_color_material(GL_COLOR_MATERIAL, mLightingDetail < 2); @@ -2971,10 +3236,6 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) { // Render debugging beacons. gObjectList.renderObjectBeacons(); - //TO-DO: - //V2 moved this line to LLPipeline::render_hud_elements - //Migrate once multisample z-buffer issues are figured out on ati cards. - //LLHUDObject::renderAll(); gObjectList.resetObjectBeacons(); } else @@ -3032,7 +3293,8 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) } } - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + static const LLCachedControl fsaa_samples("RenderFSAASamples",0); + LLGLEnable multisample(fsaa_samples > 0 ? GL_MULTISAMPLE_ARB : 0); LLVertexBuffer::unbind(); @@ -3120,7 +3382,8 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) LLGLEnable cull(GL_CULL_FACE); - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + static const LLCachedControl fsaa_samples("RenderFSAASamples",0); + LLGLEnable multisample(fsaa_samples > 0 ? GL_MULTISAMPLE_ARB : 0); calcNearbyLights(camera); setupHWLights(NULL); @@ -3203,33 +3466,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) gGLLastMatrix = NULL; glLoadMatrixd(gGLModelView); - //TO-DO: - //V2 moved block to LLPipeline::renderDeferredLighting - //Migrate once multisample z-buffer issues are figured out on ati cards. - /*if(!sImpostorRender) - { - renderHighlights(); - mHighlightFaces.clear(); - - renderDebug(); - - LLVertexBuffer::unbind(); - - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) - { - // Render debugging beacons. - gObjectList.renderObjectBeacons(); - LLHUDObject::renderAll(); - gObjectList.resetObjectBeacons(); - } - else - { - // Make sure particle effects disappear - LLHUDObject::renderAllForTimer(); - } - }*/ - //END - if (occlude) { occlude = FALSE; @@ -3357,7 +3593,7 @@ void LLPipeline::renderDebug() for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) { LLSpatialBridge* bridge = *i; - if (!bridge->isDead() && !bridge->isState(LLSpatialGroup::OCCLUDED) && hasRenderType(bridge->mDrawableType)) + if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) { glPushMatrix(); glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); @@ -3368,79 +3604,113 @@ void LLPipeline::renderDebug() if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { + 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,1,0, - 0,1,1, - 1,0,1, - 1,1,1, - 1,0,0, - 0,1,0, - 0,0,1, - 0,0,0 + 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++) { - gGL.color3fv(col+i*3); - - gGL.begin(LLRender::LINES); - LLVector3* frust = mShadowCamera[i].mAgentFrustum; - 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); - - if (i < 4) + if (i > 3) + { //render shadow frusta as volumes + if (mShadowFrustPoints[i-4].empty()) { - LLVector3* ext = mShadowExtents[i]; - - LLVector3 box[] = - { - LLVector3(ext[0][0], ext[0][1], ext[0][2]), - LLVector3(ext[1][0], ext[0][1], ext[0][2]), - LLVector3(ext[1][0], ext[1][1], ext[0][2]), - LLVector3(ext[0][0], ext[1][1], ext[0][2]), - LLVector3(ext[0][0], ext[0][1], ext[1][2]), - LLVector3(ext[1][0], ext[0][1], ext[1][2]), - LLVector3(ext[1][0], ext[1][1], ext[1][2]), - LLVector3(ext[0][0], ext[1][1], ext[1][2]), - }; - - gGL.vertex3fv(box[0].mV); gGL.vertex3fv(box[1].mV); - gGL.vertex3fv(box[1].mV); gGL.vertex3fv(box[2].mV); - gGL.vertex3fv(box[2].mV); gGL.vertex3fv(box[3].mV); - gGL.vertex3fv(box[3].mV); gGL.vertex3fv(box[0].mV); + continue; + } - gGL.vertex3fv(box[4].mV); gGL.vertex3fv(box[5].mV); - gGL.vertex3fv(box[5].mV); gGL.vertex3fv(box[6].mV); - gGL.vertex3fv(box[6].mV); gGL.vertex3fv(box[7].mV); - gGL.vertex3fv(box[7].mV); gGL.vertex3fv(box[4].mV); + 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.vertex3fv(box[0].mV); gGL.vertex3fv(box[4].mV); - gGL.vertex3fv(box[1].mV); gGL.vertex3fv(box[5].mV); - gGL.vertex3fv(box[2].mV); gGL.vertex3fv(box[6].mV); - gGL.vertex3fv(box[3].mV); gGL.vertex3fv(box[7].mV); + + 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(); } - gGL.end(); - - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + + 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(); + } + + } + + /*for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -3455,7 +3725,7 @@ void LLPipeline::renderDebug() } } } - } + }*/ } } @@ -3495,13 +3765,19 @@ void LLPipeline::renderDebug() if (mRenderDebugMask & LLPipeline::RENDER_DEBUG_BUILD_QUEUE) { U32 count = 0; - U32 size = mBuildQ2.size(); + 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(); + glLoadMatrixd(gGLModelView); + gGLLastMatrix = NULL; + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); iter != mGroupQ2.end(); ++iter) { LLSpatialGroup* group = *iter; @@ -3523,7 +3799,7 @@ void LLPipeline::renderDebug() glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); } - F32 alpha = (F32) (size-count)/size; + F32 alpha = llclamp((F32) (size-count)/size, 0.f, 1.f); LLVector2 c(1.f-alpha, alpha); @@ -3531,7 +3807,7 @@ void LLPipeline::renderDebug() ++count; - col.set(c.mV[0], c.mV[1], 0, alpha*0.5f+0.1f); + col.set(c.mV[0], c.mV[1], 0, alpha*0.5f+0.5f); group->drawObjectBox(col); if (bridge) @@ -3539,8 +3815,10 @@ void LLPipeline::renderDebug() gGL.popMatrix(); } } + + gGL.popMatrix(); } - + gGL.flush(); } @@ -3757,7 +4035,7 @@ void LLPipeline::rebuildPools() max_count--; } - if (gAgent.getAvatarObject()) + if (isAgentAvatarValid()) { gAgent.getAvatarObject()->rebuildHUD(); } @@ -4052,16 +4330,19 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) light_pos.normalize(); + LLLightState* light = gGL.getLight(1); + mHWLightColors[1] = diffuse; - glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse.mV); - glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_POSITION, light_pos.mV); - glLightf (GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f); - glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f); - glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f); - glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 0.0f); - glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 180.0f); + + 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) { @@ -4092,22 +4373,28 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) backlight_diffuse *= backlight_mag / max_component; mHWLightColors[1] = backlight_diffuse; - glLightfv(GL_LIGHT1, GL_POSITION, backlight_pos.mV); // this is just sun/moon direction - glLightfv(GL_LIGHT1, GL_DIFFUSE, backlight_diffuse.mV); - glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV); - glLightf (GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f); - glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f); - glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f); - glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 0.0f); - glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 180.0f); + + 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; - glLightfv(GL_LIGHT1, GL_DIFFUSE, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV); + + light->setDiffuse(LLColor4::black); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); } } @@ -4291,15 +4578,17 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) LLVector4 light_pos(mSunDir, 0.0f); LLColor4 light_diffuse = mSunDiffuse; mHWLightColors[0] = light_diffuse; - glLightfv(GL_LIGHT0, GL_POSITION, light_pos.mV); // this is just sun/moon direction - glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse.mV); - glLightfv(GL_LIGHT0, GL_AMBIENT, LLColor4::black.mV); - glLightfv(GL_LIGHT0, GL_SPECULAR, LLColor4::black.mV); - glLightf (GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0f); - glLightf (GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0f); - glLightf (GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.0f); - glLightf (GL_LIGHT0, GL_SPOT_EXPONENT, 0.0f); - glLightf (GL_LIGHT0, GL_SPOT_CUTOFF, 180.0f); + + LLLightState* light = gGL.getLight(0); + light->setPosition(light_pos); + light->setDiffuse(light_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); } // Light 1 = Backlight (for avatars) @@ -4357,21 +4646,46 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) float linatten = x / (light_radius); // % of brightness at radius mHWLightColors[cur_light] = light_color; - S32 gllight = GL_LIGHT0+cur_light; - glLightfv(gllight, GL_POSITION, light_pos_gl.mV); - glLightfv(gllight, GL_DIFFUSE, light_color.mV); - glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); - glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f); - glLightf (gllight, GL_LINEAR_ATTENUATION, linatten); - glLightf (gllight, GL_QUADRATIC_ATTENUATION, 0.0f); - //Point lights + 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) { - glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); - glLightf (gllight, GL_SPOT_CUTOFF, 180.0f); + light_state->setLinearAttenuation(light_radius*1.5f); + light_state->setQuadraticAttenuation(light->getLightFalloff()*0.5f+1.f); + } + else + { + light_state->setLinearAttenuation(linatten); + light_state->setQuadraticAttenuation(0.f); + } + + static const LLCachedControl render_spot_lights_in_nondeferred("RenderSpotLightsInNondeferred",false); + if (light->isLightSpotlight() // directional (spot-)light + && (LLPipeline::sRenderDeferred || render_spot_lights_in_nondeferred)) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on + { + LLVector3 spotparams = light->getSpotLightParams(); + 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); + + light_state->setSpecular(LLColor4::black); + } + 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 float specular[] = {0.f, 0.f, 0.f, 1.f}; - glLightfv(gllight, GL_SPECULAR, specular); + const LLColor4 specular(0.f, 0.f, 0.f, 1.f); + light_state->setSpecular(specular); //llinfos << "boring light" << llendl; } cur_light++; @@ -4384,12 +4698,12 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) for ( ; cur_light < 8 ; cur_light++) { mHWLightColors[cur_light] = LLColor4::black; - S32 gllight = GL_LIGHT0+cur_light; - glLightfv(gllight, GL_DIFFUSE, LLColor4::black.mV); - glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); - glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); - } + LLLightState* light = gGL.getLight(cur_light); + light->setDiffuse(LLColor4::black); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + } if (isAgentAvatarValid() && gAgent.getAvatarObject()->mSpecialRenderMode == 3) { @@ -4405,23 +4719,24 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) float linatten = x / (light_radius); // % of brightness at radius mHWLightColors[2] = light_color; - S32 gllight = GL_LIGHT2; - glLightfv(gllight, GL_POSITION, light_pos_gl.mV); - glLightfv(gllight, GL_DIFFUSE, light_color.mV); - glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); - glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); - glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f); - glLightf (gllight, GL_LINEAR_ATTENUATION, linatten); - glLightf (gllight, GL_QUADRATIC_ATTENUATION, 0.0f); - glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); - glLightf (gllight, GL_SPOT_CUTOFF, 180.0f); + LLLightState* light = gGL.getLight(2); + + 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); } // Init GL state glDisable(GL_LIGHTING); - for (S32 gllight=GL_LIGHT0; gllight<=GL_LIGHT7; gllight++) + for (S32 i = 0; i < 8; ++i) { - glDisable(gllight); + gGL.getLight(i)->disable(); } mLightMask = 0; } @@ -4444,15 +4759,16 @@ void LLPipeline::enableLights(U32 mask) { for (S32 i=0; i<8; i++) { + LLLightState* light = gGL.getLight(i); if (mask & (1<enable(); + light->setDiffuse(mHWLightColors[i]); } else { - glDisable(GL_LIGHT0 + i); - glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, LLColor4::black.mV); + light->disable(); + light->setDiffuse(LLColor4::black); } } } @@ -4473,7 +4789,6 @@ void LLPipeline::enableLightsStatic() if (mLightingDetail >= 2) { mask |= mLightMovingMask; // Hardware moving lights - glColor4f(0.f, 0.f, 0.f, 1.0f); // no local lighting by default } else { @@ -4487,10 +4802,7 @@ void LLPipeline::enableLightsDynamic() assertInitialized(); U32 mask = 0xff & (~2); // Local lights enableLights(mask); - if (mLightingDetail >= 2) - { - glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default - } + LLVOAvatar* avatarp = gAgent.getAvatarObject(); @@ -4530,16 +4842,11 @@ void LLPipeline::enableLightsFullbright(const LLColor4& color) enableLights(mask); glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV); - /*if (mLightingDetail >= 2) - { - glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default - }*/ } void LLPipeline::disableLights() { enableLights(0); // no lighting (full bright) - glColor4f(1.f, 1.f, 1.f, 1.f); // lighting color = white by default } //============================================================================ @@ -4790,7 +5097,10 @@ void LLPipeline::toggleRenderPairedTypeControl(void *data) for(U8 i = 1 ;i < NUM_RENDER_TYPES; ++i) { if( typeflags & (1ULL<mNameText.notNull() && av->mNameText->lineSegmentIntersect(start, local_end, position)) + if (av->mNameText.notNull() + && av->mNameText->lineSegmentIntersect(start, local_end, position)) { drawable = av->mDrawable; local_end = position; @@ -5163,8 +5474,7 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable) for (S32 i = 0; i < drawable->getNumFaces(); i++) { LLFace* facep = drawable->getFace(i); - facep->mVertexBuffer = NULL; - facep->mLastVertexBuffer = NULL; + facep->clearVertexBuffer(); } } @@ -5350,7 +5660,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b if (res_mod > 1) { - tc2 /= (F32) res_mod; + tc2 /= (F32) res_mod.get(); } gGL.setColorMask(true, true); @@ -5436,8 +5746,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b gGlowExtractProgram.bind(); static const LLCachedControl minLum("RenderGlowMinLuminance",2.5); - static const LLCachedControl maxAlpha("RenderGlowMaxExtractAlpha",0.065f); - static const LLCachedControl warmthAmount("RenderGlowWarmthAmount",0.0f); + static const LLCachedControl maxAlpha("RenderGlowMaxExtractAlpha",0.065f); + static const LLCachedControl warmthAmount("RenderGlowWarmthAmount",0.0f); static const LLCachedControl lumWeights("RenderGlowLumWeights",LLVector3(.299f,.587f,.114f)); static const LLCachedControl warmthWeights("RenderGlowWarmthWeights",LLVector3(1.f,.5f,.7f)); gGlowExtractProgram.uniform1f("minLuminance", llmax(minLum.get(),0.0f)); @@ -5477,8 +5787,6 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b tc1.setVec(0,0); tc2.setVec(2,2); - - // power of two between 1 and 1024 static const LLCachedControl glowResPow("RenderGlowResolutionPow",9); const U32 glow_res = llmax(1, @@ -5529,7 +5837,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b 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); @@ -5551,15 +5859,40 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b gViewerWindow->setupViewport(); + tc2.setVec((F32) gViewerWindow->getWindowDisplayWidth(), + (F32) gViewerWindow->getWindowDisplayHeight()); + gGL.flush(); - { - LLVertexBuffer::unbind(); + LLVertexBuffer::unbind(); + if (LLPipeline::sRenderDeferred && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) + { + LLGLDisable blend(GL_BLEND); + bindDeferredShader(gDeferredGIFinalProgram); + + S32 channel = gDeferredGIFinalProgram.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); + if (channel > -1) + { + mScreen.bindTexture(0, channel); + } + + 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); - tc2.setVec((F32) gViewerWindow->getWindowDisplayWidth(), - (F32) gViewerWindow->getWindowDisplayHeight()); + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3,-1); + + gGL.end(); + + unbindDeferredShader(gDeferredGIFinalProgram); + } + else + { if (res_mod > 1) { @@ -5600,14 +5933,16 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b gGL.getTexUnit(0)->bind(&mGlow[1]); gGL.getTexUnit(1)->activate(); gGL.getTexUnit(1)->enable(LLTexUnit::TT_RECT_TEXTURE); - + + //tex unit 1 gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); gGL.getTexUnit(1)->bind(&mScreen); gGL.getTexUnit(1)->activate(); - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + static const LLCachedControl fsaa_samples("RenderFSAASamples",0); + LLGLEnable multisample(fsaa_samples > 0 ? GL_MULTISAMPLE_ARB : 0); buff->setBuffer(mask); buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3); @@ -5618,9 +5953,6 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); - //TO-DO: - //V2 requires this for hover text and such since they have been pulled out of geom render. - //Do this when multisample z-buffer issues are figured out if (LLRenderTarget::sUseFBO) { //copy depth buffer from mScreen to framebuffer LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), @@ -5642,8 +5974,17 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b } -void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) +void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRenderTarget* gi_source, LLRenderTarget* last_gi_post, U32 noise_map) { + //LLFastTimer t(FTM_BIND_DEFERRED); + + if (noise_map == 0xFFFFFFFF) + { + noise_map = mNoiseMap; + } + + LLGLState::checkTextureChannels(); + shader.bind(); S32 channel = 0; channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); @@ -5651,7 +5992,6 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) { mDeferredScreen.bindTexture(0,channel); gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); @@ -5668,26 +6008,164 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); + if (gi_source) + { + BOOL has_gi = FALSE; + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_DIFFUSE); + if (channel > -1) + { + has_gi = TRUE; + gi_source->bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_SPECULAR); + if (channel > -1) + { + has_gi = TRUE; + gi_source->bindTexture(1, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_NORMAL); + if (channel > -1) + { + has_gi = TRUE; + gi_source->bindTexture(2, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_MIN_POS); + if (channel > -1) + { + has_gi = TRUE; + gi_source->bindTexture(1, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_MAX_POS); + if (channel > -1) + { + has_gi = TRUE; + gi_source->bindTexture(3, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_DIFFUSE); + if (channel > -1) + { + has_gi = TRUE; + last_gi_post->bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_NORMAL); + if (channel > -1) + { + has_gi = TRUE; + last_gi_post->bindTexture(2, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MAX_POS); + if (channel > -1) + { + has_gi = TRUE; + last_gi_post->bindTexture(1, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MIN_POS); + if (channel > -1) + { + has_gi = TRUE; + last_gi_post->bindTexture(3, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_DEPTH); + if (channel > -1) + { + has_gi = TRUE; + gGL.getTexUnit(channel)->bind(gi_source, TRUE); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + stop_glerror(); + + glTexParameteri(LLTexUnit::getInternalType(mGIMap.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + glTexParameteri(LLTexUnit::getInternalType(mGIMap.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA); + + stop_glerror(); + } + + if (has_gi) + { + F32 range_x = llmin(mGIRange.mV[0], 1.f); + F32 range_y = llmin(mGIRange.mV[1], 1.f); + + LLVector2 scale(range_x,range_y); + + LLVector2 kern[25]; + + for (S32 i = 0; i < 5; ++i) + { + for (S32 j = 0; j < 5; ++j) + { + S32 idx = i*5+j; + kern[idx].mV[0] = (i-2)*0.5f; + kern[idx].mV[1] = (j-2)*0.5f; + kern[idx].scaleVec(scale); + } + } + + shader.uniform2fv("gi_kern", 25, (F32*) kern); + shader.uniformMatrix4fv("gi_mat", 1, FALSE, mGIMatrix.m); + shader.uniformMatrix4fv("gi_mat_proj", 1, FALSE, mGIMatrixProj.m); + shader.uniformMatrix4fv("gi_inv_proj", 1, FALSE, mGIInvProj.m); + shader.uniformMatrix4fv("gi_norm_mat", 1, FALSE, mGINormalMatrix.m); + } + } + + /*channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); if (channel > -1) { mDeferredScreen.bindTexture(3, channel); - } + }*/ channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); if (channel > -1) { - gGL.getTexUnit(channel)->bind(&mDeferredScreen, TRUE); + gGL.getTexUnit(channel)->bind(&mDeferredDepth, TRUE); gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + stop_glerror(); + + glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA); + + stop_glerror(); + + glh::matrix4f projection = glh_get_current_projection(); + glh::matrix4f inv_proj = projection.inverse(); + + shader.uniformMatrix4fv("inv_proj", 1, FALSE, inv_proj.m); + shader.uniform4f("viewport", (F32) gGLViewport[0], + (F32) gGLViewport[1], + (F32) gGLViewport[2], + (F32) gGLViewport[3]); } channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NOISE); if (channel > -1) { - gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); + gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, noise_map); gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHTFUNC); + if (channel > -1) + { + gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); + } + stop_glerror(); channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE); @@ -5697,16 +6175,76 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE); + if (channel > -1) + { + gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mLuminanceMap.getTexture(), true); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_BLOOM); + if (channel > -1) + { + mGlow[1].bindTexture(0, channel); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + if (channel > -1) + { + gi_source->bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_EDGE, LLTexUnit::TT_RECT_TEXTURE); + if (channel > -1) + { + mEdgeMap.bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + if (channel > -1) + { + mDeferredLight[1].bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + if (channel > -1) + { + mDeferredLight[2].bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + + stop_glerror(); for (U32 i = 0; i < 4; i++) + { + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE); + stop_glerror(); + if (channel > -1) + { + stop_glerror(); + gGL.getTexUnit(channel)->bind(&mShadow[i], TRUE); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + stop_glerror(); + + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); + stop_glerror(); + } + } + + for (U32 i = 4; i < 6; i++) { channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i); stop_glerror(); if (channel > -1) { stop_glerror(); - gGL.getTexUnit(channel)->bind(&mSunShadow[i], TRUE); + gGL.getTexUnit(channel)->bind(&mShadow[i], TRUE); gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); stop_glerror(); @@ -5719,17 +6257,19 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) stop_glerror(); - F32 mat[64]; + 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]; } - shader.uniformMatrix4fv("shadow_matrix[0]", 4, FALSE, mat); - shader.uniformMatrix4fv("shadow_matrix", 4, FALSE, mat); + shader.uniformMatrix4fv("shadow_matrix[0]", 6, FALSE, mat); + shader.uniformMatrix4fv("shadow_matrix", 6, FALSE, mat); stop_glerror(); @@ -5758,11 +6298,33 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) static const LLCachedControl render_shadow_noise("RenderShadowNoise",-.0001f); static const LLCachedControl render_shadow_blur_size("RenderShadowBlurSize",.7f); static const LLCachedControl render_ssao_scale("RenderSSAOScale",500); - static const LLCachedControl render_ssao_max_scale("RenderSSAOMaxScale",60); + static const LLCachedControl render_ssao_max_scale("RenderSSAOMaxScale",200); static const LLCachedControl render_ssao_factor("RenderSSAOFactor",.3f); - static const LLCachedControl render_ssao_effect("RenderSSAOEffect",LLVector3(.4f,1,0)); + static const LLCachedControl render_ssao_effect("RenderSSAOEffect",LLVector3(.4f,1.f,0.f)); static const LLCachedControl render_deferred_alpha_soft("RenderDeferredAlphaSoften",.75f); - + static const LLCachedControl render_shadow_offset_error("RenderShadowOffsetError",0.f); + static const LLCachedControl render_shadow_bias_error("RenderShadowBiasError",0.f); + static const LLCachedControl render_shadow_offset("RenderShadowOffset",.1f); + static const LLCachedControl render_shadow_bias("RenderShadowBias",0.f); + static const LLCachedControl render_spot_shadow_offset("RenderSpotShadowOffset",.4f); + static const LLCachedControl render_spot_shadow_bias("RenderSpotShadowBias",0.f); + + static const LLCachedControl render_luminance_scale("RenderLuminanceScale",1.f); + static const LLCachedControl render_sun_luminance_scale("RenderSunLuminanceScale",1.f); + static const LLCachedControl render_sun_luminance_offset("RenderSunLuminanceOffset",0.f); + static const LLCachedControl render_luminance_detail("RenderLuminanceDetail",16.f); + static const LLCachedControl render_gi_range("RenderGIRange",96.f); + static const LLCachedControl render_gi_brightness("RenderGIBrightness",.3f); + static const LLCachedControl render_gi_luminance("RenderGILuminance",.075f); + static const LLCachedControl render_gi_blur_edge_weight("RenderGIBlurEdgeWeight",.8f); + static const LLCachedControl render_gi_blur_brightness("RenderGIBlurBrightness",1.025f); + static const LLCachedControl render_gi_render_gi_noise("RenderGINoise",.7); + static const LLCachedControl render_gi_attenuation("RenderGIAttenuation",.1f); + static const LLCachedControl render_gi_ambiance("RenderGIAmbiance",.5f); + static const LLCachedControl render_edge_depth_cutoff("RenderEdgeDepthCutoff",.01f); + static const LLCachedControl render_edge_norm_cutoff("RenderEdgeNormCutoff",.25f); + + shader.uniform1f("sun_wash", render_deferred_sun_wash); shader.uniform1f("shadow_noise", render_shadow_noise); shader.uniform1f("blur_size", render_shadow_blur_size); @@ -5784,9 +6346,34 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) matrix_nondiag, matrix_nondiag, matrix_diag}; shader.uniformMatrix3fv("ssao_effect_mat", 1, GL_FALSE, ssao_effect_mat); + F32 shadow_offset_error = 1.f + render_shadow_offset_error * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); + F32 shadow_bias_error = 1.f + render_shadow_bias_error * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); + shader.uniform2f("screen_res", mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); shader.uniform1f("near_clip", LLViewerCamera::getInstance()->getNear()*2.f); - shader.uniform1f("alpha_soften", render_deferred_alpha_soft); + shader.uniform1f ("shadow_offset", render_shadow_offset*shadow_offset_error); + shader.uniform1f("shadow_bias", render_shadow_bias*shadow_bias_error); + shader.uniform1f ("spot_shadow_offset", render_spot_shadow_offset); + shader.uniform1f("spot_shadow_bias", render_spot_shadow_bias); + + shader.uniform1f("lum_scale", render_luminance_scale); + shader.uniform1f("sun_lum_scale", render_sun_luminance_scale); + shader.uniform1f("sun_lum_offset", render_sun_luminance_offset); + shader.uniform1f("lum_lod", render_luminance_detail); + shader.uniform1f("gi_range", render_gi_range); + shader.uniform1f("gi_brightness", render_gi_brightness); + shader.uniform1f("gi_luminance", render_gi_luminance); + shader.uniform1f("gi_edge_weight", render_gi_blur_edge_weight); + shader.uniform1f("gi_blur_brightness", render_gi_blur_brightness); + shader.uniform1f("gi_sample_width", mGILightRadius); + shader.uniform1f("gi_noise", render_gi_render_gi_noise); + shader.uniform1f("gi_attenuation", render_gi_attenuation); + shader.uniform1f("gi_ambiance", render_gi_ambiance); + shader.uniform2f("shadow_res", mShadow[0].getWidth(), mShadow[0].getHeight()); + shader.uniform2f("proj_shadow_res", mShadow[4].getWidth(), mShadow[4].getHeight()); + shader.uniform1f("depth_cutoff", render_edge_depth_cutoff); + shader.uniform1f("norm_cutoff", render_edge_norm_cutoff); + if (shader.getUniformLocation("norm_mat") >= 0) { glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose(); @@ -5801,131 +6388,238 @@ void LLPipeline::renderDeferredLighting() return; } - LLViewerCamera* camera = LLViewerCamera::getInstance(); - /*{ + { + + LLViewerCamera* camera = LLViewerCamera::getInstance(); + { LLGLDepthTest depth(GL_TRUE); mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); - }*/ + } - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + static const LLCachedControl fsaa_samples("RenderFSAASamples",0); + LLGLEnable multisample(fsaa_samples > 0 ? GL_MULTISAMPLE_ARB : 0); - if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) - { - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); - } - - //ati doesn't seem to love actually using the stencil buffer on FBO's - LLGLEnable stencil(GL_STENCIL_TEST); - glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - - gGL.setColorMask(true, true); - - //mDeferredLight[0].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), - // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); - - //draw a cube around every light - LLVertexBuffer::unbind(); - - //glBlendFunc(GL_ONE, GL_ONE); - LLGLEnable cull(GL_CULL_FACE); - LLGLEnable blend(GL_BLEND); - - glh::matrix4f mat = glh_copy_matrix(gGLModelView); - - F32 vert[] = - { - -1,1, - -1,-3, - 3,1, - }; - glVertexPointer(2, GL_FLOAT, 0, vert); - glColor3f(1,1,1); - - { - setupHWLights(NULL); //to set mSunDir; - LLVector4 dir(mSunDir, 0.f); - glh::vec4f tc(dir.mV); - mat.mult_matrix_vec(tc); - glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0); - } - - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - mDeferredLight[0].bindTarget(); - - //Sun shadows. - { - bindDeferredShader(gDeferredSunProgram); - - glClearColor(1,1,1,1); - mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT); - glClearColor(0,0,0,0); - - glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); - - const U32 slice = 32; - F32 offset[slice*3]; - for (U32 i = 0; i < 4; i++) + if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) { - for (U32 j = 0; j < 8; j++) + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); + } + + //ati doesn't seem to love actually using the stencil buffer on FBO's + LLGLEnable stencil(GL_STENCIL_TEST); + glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + + gGL.setColorMask(true, true); + + //draw a cube around every light + LLVertexBuffer::unbind(); + + LLGLEnable cull(GL_CULL_FACE); + LLGLEnable blend(GL_BLEND); + + glh::matrix4f mat = glh_copy_matrix(gGLModelView); + + F32 vert[] = + { + -1,1, + -1,-3, + 3,1, + }; + glVertexPointer(2, GL_FLOAT, 0, vert); + glColor3f(1,1,1); + + { + setupHWLights(NULL); //to set mSunDir; + LLVector4 dir(mSunDir, 0.f); + glh::vec4f tc(dir.mV); + mat.mult_matrix_vec(tc); + glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0); + } + + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + static const LLCachedControl render_deferred_ssao("RenderDeferredSSAO",false); + static const LLCachedControl render_shadow_detail("RenderShadowDetail",0); + if (render_deferred_ssao || render_shadow_detail > 0) + { + mDeferredLight[0].bindTarget(); + { //paint shadow/SSAO light map (direct lighting lightmap) + //LLFastTimer ftm(FTM_SUN_SHADOW); + bindDeferredShader(gDeferredSunProgram, 0); + + glClearColor(1,1,1,1); + mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT); + glClearColor(0,0,0,0); + + glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); + + const U32 slice = 32; + F32 offset[slice*3]; + for (U32 i = 0; i < 4; i++) + { + for (U32 j = 0; j < 8; j++) + { + glh::vec3f v; + v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); + v.normalize(); + inv_trans.mult_matrix_vec(v); + v.normalize(); + offset[(i*8+j)*3+0] = v.v[0]; + offset[(i*8+j)*3+1] = v.v[2]; + offset[(i*8+j)*3+2] = v.v[1]; + } + } + + gDeferredSunProgram.uniform3fv("offset", slice, offset); + gDeferredSunProgram.uniform2f("screenRes", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight()); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + stop_glerror(); + } + + unbindDeferredShader(gDeferredSunProgram); + } + mDeferredLight[0].flush(); + } + + static const LLCachedControl render_deferred_blur_light("RenderDeferredBlurLight",false); + static const LLCachedControl render_shadow_gi("RenderDeferredGI",false); + { //global illumination specific block (still experimental) + if (render_deferred_blur_light && + render_shadow_gi) { - glh::vec3f v; - v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); - v.normalize(); - inv_trans.mult_matrix_vec(v); - v.normalize(); - offset[(i*8+j)*3+0] = v.v[0]; - offset[(i*8+j)*3+1] = v.v[2]; - offset[(i*8+j)*3+2] = v.v[1]; + //LLFastTimer ftm(FTM_EDGE_DETECTION); + //generate edge map + LLGLDisable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); + LLGLDepthTest depth(GL_FALSE); + LLGLDisable stencil(GL_STENCIL_TEST); + + { + gDeferredEdgeProgram.bind(); + mEdgeMap.bindTarget(); + bindDeferredShader(gDeferredEdgeProgram); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + unbindDeferredShader(gDeferredEdgeProgram); + mEdgeMap.flush(); + } + } + + if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) + { + { //get luminance map from previous frame's light map + LLGLEnable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); + LLGLDepthTest depth(GL_FALSE); + LLGLDisable stencil(GL_STENCIL_TEST); + + //static F32 fade = 1.f; + + { + gGL.setSceneBlendType(LLRender::BT_ALPHA); + gLuminanceGatherProgram.bind(); + gLuminanceGatherProgram.uniform2f("screen_res", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight()); + mLuminanceMap.bindTarget(); + bindDeferredShader(gLuminanceGatherProgram); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + unbindDeferredShader(gLuminanceGatherProgram); + mLuminanceMap.flush(); + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLuminanceMap.getTexture(), true); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); + glGenerateMipmapEXT(GL_TEXTURE_2D); + } + } + + { //paint noisy GI map (bounce lighting lightmap) + //LLFastTimer ftm(FTM_GI_TRACE); + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + LLGLDisable test(GL_ALPHA_TEST); + + mGIMapPost[0].bindTarget(); + + bindDeferredShader(gDeferredGIProgram, 0, &mGIMap, 0, mTrueNoiseMap); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + unbindDeferredShader(gDeferredGIProgram); + mGIMapPost[0].flush(); + } + + U32 pass_count = 0; + if (render_deferred_blur_light) + { + static const LLCachedControl render_gui_blur_passes("RenderGIBlurPasses",(U32)1); + pass_count = llclamp(render_gui_blur_passes.get(), (U32) 1, (U32) 128); + } + + static const LLCachedControl render_gui_blur_size("RenderGIBlurSize",4.f); + static const LLCachedControl render_gui_blur_increment("RenderGIBlurIncrement",.8f); + static const LLCachedControl render_gui_blur_brightness("RenderGIBlurBrightness",1.025f); + for (U32 i = 0; i < pass_count; ++i) + { //gather/soften indirect lighting map + //LLFastTimer ftm(FTM_GI_GATHER); + bindDeferredShader(gDeferredPostGIProgram, 0, &mGIMapPost[0], NULL, mTrueNoiseMap); + F32 blur_size = render_gui_blur_size/((F32) i * render_gui_blur_increment+1.f); + gDeferredPostGIProgram.uniform2f("delta", 1.f, 0.f); + gDeferredPostGIProgram.uniform1f("kern_scale", blur_size); + gDeferredPostGIProgram.uniform1f("gi_blur_brightness", render_gui_blur_brightness); + + mGIMapPost[1].bindTarget(); + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + stop_glerror(); + } + + mGIMapPost[1].flush(); + unbindDeferredShader(gDeferredPostGIProgram); + bindDeferredShader(gDeferredPostGIProgram, 0, &mGIMapPost[1], NULL, mTrueNoiseMap); + mGIMapPost[0].bindTarget(); + + gDeferredPostGIProgram.uniform2f("delta", 0.f, 1.f); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + stop_glerror(); + } + mGIMapPost[0].flush(); + unbindDeferredShader(gDeferredPostGIProgram); + } } } - gDeferredSunProgram.uniform3fv("offset", slice, offset); - gDeferredSunProgram.uniform2f("screenRes", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight()); + if(render_deferred_ssao) + { //soften direct lighting lightmap + //LLFastTimer ftm(FTM_SOFTEN_SHADOW); + //blur lightmap + mDeferredLight[1].bindTarget(); - { - LLGLDisable blend(GL_BLEND); - //TO-DO: - //V2 changed to LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - //Do this when multisample z-buffer issues are figured out - //LLGLDepthTest depth(GL_FALSE); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - stop_glerror(); - } - - unbindDeferredShader(gDeferredSunProgram); - } - - mDeferredLight[0].flush(); - - //SSAO - { - //blur lightmap - mDeferredLight[1].bindTarget(); - - //mDeferredLight[1].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), - // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); - glClearColor(1,1,1,1); - mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); + glClearColor(1,1,1,1); + mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); glClearColor(0,0,0,0); bindDeferredShader(gDeferredBlurLightProgram); - static const LLCachedControl go("RenderShadowGaussian",LLVector3(2.f,2.f,0.f)); - static const LLCachedControl blur_size("RenderShadowBlurSize",.7f); - static const LLCachedControl blur_samples("RenderShadowBlurSamples",(U32)5); - U32 kern_length = llclamp(blur_samples.get(), (U32) 1, (U32) 16)*2 - 1; + static const LLCachedControl go("RenderShadowGaussian",LLVector3(3.f,2.f,0.f)); + const U32 kern_length = 4; + static const LLCachedControl blur_size("RenderShadowBlurSize",1.4f); + static const LLCachedControl shadow_blur_dist_factor("RenderShadowBlurDistFactor",.1f); // sample symmetrically with the middle sample falling exactly on 0.0 - F32 x = -(kern_length/2.0f) + 0.5f; + F32 x = 0.f; LLVector3 gauss[32]; // xweight, yweight, offset @@ -5936,26 +6630,14 @@ void LLPipeline::renderDeferredLighting() gauss[i].mV[2] = x; x += 1.f; } - /* swap the x=0 position to the start of gauss[] so we can - treat it specially as an optimization. */ - LLVector3 swap; - swap = gauss[kern_length/2]; - gauss[kern_length/2] = gauss[0]; - gauss[0] = swap; - llassert(gauss[0].mV[2] == 0.0f); gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); - gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform1f("dist_factor", shadow_blur_dist_factor); gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); { LLGLDisable blend(GL_BLEND); - //TO-DO: - //V2 changed to LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - //Do this when multisample z-buffer issues are figured out - //LLGLDepthTest depth(GL_FALSE); LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); stop_glerror(); glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); @@ -5972,13 +6654,9 @@ void LLPipeline::renderDeferredLighting() { LLGLDisable blend(GL_BLEND); - //TO-DO: - //V2 changed to LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - //Do this when multisample z-buffer issues are figured out - //LLGLDepthTest depth(GL_FALSE); LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); stop_glerror(); } mDeferredLight[0].flush(); @@ -5997,12 +6675,26 @@ void LLPipeline::renderDeferredLighting() //mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), // 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); - mScreen.bindTarget(); - // clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky - glClearColor(0,0,0,0); - mScreen.clear(GL_COLOR_BUFFER_BIT); - - bindDeferredShader(gDeferredSoftenProgram); + if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) + { + mDeferredLight[1].bindTarget(); + // clear color buffer here (GI) - zeroing alpha (glow) is important or it will accumulate against sky + glClearColor(0,0,0,0); + mScreen.clear(GL_COLOR_BUFFER_BIT); + } + else + { + mScreen.bindTarget(); + // clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky + glClearColor(0,0,0,0); + mScreen.clear(GL_COLOR_BUFFER_BIT); + } + + static const LLCachedControl render_deferred_atmospheric("RenderDeferredAtmospheric",false); + if (render_deferred_atmospheric) + { //apply sunlight contribution + //LLFastTimer ftm(FTM_ATMOSPHERICS); + bindDeferredShader(gDeferredSoftenProgram, 0, &mGIMapPost[0]); { LLGLDepthTest depth(GL_FALSE); LLGLDisable blend(GL_BLEND); @@ -6018,14 +6710,14 @@ void LLPipeline::renderDeferredLighting() glVertexPointer(2, GL_FLOAT, 0, vert); glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - + glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); } unbindDeferredShader(gDeferredSoftenProgram); - + } { //render sky LLGLDisable blend(GL_BLEND); @@ -6033,7 +6725,7 @@ void LLPipeline::renderDeferredLighting() gGL.setSceneBlendType(LLRender::BT_ALPHA); gPipeline.pushRenderTypeMask(); - + gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_CLOUDS, LLPipeline::RENDER_TYPE_WL_SKY, @@ -6044,17 +6736,39 @@ void LLPipeline::renderDeferredLighting() gPipeline.popRenderTypeMask(); } - gGL.setSceneBlendType(LLRender::BT_ADD); - std::list fullscreen_lights; - std::list light_colors; + static const LLCachedControl render_local("RenderLocalLights",false); - F32 v[24]; - glVertexPointer(3, GL_FLOAT, 0, v); + if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) { - bindDeferredShader(gDeferredLightProgram); - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) + mDeferredLight[1].flush(); + mDeferredLight[2].bindTarget(); + mDeferredLight[2].clear(GL_COLOR_BUFFER_BIT); + } + + if (render_local) + { + gGL.setSceneBlendType(LLRender::BT_ADD); + std::list fullscreen_lights; + LLDrawable::drawable_list_t spot_lights; + LLDrawable::drawable_list_t fullscreen_spot_lights; + + for (U32 i = 0; i < 2; i++) { + mTargetShadowSpotLight[i] = NULL; + } + + std::list light_colors; + + LLVertexBuffer::unbind(); + + F32 v[24]; + glVertexPointer(3, GL_FLOAT, 0, v); + + { + bindDeferredShader(gDeferredLightProgram); + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) + { LLDrawable* drawablep = *iter; LLVOVolume* volume = drawablep->getVOVolume(); @@ -6098,7 +6812,7 @@ void LLPipeline::renderDeferredLighting() glh::vec3f tc(c); mat.mult_matrix_vec(tc); - + //vertex positions are encoded so the 3 bits of their vertex index //correspond to their axis facing, with bit position 3,2,1 matching //axis facing x,y,z, bit set meaning positive facing, bit clear @@ -6107,7 +6821,7 @@ void LLPipeline::renderDeferredLighting() v[3] = c[0]-s; v[4] = c[1]-s; v[5] = c[2]+s; // 1 - 0001 v[6] = c[0]-s; v[7] = c[1]+s; v[8] = c[2]-s; // 2 - 0010 v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s; // 3 - 0011 - + v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100 v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101 v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110 @@ -6120,25 +6834,91 @@ void LLPipeline::renderDeferredLighting() camera->getOrigin().mV[2] > c[2] + s + 0.2f || camera->getOrigin().mV[2] < c[2] - s - 0.2f) { //draw box if camera is outside box - glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); - glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center)); + if (render_local) + { + if (volume->isLightSpotlight()) + { + drawablep->getVOVolume()->updateSpotLightPriority(); + spot_lights.push_back(drawablep); + continue; + } + + glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); + glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); + glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, + GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center)); + } } else { + if (volume->isLightSpotlight()) + { + drawablep->getVOVolume()->updateSpotLightPriority(); + fullscreen_spot_lights.push_back(drawablep); + continue; + } + fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s*s)); light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f)); } } unbindDeferredShader(gDeferredLightProgram); - } + } + if (!spot_lights.empty()) + { + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + bindDeferredShader(gDeferredSpotLightProgram); + gDeferredSpotLightProgram.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + + for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter) + { + //LLFastTimer ftm(FTM_PROJECTORS); + LLDrawable* drawablep = *iter; + + LLVOVolume* volume = drawablep->getVOVolume(); + + LLVector3 center = drawablep->getPositionAgent(); + F32* c = center.mV; + F32 s = volume->getLightRadius()*1.5f; + + sVisibleLightCount++; + + glh::vec3f tc(c); + mat.mult_matrix_vec(tc); + + setupSpotLight(gDeferredSpotLightProgram, drawablep); + + LLColor3 col = volume->getLightColor(); + col *= volume->getLightIntensity(); + + //vertex positions are encoded so the 3 bits of their vertex index + //correspond to their axis facing, with bit position 3,2,1 matching + //axis facing x,y,z, bit set meaning positive facing, bit clear + //meaning negative facing + v[0] = c[0]-s; v[1] = c[1]-s; v[2] = c[2]-s; // 0 - 0000 + v[3] = c[0]-s; v[4] = c[1]-s; v[5] = c[2]+s; // 1 - 0001 + v[6] = c[0]-s; v[7] = c[1]+s; v[8] = c[2]-s; // 2 - 0010 + v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s; // 3 - 0011 + + v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100 + v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101 + v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110 + v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111 + + glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); + glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); + glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, + GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center)); + } + gDeferredSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + unbindDeferredShader(gDeferredSpotLightProgram); + } + + { + bindDeferredShader(gDeferredMultiLightProgram); - if (!fullscreen_lights.empty()) - { - bindDeferredShader(gDeferredMultiLightProgram); LLGLDepthTest depth(GL_FALSE); //full screen blit @@ -6150,41 +6930,121 @@ void LLPipeline::renderDeferredLighting() U32 count = 0; - const U32 max_count = 16; - LLVector4 light[max_count]; - LLVector4 col[max_count]; + const U32 max_count = 8; + LLVector4 light[max_count]; + LLVector4 col[max_count]; glVertexPointer(2, GL_FLOAT, 0, vert); + F32 far_z = 0.f; + while (!fullscreen_lights.empty()) { light[count] = fullscreen_lights.front(); fullscreen_lights.pop_front(); col[count] = light_colors.front(); light_colors.pop_front(); - count++; + far_z = llmin(light[count].mV[2]-sqrtf(light[count].mV[3]), far_z); + + count++; if (count == max_count || fullscreen_lights.empty()) { gDeferredMultiLightProgram.uniform1i("light_count", count); - gDeferredMultiLightProgram.uniform4fv("light[0]", count, (GLfloat*) light); gDeferredMultiLightProgram.uniform4fv("light", count, (GLfloat*) light); - gDeferredMultiLightProgram.uniform4fv("light_col[0]", count, (GLfloat*) col); gDeferredMultiLightProgram.uniform4fv("light_col", count, (GLfloat*) col); + gDeferredMultiLightProgram.uniform1f("far_z", far_z); + far_z = 0.f; count = 0; - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + } + } + unbindDeferredShader(gDeferredMultiLightProgram); + + bindDeferredShader(gDeferredMultiSpotLightProgram); + + gDeferredMultiSpotLightProgram.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + + for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter) + { + //LLFastTimer ftm(FTM_PROJECTORS); + LLDrawable* drawablep = *iter; + + LLVOVolume* volume = drawablep->getVOVolume(); + + LLVector3 center = drawablep->getPositionAgent(); + F32* c = center.mV; + F32 s = volume->getLightRadius()*1.5f; + + sVisibleLightCount++; + + glh::vec3f tc(c); + mat.mult_matrix_vec(tc); + + setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); + + LLColor3 col = volume->getLightColor(); + col *= volume->getLightIntensity(); + + glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); + glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + } + + gDeferredMultiSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + unbindDeferredShader(gDeferredMultiSpotLightProgram); + + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); } } + + gGL.setColorMask(true, true); + + if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) + { + mDeferredLight[2].flush(); + + mScreen.bindTarget(); + mScreen.clear(GL_COLOR_BUFFER_BIT); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + gGL.setSceneBlendType(LLRender::BT_ALPHA); - unbindDeferredShader(gDeferredMultiLightProgram); + { //mix various light maps (local, sun, gi) + //LLFastTimer ftm(FTM_POST); + LLGLDisable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); + LLGLDepthTest depth(GL_FALSE); + LLGLDisable stencil(GL_STENCIL_TEST); + + bindDeferredShader(gDeferredPostProgram, 0, &mGIMapPost[0]); + + gDeferredPostProgram.bind(); + + LLVertexBuffer::unbind(); + + glVertexPointer(2, GL_FLOAT, 0, vert); + glColor3f(1,1,1); + + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glDrawArrays(GL_TRIANGLES, 0, 3); + + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + unbindDeferredShader(gDeferredPostProgram); + } + } } - //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - { //render non-deferred geometry + { //render non-deferred geometry (alpha, fullbright, glow) LLGLDisable blend(GL_BLEND); LLGLDisable stencil(GL_STENCIL_TEST); @@ -6214,9 +7074,6 @@ void LLPipeline::renderDeferredLighting() popRenderTypeMask(); } - //TO-DO: - //V2 moved block from LLPipeline::renderGeomPostDeferred - //Migrate once multisample z-buffer issues are figured out on ati cards. { //render highlights, etc. renderHighlights(); @@ -6238,6 +7095,136 @@ void LLPipeline::renderDeferredLighting() } +void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) +{ + //construct frustum + LLVOVolume* volume = drawablep->getVOVolume(); + LLVector3 params = volume->getSpotLightParams(); + + 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(); + + //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 origin = np - at_axis*dist; + + //matrix from volume space to agent space + LLMatrix4 light_mat(quat, LLVector4(origin,1.f)); + + glh::matrix4f light_to_agent((F32*) light_mat.mMatrix); + glh::matrix4f light_to_screen = glh_get_current_modelview() * light_to_agent; + + glh::matrix4f screen_to_light = light_to_screen.inverse(); + + 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]; + + F32 fovy = fov * RAD_TO_DEG; + F32 aspect = width/height; + + 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 p1(0, 0, -(near_clip+0.01f)); + glh::vec3f p2(0, 0, -(near_clip+1.f)); + + glh::vec3f screen_origin(0, 0, 0); + + light_to_screen.mult_matrix_vec(p1); + light_to_screen.mult_matrix_vec(p2); + light_to_screen.mult_matrix_vec(screen_origin); + + 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("proj_mat", 1, FALSE, screen_to_light.m); + shader.uniform1f("proj_near", near_clip); + shader.uniform3fv("proj_p", 1, p1.v); + shader.uniform3fv("proj_n", 1, n.v); + shader.uniform3fv("proj_origin", 1, screen_origin.v); + shader.uniform1f("proj_range", proj_range); + shader.uniform1f("proj_ambiance", params.mV[2]); + S32 s_idx = -1; + + for (U32 i = 0; i < 2; i++) + { + if (mShadowSpotLight[i] == drawablep) + { + s_idx = i; + } + } + + shader.uniform1i("proj_shadow_idx", s_idx); + + if (s_idx >= 0) + { + shader.uniform1f("shadow_fade", 1.f-mSpotLightFade[s_idx]); + } + else + { + shader.uniform1f("shadow_fade", 1.f); + } + + { + 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(); + + S32 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + + if (channel > -1 && img) + { + gGL.getTexUnit(channel)->bind(img); + + F32 lod_range = logf(img->getWidth())/logf(2.f); + + shader.uniform1f("proj_focus", focus); + shader.uniform1f("proj_lod", lod_range); + shader.uniform1f("proj_ambient_lod", llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f)); + } +} + void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) { stop_glerror(); @@ -6247,14 +7234,43 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) shader.disableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); shader.disableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_EDGE, LLTexUnit::TT_RECT_TEXTURE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE); + shader.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MIP); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_BLOOM); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_NORMAL); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_DIFFUSE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_SPECULAR); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_DEPTH); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MIN_POS); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MAX_POS); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_NORMAL); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_DIFFUSE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MIN_POS); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MAX_POS); + for (U32 i = 0; i < 4; i++) + { + if (shader.disableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE) > -1) + { + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + } + } + + for (U32 i = 4; i < 6; i++) { if (shader.disableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i) > -1) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); } } + shader.disableTexture(LLViewerShaderMgr::DEFERRED_NOISE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHTFUNC); S32 channel = shader.disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); if (channel > -1) @@ -6268,6 +7284,8 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(0)->activate(); shader.unbind(); + + LLGLState::checkTextureChannels(); } inline float sgn(float a) @@ -6397,53 +7415,45 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gPipeline.popRenderTypeMask(); } - - static const LLCachedControl water_reflections("RenderWaterReflections",false); - if (water_reflections) + static const LLCachedControl detail("RenderReflectionDetail",0); + if (detail > 0) { //mask out selected geometry based on reflection detail - static const LLCachedControl detail("RenderReflectionDetail",0); - //if (detail > 0) - { //mask out selected geometry based on reflection detail + gPipeline.pushRenderTypeMask(); + if (detail < 4) + { + clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES); + if (detail < 3) { - gPipeline.pushRenderTypeMask(); - if (detail < 3) + clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); + if (detail < 2) { - clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES); - if (detail < 2) - { - clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); - if (detail < 1) - { - clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES); - } - } + clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES); } - - clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER, - LLPipeline::RENDER_TYPE_VOIDWATER, - LLPipeline::RENDER_TYPE_GROUND, - LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS, - LLPipeline::RENDER_TYPE_WL_CLOUDS, - LLPipeline::END_RENDER_TYPES); - static const LLCachedControl skip_distortion_updates("SkipReflectOcclusionUpdates",false); - LLPipeline::sSkipUpdate = skip_distortion_updates; - LLGLUserClipPlane clip_plane(plane, mat, projection); - LLGLDisable cull(GL_CULL_FACE); - updateCull(camera, ref_result, 1); - stateSort(camera, ref_result); - gPipeline.grabReferences(ref_result); - renderGeom(camera); - LLPipeline::sSkipUpdate = FALSE; - gPipeline.popRenderTypeMask(); } - } + } + + clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER, + LLPipeline::RENDER_TYPE_VOIDWATER, + LLPipeline::RENDER_TYPE_GROUND, + LLPipeline::RENDER_TYPE_SKY, + LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS, + LLPipeline::RENDER_TYPE_WL_CLOUDS, + LLPipeline::END_RENDER_TYPES); + static const LLCachedControl skip_distortion_updates("SkipReflectOcclusionUpdates",false); + LLPipeline::sSkipUpdate = skip_distortion_updates; + LLGLUserClipPlane clip_plane(plane, mat, projection); + LLGLDisable cull(GL_CULL_FACE); + updateCull(camera, ref_result, -water_clip, &plane); + stateSort(camera, ref_result); + gPipeline.grabReferences(ref_result); + renderGeom(camera); + LLPipeline::sSkipUpdate = FALSE; + gPipeline.popRenderTypeMask(); } - } + } glCullFace(GL_BACK); glPopMatrix(); mWaterRef.flush(); - glh_set_current_modelview(current); } @@ -6482,9 +7492,11 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) { //clip out geometry on the same side of water as the camera mat = glh_get_current_modelview(); - LLGLUserClipPlane clip_plane(LLPlane(-pnorm, -(pd+pad)), mat, projection); + LLPlane plane(-pnorm, -(pd+pad)); + + LLGLUserClipPlane clip_plane(plane, mat, projection); static LLCullResult result; - updateCull(camera, result, water_clip); + updateCull(camera, result, water_clip, &plane); stateSort(camera, result); gGL.setColorMask(true, true); @@ -6594,31 +7606,480 @@ glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max) return ret; } -void LLPipeline::generateSunShadow(LLCamera& camera) +void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult &result, BOOL use_shader, BOOL use_occlusion) { - if (!sRenderDeferred) + LLFastTimer t(LLFastTimer::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; + + U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY, LLRenderPass::PASS_BUMP, LLRenderPass::PASS_FULLBRIGHT_SHINY }; + LLGLEnable cull(GL_CULL_FACE); + + if (use_shader) + { + gDeferredShadowProgram.bind(); + } + + updateCull(shadow_cam, result); + stateSort(shadow_cam, result); + + //generate shadow map + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadMatrixf(proj.m); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadMatrixf(view.m); + + stop_glerror(); + gGLLastMatrix = NULL; + + { + LLGLDepthTest depth(GL_TRUE); + glClear(GL_DEPTH_BUFFER_BIT); + } + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + glColor4f(1,1,1,1); + + stop_glerror(); + + gGL.setColorMask(false, false); + + //glCullFace(GL_FRONT); + + LLVertexBuffer::unbind(); + + { + //LLFastTimer ftm(FTM_SHADOW_SIMPLE); + LLGLDisable test(GL_ALPHA_TEST); + gGL.getTexUnit(0)->disable(); + for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i) + { + renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); + } + gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + } + + if (use_shader) + { + gDeferredShadowProgram.unbind(); + renderGeomShadow(shadow_cam); + gDeferredShadowProgram.bind(); + } + else + { + renderGeomShadow(shadow_cam); + } + + { + //LLFastTimer ftm(FTM_SHADOW_ALPHA); + LLGLEnable test(GL_ALPHA_TEST); + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.6f); + renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE); + glColor4f(1,1,1,1); + renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE); + gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + } + + //glCullFace(GL_BACK); + + gGLLastMatrix = NULL; + glLoadMatrixd(gGLModelView); + doOcclusion(shadow_cam); + + if (use_shader) + { + gDeferredShadowProgram.unbind(); + } + + gGL.setColorMask(true, true); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + gGLLastMatrix = NULL; + + LLPipeline::sUseOcclusion = occlude; + LLPipeline::sShadowRender = FALSE; +} + +BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector3& max, std::vector& fp, LLVector3 light_dir) +{ + //LLFastTimer t(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 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 < 8; i++) + { + pp.push_back(camera.mAgentFrustum[i]); + } + + + //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 < 6; 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]]; + const LLVector3 n(cp.mV); + + 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,1, + + 4,5, + 5,6, + 6,7, + 7,4, + + 0,4, + 1,5, + 2,6, + 3,7 + }; + + LLVector3 center = (max+min)*0.5f; + LLVector3 size = (max-min)*0.5f; + + 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]; + const LLVector3 n(cp.mV); + + 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); + } + } + } + + 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; + + 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 < 6; ++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::generateGI(LLCamera& camera, LLVector3& lightDir, std::vector& vpc) +{ + if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) < 3) { return; } - //temporary hack to disable shadows but keep local lights - static BOOL clear = TRUE; - static const LLCachedControl gen_shadow("RenderDeferredSunShadow",false); - if (!gen_shadow) + LLVector3 up; + + //LLGLEnable depth_clamp(GL_DEPTH_CLAMP_NV); + + if (lightDir.mV[2] > 0.5f) + { + up = LLVector3(1,0,0); + } + else + { + up = LLVector3(0, 0, 1); + } + + + static const LLCachedControl gi_range("RenderGIRange",96.f); + + U32 res = mGIMap.getWidth(); + + static const LLCachedControl render_gi_attenuation("RenderGIAttenuation",.1f); + F32 atten = llmax(render_gi_attenuation.get(), 0.001f); + + //set radius to range at which distance attenuation of incoming photons is near 0 + + F32 lrad = sqrtf(1.f/(atten*0.01f)); + + F32 lrange = lrad+gi_range*0.5f; + + LLVector3 pad(lrange,lrange,lrange); + + glh::matrix4f view = look(LLVector3(128.f,128.f,128.f), lightDir, up); + + LLVector3 cp = camera.getOrigin()+camera.getAtAxis()*(gi_range*0.5f); + + glh::vec3f scp(cp.mV); + view.mult_matrix_vec(scp); + cp.setVec(scp.v); + + F32 pix_width = lrange/(res*0.5f); + + //move cp to the nearest pix_width + for (U32 i = 0; i < 3; i++) + { + cp.mV[i] = llround(cp.mV[i], pix_width); + } + + LLVector3 min = cp-pad; + LLVector3 max = cp+pad; + + //set mGIRange to range in tc space[0,1] that covers texture block of intersecting lights around a point + mGIRange.mV[0] = (max.mV[0]-min.mV[0])/res; + mGIRange.mV[1] = (max.mV[1]-min.mV[1])/res; + mGILightRadius = lrad/lrange*0.5f; + + glh::matrix4f proj = gl_ortho(min.mV[0], max.mV[0], + min.mV[1], max.mV[1], + -max.mV[2], -min.mV[2]); + + LLCamera sun_cam = camera; + + glh::matrix4f eye_view = glh_get_current_modelview(); + + //get eye space to camera space matrix + mGIMatrix = view*eye_view.inverse(); + mGINormalMatrix = mGIMatrix.inverse().transpose(); + mGIInvProj = proj.inverse(); + mGIMatrixProj = proj*mGIMatrix; + + //translate and scale to [0,1] + glh::matrix4f trans(.5f, 0.f, 0.f, .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); + + mGIMatrixProj = trans*mGIMatrixProj; + + glh_set_current_modelview(view); + glh_set_current_projection(proj); + + LLViewerCamera::updateFrustumPlanes(sun_cam, TRUE, FALSE, TRUE); + + sun_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); + static LLCullResult result; + + pushRenderTypeMask(); + + andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE, + LLPipeline::RENDER_TYPE_FULLBRIGHT, + LLPipeline::RENDER_TYPE_BUMP, + LLPipeline::RENDER_TYPE_VOLUME, + LLPipeline::RENDER_TYPE_TREE, + LLPipeline::RENDER_TYPE_TERRAIN, + LLPipeline::RENDER_TYPE_WATER, + LLPipeline::RENDER_TYPE_VOIDWATER, + LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW, + LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_PASS_SIMPLE, + LLPipeline::RENDER_TYPE_PASS_BUMP, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, + LLPipeline::RENDER_TYPE_PASS_SHINY, + END_RENDER_TYPES); + + + + S32 occlude = LLPipeline::sUseOcclusion; + //LLPipeline::sUseOcclusion = 0; + LLPipeline::sShadowRender = TRUE; + + //only render large objects into GI map + static const LLCachedControl render_gi_min_render_size("RenderGIMinRenderSize",.5f); + sMinRenderSize = render_gi_min_render_size; + + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_GI_SOURCE; + mGIMap.bindTarget(); + + F64 last_modelview[16]; + F64 last_projection[16]; + for (U32 i = 0; i < 16; i++) + { + last_modelview[i] = gGLLastModelView[i]; + last_projection[i] = gGLLastProjection[i]; + gGLLastModelView[i] = mGIModelview.m[i]; + gGLLastProjection[i] = mGIProjection.m[i]; + } + + sun_cam.setOrigin(0.f, 0.f, 0.f); + updateCull(sun_cam, result); + stateSort(sun_cam, result); + + for (U32 i = 0; i < 16; i++) + { + gGLLastModelView[i] = last_modelview[i]; + gGLLastProjection[i] = last_projection[i]; + } + + mGIProjection = proj; + mGIModelview = view; + + LLGLEnable cull(GL_CULL_FACE); + + //generate GI map + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadMatrixf(proj.m); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadMatrixf(view.m); + + stop_glerror(); + gGLLastMatrix = NULL; + + mGIMap.clear(); + + { + //LLGLEnable enable(GL_DEPTH_CLAMP_NV); + renderGeomDeferred(camera); + } + + mGIMap.flush(); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + gGLLastMatrix = NULL; + + LLPipeline::sUseOcclusion = occlude; + LLPipeline::sShadowRender = FALSE; + sMinRenderSize = 0.f; + + popRenderTypeMask(); + +} + +void LLPipeline::generateSunShadow(LLCamera& camera) +{ + static const LLCachedControl shadow_detial("RenderShadowDetail",0); + if (!sRenderDeferred || shadow_detial <= 0) { - if (clear) - { - clear = FALSE; - for (U32 i = 0; i < 4; i++) - { - mSunShadow[i].bindTarget(); - mSunShadow[i].clear(); - mSunShadow[i].flush(); - } - } return; } - clear = TRUE; + + F64 last_modelview[16]; + F64 last_projection[16]; + for (U32 i = 0; i < 16; i++) + { //store last_modelview of world camera + last_modelview[i] = gGLLastModelView[i]; + last_projection[i] = gGLLastProjection[i]; + } + pushRenderTypeMask(); andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE, LLPipeline::RENDER_TYPE_ALPHA, @@ -6643,40 +8104,137 @@ void LLPipeline::generateSunShadow(LLCamera& camera) //get sun view matrix - F32 range = 128.f; - //store current projection/modelview matrix glh::matrix4f saved_proj = glh_get_current_projection(); glh::matrix4f saved_view = glh_get_current_modelview(); glh::matrix4f inv_view = saved_view.inverse(); - glh::matrix4f view[4]; - glh::matrix4f proj[4]; - LLVector3 up; - + glh::matrix4f view[6]; + glh::matrix4f proj[6]; + //clip contains parallel split distances for 3 splits - static const LLCachedControl clip("RenderShadowClipPlanes",LLVector3(4.f,8.f,24.f)); - - //far clip on last split is minimum of camera view distance and 128 - mSunClipPlanes = LLVector4(clip, clip.get().mV[2] * clip.get().mV[2]/clip.get().mV[1]); - - const LLPickInfo& pick_info = gViewerWindow->getLastPick(); - - if (!pick_info.mPosGlobal.isExactlyZero()) - { //squish nearest frustum based on alt-zoom (tighten up nearest frustum when focusing on tiny object - F32 focus_dist = (F32) (pick_info.mPosGlobal + LLVector3d(pick_info.mObjectOffset) - gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin())).magVec(); - mSunClipPlanes.mV[0] = llclamp(focus_dist*focus_dist, 2.f, mSunClipPlanes.mV[0]); - } + static const LLCachedControl normal_clip_planes("RenderShadowClipPlanes",LLVector3(1.f,12.f,32.f)); + static const LLCachedControl ortho_clip_planes("RenderShadowOrthoClipPlanes",LLVector3(4.f,8.f,24.f)); + const LLVector3 &sun_clip = normal_clip_planes.get(); + const LLVector3 &ortho_clip = ortho_clip_planes.get(); - // convenience array of 4 near clip plane distances - F32 dist[] = { 0.1f, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] }; + //far clip on last split is minimum of camera view distance and 128 + mSunClipPlanes = LLVector4(sun_clip, sun_clip.mV[2] * sun_clip.mV[2]/sun_clip.mV[1]); + + mSunOrthoClipPlanes = LLVector4(ortho_clip, ortho_clip.mV[2]*ortho_clip.mV[2]/ortho_clip.mV[1]); //currently used for amount to extrude frusta corners for constructing shadow frusta - static const LLCachedControl n("RenderShadowNearDist",LLVector3(256,256,256)); - F32 nearDist[] = { n.get().mV[0], n.get().mV[1], n.get().mV[2], n.get().mV[2] }; + //staic const LLCachedControl shadow_near_dist("RenderShadowNearDist"); + //LLVector3 &n = shadow_near_dist.get(); + //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; + + LLVector3 lightDir = -mSunDir; + lightDir.normVec(); + + glh::vec3f light_dir(lightDir.mV); + + //create light space camera matrix + + LLVector3 at = lightDir; + + LLVector3 up = camera.getAtAxis(); + + if (fabsf(up*lightDir) > 0.75f) + { + up = camera.getUpAxis(); + } + + /*LLVector3 left = up%at; + up = at%left;*/ + + up.normVec(); + at.normVec(); + + + LLCamera main_camera = camera; + + F32 near_clip = 0.f; + { + //get visible point cloud + std::vector fp; + + main_camera.calcAgentFrustumPlanes(main_camera.mAgentFrustum); + + LLVector3 min,max; + getVisiblePointCloud(main_camera,min,max,fp); + + if (fp.empty()) + { + if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA)) + { + mShadowCamera[0] = main_camera; + mShadowExtents[0][0] = min; + mShadowExtents[0][1] = max; + + mShadowFrustPoints[0].clear(); + mShadowFrustPoints[1].clear(); + mShadowFrustPoints[2].clear(); + mShadowFrustPoints[3].clear(); + } + popRenderTypeMask(); + return; + } + + generateGI(camera, lightDir, fp); + + //get good split distances for frustum + for (U32 i = 0; i < fp.size(); ++i) + { + glh::vec3f v(fp[i].mV); + saved_view.mult_matrix_vec(v); + fp[i].setVec(v.v); + } + + min = fp[0]; + max = fp[0]; + + //get camera space bounding box + for (U32 i = 1; i < fp.size(); ++i) + { + update_min_max(min, max, fp[i]); + } + + near_clip = -max.mV[2]; + F32 far_clip = -min.mV[2]*2.f; + + far_clip = llmin(far_clip, 128.f); + far_clip = llmin(far_clip, camera.getFar()); + + F32 range = far_clip-near_clip; + + static const LLCachedControl shadow_split_exponent("RenderShadowSplitExponent",LLVector3(3.f,3.f,2.f)); + const LLVector3 &split_exp = shadow_split_exponent.get(); + + F32 da = 1.f-llmax( fabsf(lightDir*up), fabsf(lightDir*camera.getLeftAxis()) ); + + da = powf(da, split_exp.mV[2]); + + + F32 sxp = split_exp.mV[1] + (split_exp.mV[0]-split_exp.mV[1])*da; + + + for (U32 i = 0; i < 4; ++i) + { + F32 x = (F32)(i+1)/4.f; + x = powf(x, sxp); + mSunClipPlanes.mV[i] = near_clip+range*x; + } + } + + // convenience array of 4 near clip plane distances + F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] }; for (S32 j = 0; j < 4; j++) { + if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA)) + { + mShadowFrustPoints[j].clear(); + } LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+j; @@ -6684,83 +8242,45 @@ void LLPipeline::generateSunShadow(LLCamera& camera) glh_set_current_modelview(saved_view); glh_set_current_projection(saved_proj); - //get center of far clip plane (for point of interest later) - LLVector3 center = camera.getOrigin() + camera.getAtAxis() * range; - LLVector3 eye = camera.getOrigin(); //camera used for shadow cull/render LLCamera shadow_cam; - // perspective shadow map - glh::vec3f p[16]; //point cloud to be contained by shadow projection (light camera space) - glh::vec3f wp[16]; //point cloud to be contained by shadow projection (world space) - - LLVector3 lightDir = -mSunDir; - glh::vec3f light_dir(lightDir.mV); - - //create light space camera matrix - LLVector3 at; - F32 dl = camera.getLeftAxis() * lightDir; - F32 du = camera.getUpAxis() * lightDir; - - //choose an at axis such that up will be most aligned with lightDir - if (dl*dl < du*du) - { - at = lightDir%camera.getLeftAxis(); - } - else - { - at = lightDir%camera.getUpAxis(); - } - - if (at * camera.getAtAxis() < 0) - { - at = -at; - } - - - LLVector3 left = lightDir%at; - up = left%lightDir; - up.normVec(); - //create world space camera frustum for this split shadow_cam = camera; shadow_cam.setFar(16.f); - LLViewerCamera::updateFrustumPlanes(shadow_cam); + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); LLVector3* frust = shadow_cam.mAgentFrustum; LLVector3 pn = shadow_cam.getAtAxis(); - LLVector3 frust_center; - LLVector3 min, max; //construct 8 corners of split frustum section for (U32 i = 0; i < 4; i++) { LLVector3 delta = frust[i+4]-eye; + delta += (frust[i+4]-frust[(i+2)%4+4])*0.05f; delta.normVec(); F32 dp = delta*pn; - frust[i] = eye + (delta*dist[j])/dp; - frust[i+4] = eye + (delta*dist[j+1])/dp; - frust_center += frust[i] + frust[i+4]; + frust[i] = eye + (delta*dist[j]*0.95f)/dp; + frust[i+4] = eye + (delta*dist[j+1]*1.05f)/dp; } - - //get frustum center - frust_center /= 8.f; shadow_cam.calcAgentFrustumPlanes(frust); - + shadow_cam.mFrustumCornerDist = 0.f; if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { mShadowCamera[j] = shadow_cam; } - if (gPipeline.getVisibleExtents(shadow_cam, min, max)) + std::vector fp; + + if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir)) { //no possible shadow receivers if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) @@ -6770,6 +8290,16 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mShadowCamera[j+4] = shadow_cam; } + mShadow[j].bindTarget(); + { + LLGLDepthTest depth(GL_TRUE); + mShadow[j].clear(); + } + mShadow[j].flush(); + + mShadowError.mV[j] = 0.f; + mShadowFOV.mV[j] = 0.f; + continue; } @@ -6777,53 +8307,265 @@ void LLPipeline::generateSunShadow(LLCamera& camera) { mShadowExtents[j][0] = min; mShadowExtents[j][1] = max; + mShadowFrustPoints[j] = fp; } - view[j] = look(frust_center-lightDir*nearDist[j], lightDir, up); - F32 shadow_dist = nearDist[j]; - for (U32 i = 0; i < 8; i++) + //find a good origin for shadow projection + LLVector3 origin; + + //get a temporary view projection + view[j] = look(camera.getOrigin(), lightDir, -up); + + std::vector wpf; + + for (U32 i = 0; i < fp.size(); i++) { - //points in worldspace (wp) and light camera space (p) - //that must be included in shadow generation - wp[i] = glh::vec3f(frust[i].mV); - wp[i+8] = wp[i] - light_dir*shadow_dist; - view[j].mult_matrix_vec(wp[i], p[i]); - view[j].mult_matrix_vec(wp[i+8], p[i+8]); + glh::vec3f p = glh::vec3f(fp[i].mV); + view[j].mult_matrix_vec(p); + wpf.push_back(LLVector3(p.v)); } - - min = LLVector3(p[0].v); - max = LLVector3(p[0].v); - LLVector3 fmin = min; - LLVector3 fmax = max; + min = wpf[0]; + max = wpf[0]; - for (U32 i = 1; i < 16; i++) - { //find camera space AABB of frustum in light camera space - update_min_max(min, max, LLVector3(p[i].v)); - if (i < 8) + for (U32 i = 0; i < fp.size(); ++i) + { //get AABB in camera space + update_min_max(min, max, wpf[i]); + } + + // Construct a perspective transform with perspective along y-axis that contains + // points in wpf + //Known: + // - far clip plane + // - near clip plane + // - points in frustum + //Find: + // - origin + + //get some "interesting" points of reference + LLVector3 center = (min+max)*0.5f; + LLVector3 size = (max-min)*0.5f; + LLVector3 near_center = center; + near_center.mV[1] += size.mV[1]*2.f; + + + //put all points in wpf in quadrant 0, reletive to center of min/max + //get the best fit line using least squares + F32 bfm = 0.f; + F32 bfb = 0.f; + + for (U32 i = 0; i < wpf.size(); ++i) + { + wpf[i] -= center; + wpf[i].mV[0] = fabsf(wpf[i].mV[0]); + wpf[i].mV[2] = fabsf(wpf[i].mV[2]); + } + + if (!wpf.empty()) + { + F32 sx = 0.f; + F32 sx2 = 0.f; + F32 sy = 0.f; + F32 sxy = 0.f; + + for (U32 i = 0; i < wpf.size(); ++i) + { + sx += wpf[i].mV[0]; + sx2 += wpf[i].mV[0]*wpf[i].mV[0]; + sy += wpf[i].mV[1]; + sxy += wpf[i].mV[0]*wpf[i].mV[1]; + } + + bfm = (sy*sx-wpf.size()*sxy)/(sx*sx-wpf.size()*sx2); + bfb = (sx*sxy-sy*sx2)/(sx*sx-bfm*sx2); + } + + { + // best fit line is y=bfm*x+bfb + + //find point that is furthest to the right of line + F32 off_x = -1.f; + LLVector3 lp; + + for (U32 i = 0; i < wpf.size(); ++i) { - update_min_max(fmin, fmax, LLVector3(p[i].v)); + //y = bfm*x+bfb + //x = (y-bfb)/bfm + F32 lx = (wpf[i].mV[1]-bfb)/bfm; + + lx = wpf[i].mV[0]-lx; + + if (off_x < lx) + { + off_x = lx; + lp = wpf[i]; + } + } + + //get line with slope bfm through lp + // bfb = y-bfm*x + bfb = lp.mV[1]-bfm*lp.mV[0]; + + //calculate error + mShadowError.mV[j] = 0.f; + + for (U32 i = 0; i < wpf.size(); ++i) + { + F32 lx = (wpf[i].mV[1]-bfb)/bfm; + mShadowError.mV[j] += fabsf(wpf[i].mV[0]-lx); + } + + mShadowError.mV[j] /= wpf.size(); + mShadowError.mV[j] /= size.mV[0]; + + static const LLCachedControl render_shadow_error_cutoff("RenderShadowErrorCutoff",5.f); + if (mShadowError.mV[j] > render_shadow_error_cutoff) + { //just use ortho projection + mShadowFOV.mV[j] = -1.f; + origin.clearVec(); + proj[j] = gl_ortho(min.mV[0], max.mV[0], + min.mV[1], max.mV[1], + -max.mV[2], -min.mV[2]); + } + else + { + //origin is where line x = 0; + origin.setVec(0,bfb,0); + + F32 fovz = 1.f; + F32 fovx = 1.f; + + LLVector3 zp; + LLVector3 xp; + + for (U32 i = 0; i < wpf.size(); ++i) + { + LLVector3 atz = wpf[i]-origin; + atz.mV[0] = 0.f; + atz.normVec(); + if (fovz > -atz.mV[1]) + { + zp = wpf[i]; + fovz = -atz.mV[1]; + } + + LLVector3 atx = wpf[i]-origin; + atx.mV[2] = 0.f; + atx.normVec(); + if (fovx > -atx.mV[1]) + { + fovx = -atx.mV[1]; + xp = wpf[i]; + } + } + + fovx = acos(fovx); + fovz = acos(fovz); + + static const LLCachedControl render_shadow_fov_cutoff("RenderShadowFOVCutoff",1.1f); + F32 cutoff = llmin(render_shadow_fov_cutoff.get(), 1.4f); + + mShadowFOV.mV[j] = fovx; + + if (fovx < cutoff && fovz > cutoff) + { + //x is a good fit, but z is too big, move away from zp enough so that fovz matches cutoff + F32 d = zp.mV[2]/tan(cutoff); + F32 ny = zp.mV[1] + fabsf(d); + + origin.mV[1] = ny; + + fovz = 1.f; + fovx = 1.f; + + for (U32 i = 0; i < wpf.size(); ++i) + { + LLVector3 atz = wpf[i]-origin; + atz.mV[0] = 0.f; + atz.normVec(); + fovz = llmin(fovz, -atz.mV[1]); + + LLVector3 atx = wpf[i]-origin; + atx.mV[2] = 0.f; + atx.normVec(); + fovx = llmin(fovx, -atx.mV[1]); + } + + fovx = acos(fovx); + fovz = acos(fovz); + + if (fovx > cutoff || llround(fovz, 0.01f) > cutoff) + { + // llerrs << "WTF?" << llendl; + } + + mShadowFOV.mV[j] = cutoff; + } + + + origin += center; + + F32 ynear = -(max.mV[1]-origin.mV[1]); + F32 yfar = -(min.mV[1]-origin.mV[1]); + + if (ynear < 0.1f) //keep a sensible near clip plane + { + F32 diff = 0.1f-ynear; + origin.mV[1] += diff; + ynear += diff; + yfar += diff; + } + + if (fovx > cutoff) + { //just use ortho projection + origin.clearVec(); + mShadowError.mV[j] = -1.f; + proj[j] = gl_ortho(min.mV[0], max.mV[0], + min.mV[1], max.mV[1], + -max.mV[2], -min.mV[2]); + } + else + { + //get perspective projection + view[j] = view[j].inverse(); + + glh::vec3f origin_agent(origin.mV); + + //translate view to origin + view[j].mult_matrix_vec(origin_agent); + + eye = LLVector3(origin_agent.v); + + if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) + { + mShadowFrustOrigin[j] = eye; + } + + view[j] = look(LLVector3(origin_agent.v), lightDir, -up); + + F32 fx = 1.f/tanf(fovx); + F32 fz = 1.f/tanf(fovz); + + proj[j] = glh::matrix4f(-fx, 0, 0, 0, + 0, (yfar+ynear)/(ynear-yfar), 0, (2.f*yfar*ynear)/(ynear-yfar), + 0, 0, -fz, 0, + 0, -1.f, 0, 0); + } } } - //generate perspective matrix that contains frustum - //proj[j] = matrix_perspective(min, max); - proj[j] = gl_ortho(min.mV[0], max.mV[0], - min.mV[1], max.mV[1], - -max.mV[2], -min.mV[2]); - shadow_cam.setFar(128.f); shadow_cam.setOriginAndLookAt(eye, up, center); + shadow_cam.setOrigin(0,0,0); + glh_set_current_modelview(view[j]); glh_set_current_projection(proj[j]); LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - proj[j] = gl_ortho(fmin.mV[0], fmax.mV[0], - fmin.mV[1], fmax.mV[1], - -fmax.mV[2], -fmin.mV[2]); + shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); //translate and scale to from [-1, 1] to [0, 1] glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, @@ -6834,101 +8576,175 @@ void LLPipeline::generateSunShadow(LLCamera& camera) glh_set_current_modelview(view[j]); glh_set_current_projection(proj[j]); + for (U32 i = 0; i < 16; i++) + { + gGLLastModelView[i] = mShadowModelview[j].m[i]; + gGLLastProjection[i] = mShadowProjection[j].m[i]; + } + + mShadowModelview[j] = view[j]; + mShadowProjection[j] = proj[j]; + + mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view; + stop_glerror(); - //clip out geometry on the same side of water as the camera - static LLCullResult result; - S32 occlude = LLPipeline::sUseOcclusion; - LLPipeline::sUseOcclusion = 1; - LLPipeline::sShadowRender = TRUE; - //hack to prevent LOD updates from using sun camera origin - shadow_cam.setOrigin(camera.getOrigin()); - updateCull(shadow_cam, result); - stateSort(shadow_cam, result); + mShadow[j].bindTarget(); + mShadow[j].getViewport(gGLViewport); + mShadow[j].clear(); + { + static LLCullResult result[4]; + + //LLGLEnable enable(GL_DEPTH_CLAMP_NV); + renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE); + } + + mShadow[j].flush(); + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); mShadowCamera[j+4] = shadow_cam; } + } - LLFastTimer t(LLFastTimer::FTM_SHADOW_RENDER); + + //hack to disable projector shadows + static bool clear = true; + static const LLCachedControl gen_shadow("RenderShadowDetail",0); - stop_glerror(); + if (gen_shadow > 1) + { + F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); - mSunShadow[j].bindTarget(); - mSunShadow[j].getViewport(gGLViewport); + //update shadow targets + for (U32 i = 0; i < 2; i++) + { //for each current shadow + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i; - { - LLGLDepthTest depth(GL_TRUE); - mSunShadow[j].clear(); + if (mShadowSpotLight[i].notNull() && + (mShadowSpotLight[i] == mTargetShadowSpotLight[0] || + mShadowSpotLight[i] == mTargetShadowSpotLight[1])) + { //keep this spotlight + mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); } - - U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY, LLRenderPass::PASS_BUMP }; - LLGLEnable cull(GL_CULL_FACE); - - //generate sun shadow map - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadMatrixf(proj[j].m); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadMatrixf(view[j].m); - - stop_glerror(); - gGLLastMatrix = NULL; - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - glColor4f(1,1,1,1); - - glCullFace(GL_FRONT); - - stop_glerror(); - - gGL.setColorMask(false, false); - - gDeferredShadowProgram.bind(); - { - LLFastTimer ftm(LLFastTimer::FTM_SHADOW_SIMPLE); - LLGLDisable test(GL_ALPHA_TEST); - gGL.getTexUnit(0)->disable(); - for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i) - { - renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); + else + { //fade out this light + mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); + + if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) + { //faded out, grab one of the pending spots (whichever one isn't already taken) + if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) + { + mShadowSpotLight[i] = mTargetShadowSpotLight[0]; + } + else + { + mShadowSpotLight[i] = mTargetShadowSpotLight[1]; + } } - gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); } - + } + + for (S32 i = 0; i < 2; i++) + { + glh_set_current_modelview(saved_view); + glh_set_current_projection(saved_proj); + + if (mShadowSpotLight[i].isNull()) { - LLFastTimer ftm(LLFastTimer::FTM_SHADOW_ALPHA); - LLGLEnable test(GL_ALPHA_TEST); - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.6f); - renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE); - glColor4f(1,1,1,1); - renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE); - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + continue; } + + LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); + + if (!volume) + { + mShadowSpotLight[i] = NULL; + continue; + } + + LLDrawable* drawable = mShadowSpotLight[i]; + + LLVector3 params = volume->getSpotLightParams(); + F32 fov = params.mV[0]; + + //get agent->light space matrix (modelview) + LLVector3 center = drawable->getPositionAgent(); + LLQuaternion quat = volume->getRenderRotation(); + + //get near clip plane + LLVector3 scale = volume->getScale(); + LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); + at_axis *= quat; + + LLVector3 np = center+at_axis; + at_axis.normVec(); + + //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 origin = np - at_axis*dist; + + LLMatrix4 mat(quat, LLVector4(origin, 1.f)); + + view[i+4] = glh::matrix4f((F32*) mat.mMatrix); + + view[i+4] = view[i+4].inverse(); + + //get perspective matrix + F32 near_clip = dist+0.01f; + F32 width = scale.mV[VX]; + F32 height = scale.mV[VY]; + F32 far_clip = dist+volume->getLightRadius()*1.5f; + + F32 fovy = fov * RAD_TO_DEG; + F32 aspect = width/height; - gDeferredShadowProgram.unbind(); + proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); - renderGeomShadow(shadow_cam); + //translate and scale to from [-1, 1] to [0, 1] + 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); - gGL.setColorMask(true, true); + glh_set_current_modelview(view[i+4]); + glh_set_current_projection(proj[i+4]); - glCullFace(GL_BACK); - LLPipeline::sUseOcclusion = occlude; - LLPipeline::sShadowRender = FALSE; + mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - gGLLastMatrix = NULL; + for (U32 j = 0; j < 16; j++) + { + gGLLastModelView[j] = mShadowModelview[i+4].m[j]; + gGLLastProjection[j] = mShadowProjection[i+4].m[j]; + } - sMinRenderSize = 0.f; - mSunShadow[j].flush(); + mShadowModelview[i+4] = view[i+4]; + mShadowProjection[i+4] = proj[i+4]; + + LLCamera shadow_cam = camera; + shadow_cam.setFar(far_clip); + shadow_cam.setOrigin(origin); + + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + + stop_glerror(); + + mShadow[i+4].bindTarget(); + mShadow[i+4].getViewport(gGLViewport); + mShadow[i+4].clear(); + + static LLCullResult result[2]; + + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; + + renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE); + + mShadow[i+4].flush(); + } } static const LLCachedControl camera_offset("CameraOffset",false); @@ -6947,6 +8763,13 @@ void LLPipeline::generateSunShadow(LLCamera& camera) glMatrixMode(GL_MODELVIEW); } gGL.setColorMask(true, false); + + for (U32 i = 0; i < 16; i++) + { + gGLLastModelView[i] = last_modelview[i]; + gGLLastProjection[i] = last_projection[i]; + } + popRenderTypeMask(); } @@ -7100,7 +8923,9 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) { if (LLPipeline::sRenderDeferred) { - avatar->mImpostor.allocate(resX,resY,GL_RGBA16F_ARB,TRUE,TRUE); + static const LLCachedControl shadow_precision("DeferredHighPrecision",true); + const GLuint format = shadow_precision ? GL_RGBA : GL_RGBA16F_ARB; //TO-DO: Profile 16bit format later + avatar->mImpostor.allocate(resX,resY,format,TRUE,TRUE); addDeferredAttachments(avatar->mImpostor); } else @@ -7116,6 +8941,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) glStencilMask(0xFFFFFFFF); glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + { LLGLEnable scissor(GL_SCISSOR_TEST); glScissor(0, 0, resX, resY); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 436d73726..af720625e 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -185,7 +185,7 @@ public: BOOL visibleObjectsInFrustum(LLCamera& camera); BOOL getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max); BOOL getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector& fp, LLVector3 light_dir = LLVector3(0,0,0)); - void updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip = 0); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane + void updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip = 0, LLPlane* plane = NULL); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane void createObjects(F32 max_dtime); void createObject(LLViewerObject* vobj); void updateGeom(F32 max_dtime); @@ -212,12 +212,18 @@ public: void renderGeomDeferred(LLCamera& camera); void renderGeomPostDeferred(LLCamera& camera); void renderGeomShadow(LLCamera& camera); - void bindDeferredShader(LLGLSLShader& shader, U32 light_index = 0); + void bindDeferredShader(LLGLSLShader& shader, U32 light_index = 0, LLRenderTarget* gi_source = NULL, LLRenderTarget* last_gi_post = NULL, U32 noise_map = 0xFFFFFFFF); + void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep); + void unbindDeferredShader(LLGLSLShader& shader); void renderDeferredLighting(); void generateWaterReflection(LLCamera& camera); void generateSunShadow(LLCamera& camera); + + + void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, LLCullResult& result, BOOL use_shader = TRUE, BOOL use_occlusion = TRUE); + void generateGI(LLCamera& camera, LLVector3& lightDir, std::vector& vpc); void renderHighlights(); void renderDebug(); @@ -254,6 +260,9 @@ public: BOOL hasRenderDebugFeatureMask(const U32 mask) const { return (mRenderDebugFeatureMask & mask) ? TRUE : FALSE; } BOOL hasRenderDebugMask(const U32 mask) const { return (mRenderDebugMask & mask) ? TRUE : FALSE; } + + + BOOL hasRenderType(const U32 type) const; BOOL hasAnyRenderType(const U32 type, ...) const; @@ -454,22 +463,47 @@ public: static BOOL sRenderAttachedLights; static BOOL sRenderAttachedParticles; static BOOL sRenderDeferred; - static BOOL sAllowRebuildPriorityGroup; static S32 sVisibleLightCount; static F32 sMinRenderSize; //screen texture + LLRenderTarget mScreen; LLRenderTarget mDeferredScreen; - LLRenderTarget mDeferredLight[2]; + LLRenderTarget mEdgeMap; + LLRenderTarget mDeferredDepth; + LLRenderTarget mDeferredLight[3]; LLMultisampleBuffer mSampleBuffer; + LLRenderTarget mGIMap; + LLRenderTarget mGIMapPost[2]; + LLRenderTarget mLuminanceMap; //sun shadow map - LLRenderTarget mSunShadow[4]; + LLRenderTarget mShadow[6]; + std::vector mShadowFrustPoints[4]; + LLVector4 mShadowError; + LLVector4 mShadowFOV; + LLVector3 mShadowFrustOrigin[4]; LLCamera mShadowCamera[8]; LLVector3 mShadowExtents[4][2]; - glh::matrix4f mSunShadowMatrix[4]; + glh::matrix4f mSunShadowMatrix[6]; + glh::matrix4f mShadowModelview[6]; + glh::matrix4f mShadowProjection[6]; + glh::matrix4f mGIMatrix; + glh::matrix4f mGIMatrixProj; + glh::matrix4f mGIModelview; + glh::matrix4f mGIProjection; + glh::matrix4f mGINormalMatrix; + glh::matrix4f mGIInvProj; + LLVector2 mGIRange; + F32 mGILightRadius; + + LLPointer mShadowSpotLight[2]; + F32 mSpotLightFade[2]; + LLPointer mTargetShadowSpotLight[2]; + LLVector4 mSunClipPlanes; + LLVector4 mSunOrthoClipPlanes; LLVector2 mScreenScale; @@ -484,6 +518,8 @@ public: //noise map U32 mNoiseMap; + U32 mTrueNoiseMap; + U32 mLightFunc; LLColor4 mSunDiffuse; LLVector3 mSunDir; @@ -548,6 +584,9 @@ protected: LLDrawable::drawable_list_t mBuildQ2; // non-priority LLSpatialGroup::sg_vector_t mGroupQ1; //priority LLSpatialGroup::sg_vector_t mGroupQ2; // non-priority + bool mGroupQ2Locked; + bool mGroupQ1Locked; + LLViewerObject::vobj_list_t mCreateQ; LLDrawable::drawable_set_t mRetexturedList; diff --git a/indra/newview/rlvhandler.h b/indra/newview/rlvhandler.h index 362200aec..69f8ad703 100644 --- a/indra/newview/rlvhandler.h +++ b/indra/newview/rlvhandler.h @@ -22,6 +22,7 @@ #include "llstartup.h" #include "llviewerjointattachment.h" #include "llviewerobject.h" +#include "lleventtimer.h" #include "rlvcommon.h" #include "rlvhelper.h" diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index 165797b92..74b527f70 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -24,6 +24,7 @@ #include "llviewerinventory.h" #include "llvoavatar.h" #include "llwlparamset.h" +#include "lleventtimer.h" #include "rlvdefines.h" #include "rlvcommon.h" diff --git a/indra/newview/rlvlocks.h b/indra/newview/rlvlocks.h index e54caa30a..c4139b135 100644 --- a/indra/newview/rlvlocks.h +++ b/indra/newview/rlvlocks.h @@ -28,6 +28,7 @@ #include "llviewerjointattachment.h" #include "llviewerobject.h" #include "llvoavatar.h" +#include "lleventtimer.h" #include "rlvdefines.h" diff --git a/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_system.xml b/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_system.xml index a3aa83a16..65cda7032 100644 --- a/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_system.xml +++ b/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_system.xml @@ -103,7 +103,7 @@ control_name="AscentInstantMessageAnnounceIncoming" radio_style="false" width="270" name="quickstart_im_check" tool_tip="Opens an IM window when someone starts typing an IM to you. This gives you a heads up that someone is IMing you before they hit enter. "/> - - - - Reflection Detail: + Water Reflections: - + + Disabled + + Terrain and Trees - + All Static Objects - + All Avatars and Objects - + Everything - + + + Deferred Shadows: + + + + Disabled + + + Sun shadows + + + Sun and spotlight shadows + + + + Low + + Off + Lighting Detail: - Terrain Detail: diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp index c9e01c841..1a233fe2f 100644 --- a/indra/win_crash_logger/llcrashloggerwindows.cpp +++ b/indra/win_crash_logger/llcrashloggerwindows.cpp @@ -145,7 +145,7 @@ void LLCrashLoggerWindows::ProcessCaption(HWND hWnd) TCHAR header[MAX_STRING]; std::string final; GetWindowText(hWnd, templateText, sizeof(templateText)); - final = llformat(ll_convert_wide_to_string(templateText).c_str(), gProductName.c_str()); + final = llformat(ll_convert_wide_to_string(templateText,CP_ACP).c_str(), gProductName.c_str()); ConvertLPCSTRToLPWSTR(final.c_str(), header); SetWindowText(hWnd, header); } @@ -158,7 +158,7 @@ void LLCrashLoggerWindows::ProcessDlgItemText(HWND hWnd, int nIDDlgItem) TCHAR header[MAX_STRING]; std::string final; GetDlgItemText(hWnd, nIDDlgItem, templateText, sizeof(templateText)); - final = llformat(ll_convert_wide_to_string(templateText).c_str(), gProductName.c_str()); + final = llformat(ll_convert_wide_to_string(templateText,CP_ACP).c_str(), gProductName.c_str()); ConvertLPCSTRToLPWSTR(final.c_str(), header); SetDlgItemText(hWnd, nIDDlgItem, header); } @@ -201,7 +201,7 @@ bool handle_button_click(WORD button_id) wbuffer, // pointer to buffer for text 20000 // maximum size of string ); - std::string user_text(ll_convert_wide_to_string(wbuffer)); + std::string user_text(ll_convert_wide_to_string(wbuffer,CP_ACP)); // Activate and show the window. ShowWindow(gHwndProgress, SW_SHOW); // Try doing this second to make the progress window go frontmost.